1、前言:某些接口需要引用上个接口返回的值,作为下个接口的入参,但笔者又不想在本地维护及创建此文件,此时引出fixture内置函数中的临时文件存储tmpdir

2、首先下面的源码是使用flask框架写的图书管理系统,使用的basic认证方式,调用查看数据接口时需登录返回token

from flask import  Flask,make_response,jsonify,abort,request
from flask_restful import Api,Resource
from flask_httpauth import HTTPBasicAuth

from flask import Flask
from flask_jwt import JWT, jwt_required, current_identity
from werkzeug.security import safe_str_cmp

app=Flask(__name__)
app.debug = True
app.config['SECRET_KEY'] = 'super-secret'
api = Api(app=app)
auth = HTTPBasicAuth()

@auth.get_password
def get_password(name):
if name == 'admin':
return 'admin'

@auth.error_handler
def authoorized():
return make_response(jsonify({'msg':"请认证"}),401)

books=[
{'id':1,'author':'Teacher','name':'Python接口自动化测试实战','done':True},
{'id':2,'author':'Teacher','name':'Selenium3自动化测试实战','done':False},\
{'id':3,'author':'Tao','name':'Jmeter接口测试','done':False}
]

class User(object):
def __init__(self, id, username, password):
self.id = id
self.username = username
self.password = password

def __str__(self):
return "User(id='%s')" % self.id

users = [
User(1, 'admin', 'Admin'),
User(2, 'admin', 'qwe123'),
]

username_table = {u.username: u for u in users}
userid_table = {u.id: u for u in users}

def authenticate(username, password):
user = username_table.get(username, None)
if user and safe_str_cmp(user.password.encode('utf-8'), password.encode('utf-8')):
return user

def identity(payload):
user_id = payload['identity']
return userid_table.get(user_id, None)

jwt = JWT(app, authenticate, identity)

class Books(Resource):
# decorators = [auth.login_required]
decorators=[jwt_required()]

def get(self):
return jsonify({'status':0,'msg':'ok','datas':books})

def post(self):
if not request.json:
return jsonify({'status':1001,'msg':'请求参数不是JSON的数据,请检查,谢谢!'})
else:
book = {
'id': books[-1]['id'] + 1,
'author': request.json.get('author'),
'name': request.json.get('name'),
'done': True
}
books.append(book)
return jsonify({'status':1002,'msg': '添加书籍成功','datas':book}, 201)

class Book(Resource):
# decorators = [auth.login_required]
decorators = [jwt_required()]

def get(self,book_id):
book = list(filter(lambda t: t['id'] == book_id, books))
if len(book) == 0:
return jsonify({'status': 1003, 'msg': '很抱歉,您查询的书的信息不存在'})
else:
return jsonify({'status': 0, 'msg': 'ok', 'datas': book})

def put(self,book_id):
book = list(filter(lambda t: t['id'] == book_id, books))
if len(book) == 0:
return jsonify({'status': 1003, 'msg': '很抱歉,您查询的书的信息不存在'})
elif not request.json:
return jsonify({'status': 1001, 'msg': '请求参数不是JSON的数据,请检查,谢谢!'})
elif 'author' not in request.json:
return jsonify({'status': 1004, 'msg': '请求参数author不能为空'})
elif 'name' not in request.json:
return jsonify({'status': 1005, 'msg': '请求参数name不能为空'})
elif 'done' not in request.json:
return jsonify({'status': 1006, 'msg': '请求参数done不能为空'})
elif type(request.json['done'])!=bool:
return jsonify({'status': 1007, 'msg': '请求参数done为bool类型'})
else:
book[0]['author'] = request.json.get('author', book[0]['author'])
book[0]['name'] = request.json.get('name', book[0]['name'])
book[0]['done'] = request.json.get('done', book[0]['done'])
return jsonify({'status': 1008, 'msg': '更新书籍成功', 'datas': book})

def delete(self,book_id):
book = list(filter(lambda t: t['id'] == book_id, books))
if len(book) == 0:
return jsonify({'status': 1003, 'msg': '很抱歉,您查询的书的信息不存在'})
else:
books.remove(book[0])
return jsonify({'status': 1009, 'msg': '删除书籍成功'})

