tep0.6.0更新聊聊pytest变量接口用例3个级别复用
tep是一款测试工具,在pytest测试框架基础上集成了第三方包,提供项目脚手架,帮助以写Python代码方式,快速实现自动化项目落地。fixture是pytest核心技术,本文聊聊如何使用fixture完成变量、接口、用例3个级别复用。
技术原理
fixture是一种特殊函数,实现了依赖注入,pytest规定,只要在conftest.py模块中定义了fixture,作为参数传给测试函数test(fixture_name)就可以使用,无需import。tep在conftest.py上封装了一层fixtures,类似于Django初始化数据加载的fixtures,定义了env_vars环境变量,预置了登录接口等。整体思路如下图所示:
- 实线:表示fixture流转,从
tep.fixture预置fixture,到fixtures,到conftest.py,到tests。 - 虚线:表示动态变量流转,参考JMeter 
vars.put()和vars.get(),实现用例级别复用。 - 蓝色线:表示静态变量流转,参考JMeter
自定义用户变量,实现变量级别复用。 

tep.fixture
tep.fixture第一块内容是预置fixture的实现代码,如url、faker_ch等,对使用者隐藏。第二块内容是类TepVar,预置了1个Python字典vars_和2个存取方法put()、get(),划分了一块key-value形式存储区域。
fixtures
fixtures是一个包,里面包括多个fixture_*.py格式的Python模块,定义的全部都是fixture,只对外提供fixture,不提供function。
自动注册
conftest.py是pytest的特殊文件,文件名固定,tep在其中实现了自动注册功能,它会自动查找fixtures目录下,所有以fixture_开头,以.py结尾的Python模块进行导入,无需手动添加。注册后,tests才能够找到fixtures中定义的fixture,否则报错fixture not found。
tests
tests存放所有测试用例,tep建议每个Python模块中只定义1个test()函数,用例分离,独立运行。
参考了
HttpRunner每个yaml文件1条用例的做法。复杂场景可以定义多个测试test()函数或Test类,pytest都支持。
使用示例
变量级别复用
函数局部变量
import jmespath
from loguru import logger
from tep.client import request
def test_post(faker_ch, url, login):
    # description
    logger.info("test post")
    # data
    fake = faker_ch
    # request
    response = request(
        "post",
        url=url("/api/users"),
        headers=login.jwt_headers,
        json={
            "name": fake.name()
        }
    )
    # assert
    assert response.status_code < 400
    # extract
    user_id = jmespath.search("id", response.json())
函数内部变量,作用域是整条测试用例,可以在多个接口之间进行复用,比如参数化和关联:

全局环境变量
#!/usr/bin/python
# encoding=utf-8
""" Can only be modified by the administrator. Only fixtures are provided.
"""
from tep.dao import mysql_engine
from tep.fixture import *
@pytest.fixture(scope="session")
def env_vars(config):
    class Clazz(TepVars):
        env = config["env"]
        """Variables define start"""
        # Environment and variables
        mapping = {
            "qa": {
                "domain": "https://qa.com",
                "mysql_engine": mysql_engine("127.0.0.1",  # host
                                             "2306",  # port
                                             "root",  # username
                                             "123456",  # password
                                             "qa"),  # db_name
            },
            "release": {
                "domain": "https://release.com",
                "mysql_engine": mysql_engine("127.0.0.1",
                                             "2306",
                                             "root",
                                             "123456",
                                             "release"),
            }
            # Add your environment and variables
        }
        # Define properties for auto display
        domain = mapping[env]["domain"]
        mysql_engine = mapping[env]["mysql_engine"]
        """Variables define end"""
    return Clazz()
@pytest.fixture
def project_level():
    pass
使用:
def test(env_vars, env_vars_your_name):
    print(env_vars.common_var)
    print(env_vars_your_name.my_var)
全局环境变量由fixtures提供:

核心数据是env_vars.Clazz类里面的mapping、domain、mysql_engine等属性:

