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

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

  1. 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的共享机制

  1. import pytest
    import requests
  1. # 获取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 模块):

  1. 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. TensorRT深度学习训练和部署图示

    TensorRT深度学习训练和部署 NVIDIA TensorRT是用于生产环境的高性能深度学习推理库.功率效率和响应速度是部署的深度学习应用程序的两个关键指标,因为它们直接影响用户体验和所提供服务的 ...

  2. HttpServer:一款Windows平台下基于IOCP模型的高并发轻量级web服务器

    HttpServer的特点1.完全采用IOCP模型,实现真正的异步IO,高并发.高可靠: 2.支持4G以上文件下载: 3.支持断点续传: 4.轻量级,体积小,服务器文件仅200多K,无任何依赖库: 5 ...

  3. 看懂redis配置文件

    看懂redis 配置文件: https://blog.csdn.net/liqingtx/article/details/60330555 redis 数据库缓存双写一致性解决方案: https:// ...

  4. 『言善信』Fiddler工具 — 14、使用Fiddler进行弱网测试

    目录 1.什么是弱网测试 2.弱网环境的影响 3.弱网环境测试场景 4.使用Fiddler进行弱网测试 (1)Fiddler模拟弱网环境 (2)设置弱网的参数 (3)进行弱网测试对比 (4)恢复设置 ...

  5. anaconda安装VSCODE后,python报错

    重新用anaconda时遇到了一点问题. 测试anaconda捆绑安装的VSCODE时写了一行print(1),然后报错. 后来发现用anaconda下载vscdoe时并不会给python一个路径,这 ...

  6. Centos8.3、mysql8.0主从复制实战记录

    引言 最近又上线了一个项目,感觉自己这段时间收获不少就想把自己做这个项目用的技术总结梳理一下.这个项目是我自己发起,领导们不是特别重视所以得到资源有限,资源有限的情况我只能选择手动搭建数据库环境,资源 ...

  7. java面试技巧及层次。

    不断的积累,从打算找工作之日起,就要坚持在每天闲暇之余学习其中几道题目,日积月累,等到出去面试时,一切都水到渠成,面试时就自然会游刃有余了. 答题时,先答是什么,再答有什么作用和要注意什么,这里给人的 ...

  8. 浏览器中js怎么将图片下载而不是直接打开

    网上找了好多方法都是不能用的,经过试验在Chrome中都是直接打开. 经过自己的摸索,找到了一套能用的解决方案 var database = "data:image/jpg;base64,& ...

  9. OSPF 路由协议

    OSPF路由协议 目录 一.OSPF路由协议概述 1.1.内部网关和外部网关协议 1.2.OSPF的工作过程 1.3.OSPF的基本概念 二.OSPF 数据包类型 2.1.OSPF数包 2.2.OSP ...

  10. spring boot @Async异步注解上下文透传

    上一篇文章说到,之前使用了@Async注解,子线程无法获取到上下文信息,导致流量无法打到灰度,然后改成 线程池的方式,每次调用异步调用的时候都手动透传 上下文(硬编码)解决了问题. 后面查阅了资料,找 ...