api.add_resource(Books,'/v1/api/books')
api.add_resource(Book,'/v1/api/book/<int:book_id>')

if __name__ == '__main__':
app.run(debug=True,port=5550)

3、其次:把上述的登录接口分离到conftest.py 模块中,实现fixture的共享机制

import pytest
import requests
# 获取flask_api.py模块的access_token 认证登录
@pytest.fixture()
def getToken():
login_url = "http://127.0.0.1:5550/auth"
data = {"username": "admin","password": "Admin"}
response = requests.post(url=login_url,json=data)
# 返回token值
return response.json()['access_token']

4、最后:下面举个Api接口书籍管理系统的为例(test_fixture_books_temdir.py 模块):

import requests
import pytest

# 每一条测试用例必须有清理工作,就是原来数据是怎么的,用例执行完后还是怎么样的
# 此设置是添加书籍信息返回的ID,然后传ID更新数书籍信息,再删除此更新后的书籍信息

def addBooks(getToken):
# 新增书籍信息
data = {
"author": "Teacher",
"name": "安全&渗透测试",
"done": False
}
r = requests.post(
url='http://127.0.0.1:5550/v1/api/books',
json=data,
headers={'Authorization':'JWT {}'.format(getToken)}
)
print('添加书籍:\n',r.json())
return r.json()[0]['datas']['id']

def queryBooks(getToken,BookID):
# 查询书籍信息
r = requests.get(
url='http://127.0.0.1:5550/v1/api/book/{0}'.format(BookID),
headers={'Authorization':'JWT {}'.format(getToken)}
)
print('查询书籍:\n',r.json())
return r

def setBooks(getToken,BookID):
# 更新书籍信息
data = {
"author":"TAO",
"name":"Fiddler工具",
"done":False
}
r = requests.put(
url='http://127.0.0.1:5550/v1/api/book/{0}'.format(BookID),
json=data,
headers={'Authorization':'JWT {}'.format(getToken)}
)
print('更新书籍:\n',r.json())
return r

def deleteBooks(getToken,BookID):
# 删除新增书籍信息
r = requests.delete(
url='http://127.0.0.1:5550/v1/api/book/{0}'.format(BookID),
headers={'Authorization':'JWT {}'.format(getToken)}
)
print('删除书籍:\n',r.json())

def test_query_books(getToken,tmpdir):
fp = tmpdir.join('book.md')
fp.write(addBooks(getToken))
queryBooks(getToken,BookID=fp.read())
setBooks(getToken,BookID=fp.read())
# 验证:查询更新后书籍信息
assert 'Fiddler' in setBooks(getToken,BookID=fp.read()).json()['datas'][0]['name']
assert queryBooks(getToken,fp.read()).status_code == 200
deleteBooks(getToken,BookID=fp.read())

if __name__ == '__main__':
pytest.main()

5、下面是接口运行结果:
(接口自动化需做到,创建返回A,查询返回A,更新返回A,删除依然是A)