这么做的目的是为了在PyCharm中敲代码,输入.后能自动带出来,提高编码效率。
fixture_admin.py建议由管理员维护项目级别的公共变量,fixture_your_name.py由团队成员定义自己的环境变量,避免冲突。它们还有一个区别是fixture_admin.py的env_vars继承了tep.fixture.TepVar,支持env_vars.put()和env_vars.get()。
变量都由
fixture提供。
接口级别复用
tep预置登录接口fixture_login.py已经实现了接口级别复用,其他接口可以参照实现:
from tep.client import request
from tep.fixture import *
def _jwt_headers(token):
    return {"Content-Type": "application/json", "authorization": f"Bearer {token}"}
@pytest.fixture(scope="session")
def login(url):
    # Code your login
    logger.info("Administrator login")
    response = request(
        "post",
        url=url("/api/users/login"),
        headers={"Content-Type": "application/json"},
        json={
            "username": "admin",
            "password": "123456",
        }
    )
    assert response.status_code < 400
    response_token = jmespath.search("token", response.json())
    class Clazz:
        token = response_token
        jwt_headers = _jwt_headers(response_token)
    return Clazz
使用:
from loguru import logger
def test_login(login):
    logger.info(login.token)
用例级别复用
a_test.py,定义1条测试用例test_a(),使用faker_ch生成随机name,通过env_vars.put()方法写入TepVar.vars_中:
def test_a(faker_ch, env_vars):
    name = faker_ch.name()
    env_vars.put("name", name)
reuse_a_test.py,定义另外1条测试用例test(),import test_a后手动调用执行,从TepVar.vars_中读取name:
from tests.sample.case_reuse.a_test import test_a
def test(faker_ch, env_vars):
    test_a(faker_ch, env_vars)
    print(env_vars.get("name"))
注意
test_a()函数参数引用的所有fixture,需要在test()函数参数中重新申明一遍,比如示例中的(faker_ch, env_vars)。
tep是借助conftest.py和fixture,用类变量来做的,参考了JMeter BeanShell的vars。
也可以外接
redis。
tep0.6.0更新
tep用户手册是根据0.5.3版本写的,现在更新了0.6.0版本,一是支持本文提到的3个级别复用,微调了fixtures,二是把项目脚手架代码尽量封装到tep中,减少后续升级成本。涉及到4个文件:conftest.py、fixture_admin.py、fixture_login.py、fixture_your_name.py。
更新tep
pip install tep==0.6.0
- 如果还没有用过tep,使用这条命令安装后,执行
tep startproject project_name就可以创建0.6.0版本的项目脚手架,包含了预置代码结构和sample测试用例。 - 如果已经安装了tep,也需要执行这条命令升级
0.6.0版本。 
老项目升级(可选)
老项目升级也很简单,先在项目根目录执行命令:
tep -U
它会自动替换conftest.py,考虑到老项目fixtures已经有真实数据了,这里给出了version0.6.0文件包,命令执行后在项目根目录生成:

把老项目的真实数据提取出来,手动替换一下就可以了:

小结
本文介绍了如何使用pytest测试框架实现变量、接口、用例3个级别复用,给出了在tep中的使用示例,然后提供了安装升级tep0.6.0的方法。这套思路借鉴了JMeter和HttpRunner的部分设计思想,以及我使用过的接口测试平台经验,在pytest上实践了一下。tep只是测试工具,本质上还是写pytest,感兴趣可以试一下哦。
参考资料:
tep0.6.0更新聊聊pytest变量接口用例3个级别复用的更多相关文章
- 纯python自研接口自动化脚本更新版本,让小白也能实现0到1万+的接口自动化用例
		
查看完整文章点击原文链接:纯python自研接口自动化脚本更新版本,让小白也能实现0到1万+的接口自动化用例 你是否还在用postman\jmeter做接口自动化吗?用python的开源框架[unit ...
 - jmeter3.0+ant1.10+jenkins实现接口自动化并发送邮件
		
有很多关于接口自动化的文章,此篇仅用于记录自己的学习用.使用jmeter3.0+ant1.10+jenkins2.实现接口自动化并发送邮件,本篇是用的编写build文件来实现发送邮件,也可以用jenk ...
 - 浅谈Android Studio3.0更新之路(遇坑必入)
		
>可以参考官网设置-> 1 2 >> Fantasy_Lin_网友评论原文地址是:简书24K纯帅豆写的我也更新一下出处[删除]Fa 转自脚本之家 浅谈Android Studi ...
 - 开源低代码开发平台entfrm2.1.0更新
		
开源低代码开发平台entfrm2.1.0更新 新功能 代码生成支持主子表,支持预览: 新增多应用顶部菜单与左侧菜单联动: element-ui升级到2.15.1: 新增表单管理,集成avue-from ...
 - 4.修改更新源sources.list,提高软件下载安装速度(提供Kali 2.0 更新源)
		
1.切换到root用户(如果已经是root用户就直接看第二步) dnt@HackerKali:~$ su 密码: 2.用文本编辑器打开sources.list,手动添加下面的更新源 root@Hack ...
 - V4.0到来了,css雪碧图生成工具4.0更新啦
		
V3.0介绍 http://www.cnblogs.com/wang4517/p/4476758.html V4.0更新内容 V4.0下载地址:http://download.csdn.net/det ...
 - 修改更新源sources.list,提高软件下载安装速度(提供Kali 2.0 更新源)
		
1.切换到root用户(如果已经是root用户就直接看第二步) dnt@HackerKali:~$ su 密码: 2.用文本编辑器打开sources.list,手动添加下面的更新源 root@Hack ...
 - Maven3.0.3的环境变量配置
		
Maven3.0.3的环境变量配置 //该配置经过实际验证已经可以使用.验证的环境maven3.0.3(官网的目前最新版)1 windows maven3的安装 标签: #maven | 发布时间: ...
 - Android 8.0+ 更新安装apk失败的问题
		
最近做项目发现Android 8.0+ 更新安装apk时 出现安装失败的情况 总结原因是 缺少安装的权限 Android 8.0 (Android O)为了针对一些流氓软件引导用户安装其他无关应用. ...
 
随机推荐
- PyQt(Python+Qt)学习随笔:树型部件QTreeWidget的itemAbove、itemBelow方法作用探究
			
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 在QTreeWidget的方法中,对于itemBelow.itemAbove方法,官网文档介绍非常简 ...
 - PyQt学习随笔:使用QPropertyAnimation开发简单动画
			
QPropertyAnimation是PyQt5.QtCore模块提供的动画设计类,使用该类可以针对PyQt的界面对象进行动画播放,如果要针对一个指定对象进行动画播放,包括如下步骤: 一.创建动画对象 ...
 - PyQt(Python+Qt)学习随笔:使用QtWidgets.qApp实现在程序中随时访问应用的方法
			
在PyQt应用中,任何一个应用在启动时必须创建一个基于QtWidgets.QApplication或其派生类对应的应用对象,该对象用于处理事件. 如果需要在应用代码中的任何位置都能访问该应用对象,可以 ...
 - 【Vue】 axios同步执行多个请求
			
问题 项目中遇到一个需求,在填写商品的时候,选择商品分类后,加载出商品分类的扩展属性. 这个扩展属性有可能是自定义的数据字典里的单选/多远. 要用第一个axios查询扩展属性,第二个axios 从第一 ...
 - CVE申请+挖掘指南
			
CVE的全称是"Common Vulnerabilities and Exposures"翻译成中文就是"公共漏洞和披露" 可以简单理解跟国内CNVD的通用漏洞 ...
 - PHP代码审计分段讲解(5)
			
11 sql闭合绕过 源代码为 <?php if($_POST[user] && $_POST[pass]) { $conn = mysql_connect("**** ...
 - espcms代码审计(二次urldecode注入分析)
			
这里提到的漏洞是二次urldecode注入 这里用到的还是espcms,不过版本应该跟之前的有所不同,在网上找到的espcms源代码都是已经修补了这个漏洞的,我们对比分析吧 先放上漏洞位置代码,也就是 ...
 - vue之keep-alive组件
			
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
 - 题解-CF1444C Team-Building
			
题面 CF1444C Team-Building 给 \(n\) 个点 \(m\) 条边,每个点有颜色 \(c_i(1\le c_i\le k)\),求有多少个颜色对两组点并后是二分图. 数据范围:\ ...
 - BJOI2017 喷式水战改
			
题目链接. Description 维护一个序列,支持操作: 每次在 \(P_i\) 位置后插入一段 \(X_i\) 单位的燃料,这一段有三个模式,对应的能量分别是 \(A_i, B_i, C_i\) ...