Pytest单元测试框架之FixTure内置临时文件tmpdir操作的更多相关文章

  1. Pytest单元测试框架之FixTure基本使用

    前言: 在单元测试框架中,主要分为:测试固件,测试用例,测试套件,测试执行及测试报告: 测试固件不难理解,也就是我们在执行测试用例前需要做的动作和测试执行后的需要做的事情: 比如在UI自动化测试中,我 ...

  2. Pytest单元测试框架-测试用例运行规则

    1.Pytest测试用例运行规则 在pytest单元测试框架下面执行用例,需要满足以下几个特点: 1. 文件名以test_*.py开头或者*_test.py 2. 测试类.测试函数以test开头 3. ...

  3. Pytest单元测试框架-Pytest环境安装

    unittest是python自带的单元测试框架,它封装好了一些校验返回的结果方法和一些用例执行前的初始化操作,使得单元测试易于开展,因为它的易用性,很多同学也拿它来做功能测试和接口测试,只需简单开发 ...

  4. Pytest单元测试框架:插件-allure-pytest环境搭建并在本地生成一个测试报告

    之前写了allure-pytest的官方文档啃的内容,有些交流的朋友,实践起来没什么头绪,所以就有了这篇文章,也给自己填个坑 第一步:搭建Allure.JDK环境 1. 搭建JDK环境 不装jdk你会 ...

  5. Pytest单元测试框架之简单操作示例

    前言: Pytest是第三方单元格测试框架,更加简单,灵活,而且提供了更多丰富的扩展: Pytest与UnitTest框架的区别 UnitTest测试用例执行顺序是依照ascii码执行,而Pytest ...

  6. shiro框架学习-3- Shiro内置realm

    1. shiro默认自带的realm和常见使用方法 realm作用:Shiro 从 Realm 获取安全数据 默认自带的realm:idae查看realm继承关系,有默认实现和自定义继承的realm ...

  7. javascript:面向对象和常见内置对象及操作

    本文内容: 面向对象 常见内置对象及操作 首发日期:2018-05-11 面向对象: JavaScript 是面向对象的编程语言 (OOP).OOP 语言使我们有能力定义自己的对象和变量类型. 对象是 ...

  8. Pytest单元测试框架-学习

    pytest: Python的一个单元测试框架,基于UnitTest二次开发,语法上更加简洁,可以用来做Python开发项目的单元测试,UI自动化.接口自动化测试等,有很多的插件访问Pytest插件汇 ...

  9. Pytest单元测试框架——Pytest+Allure+Jenkins的应用

    一.简介 pytest+allure+jenkins进行接口测试.生成测试报告.结合jenkins进行集成. pytest是python的一种单元测试框架,与python自带的unittest测试框架 ...

随机推荐

  1. 一文搞定Samba云服务器配置(阿里云)

    石头门第五话桶子入侵SERN的时候,先是PowerShell连接远程服务器,然后突然就用图形化界面显示了远程的试验报告,就是来源于Samba(大概). 抱着以上的想法才买了个服务器并且配一下samba ...

  2. 通过Dapr实现一个简单的基于.net的微服务电商系统(十七)——服务保护之动态配置与热重载

    在上一篇文章里,我们通过注入sentinel component到apigateway实现了对下游服务的保护,不过受限于目前变更component需要人工的重新注入配置以及重启应用更新componen ...

  3. java基础第一节课随笔

    第一题:1.定义一个HelloWold类2.在类中定义主方法3.在主方法中使用输出语句在dos控制台打印HelloWorld 打印结果如:HelloWorld4.在案例中使用当行注释.多行注释添加相关 ...

  4. SpringCloud Alibaba实战(5:子模块基本业务开发)

    源码地址:https://gitee.com/fighter3/eshop-project.git 持续更新中-- 在上一节里,我们搭建了一个微服务项目的整体架构,并进行了版本控制. 接下来我们进一步 ...

  5. Java如何利用for循环在控制台输出正方形对角线图形

    1 /* 2 利用循环在控制台输出如下正方形对角线图形 3 * * * * * * * * * * * 4 * * * * 5 * * * * 6 * * * * 7 * * * * 8 * * * ...

  6. 实验1、初入Flask

    实验介绍 1. 实验内容 Flask是一个用Python编写的Web应用程序框架.Armin Ronacher带领一个名为Pocco的国际Python爱好者团队开发了Flask.Flask基于Werk ...

  7. 孟老板 Paging3 (二) 结合Room

    BaseAdapter系列 ListAdapter系列 Paging3 (一) 入门 Paging3 (二) 结合 Room Paging3 (二)  结合Room Paging 数据源不开放, 无法 ...

  8. 飞(fly)(数学推导,liu_runda的神题)

    大概看了两三个小时的题解,思考量很大,实现简单........ 20分: 明显看出,每个点的贡献是x*(x-1)/2;即组合数C(x,2),从x个线段中选出2个的方案数,显然每次相交贡献为1,n^2枚 ...

  9. 可编程网络DataPath 及XDP

    目录 可编程网络DataPath XDP 的基本架构 XDP 的软件要求 XDP 的硬件要求 XDP 的工作流程及使用 XDP 的工作模式 XDP 的工作流程 Hello World XDP 的应用 ...

  10. ANDROID开发 Fatal signal 11(SIGSEGV) at 0x问题解决方案

    最近做ANDROID开发,也遇到了很多程序员遇到的一个问题:FATAL SIGNAL 11(SIGSEGV) at 0xxxxx,自然是各种搜索是否有人已然解决,虽然搜索出来的已有案例不少,基本都是内 ...