Raul2018

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

From: https://blog.csdn.net/weixin_45741835/article/details/123470182

tep完整教程帮你突破pytest

自动化代码美学

于 2022-03-13 19:44:00 发布

阅读量734
收藏

点赞数
文章标签: python java 大数据 单元测试 脚本语言
版权
持续维护的教程
tep教程会随着版本更新或经验积累,持续维护在电子书中,最新的最全的内容请锁定这篇文章【最新】tep完整教程帮你突破pytest:

https://dongfanger.gitee.io/blog/chapters/tep.html

 

对教程有任何疑问或建议,可添加微信交流哟:cekaigang。

tep是个小工具
tep是Try Easy Pytest的首字母缩写,是一款基于pytest测试框架的测试工具,集成了各种实用的第三方包和优秀的自动化测试设计思想,帮你快速实现自动化项目落地。tep不是测试框架,只是一个小工具。在原理篇就能看出来,它所做的事情,就相当于胶水,把pytest相关的测试技术聚合在一起。假如您的公司想使用或推广tep,那么请不要说我们准备引入tep,而是应该说我们准备用pytest直接写Python代码来实现自动化。tep只是帮你做到这一步的小小工具。

快速入门
安装tep
pip install tep


新建pytest项目
tep startproject demo


启动自带FastAPI应用
运行utils/fastapi_mock.py脚本。

 

测试
运行samples文件夹下login_pay脚本。

 

生成报告
pytest samples/login_pay --tep-reports

 


使用篇
用例集
在tests目录下将测试用例按功能模块分成多个用例集:

tests
user
user_main_process.py
user_validate.py
teacher
teacher_main_process.py
teacher_validate.py
student
student_main_process.py
student_validate.py
测试用例
用例的基本原则是用例解耦:每个.py文件都是单独的可运行的测试用例。

测试步骤
测试用例由测试步骤组成。步骤由描述、数据、请求、提取、断言5个部分组成:

# 描述
# 数据
# 请求
response = request(
"{method}",
url="{url}",
headers={headers},
{body_grammar}
)
# 提取
# var = response.jmespath("expression")
# 断言
assert response.status_code < 400
语法约定
强烈推荐直接编写Python代码。无需额外学习新语法,精通Python语言和Python库用法,让你的代码能力直线上升。tep没有做特殊封装,只做了语法约定。tep编写自动化脚本的方法,是一种追求效率的极速写法。

接口管理
接口写在用例步骤里,不用单独管理,不为了代码数据分离而分离。如果想单独管理,可以参考示例代码中的mvc写法,不推荐这种效率偏低的方式。

接口复用
接口复用的原则是逻辑相对简单,url+入参+出参,比较固定且重复使用次数很多。符合复用要求的接口可以做成fixture,供测试用例使用。参考fixtures/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(env_vars):
# 封装登录接口
logger.info("Administrator login")
response = request(
"post",
url=env_vars.domain + "/login",
headers={"Content-Type": "application/json"},
json={
"username": "dongfanger",
"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
返回值使用类包了一层,一是为了在写代码时会有语法智能补全,二是方便后续扩展,直接给类添加新的属性即可,不影响其他用例。

接口串联
得益于一个.py文件就是一条用例的约定。接口的串联就能通过变量进行实现,从上个接口响应中取值,存入变量,放到下个接口的入参中,轻松完成。

全局变量
env_vars是全局变量池,提供了put()和get()方法对变量进行动态存取。在fixtures/fixture_env_vars.py可以设置预设变量:

#!/usr/bin/python
# encoding=utf-8

from tep.dao import mysql_engine
from tep.fixture import *


@pytest.fixture(scope="session")
def env_vars(config):
class Clazz(TepVars):
env = config["env"]

"""变量定义开始"""
# 环境变量
mapping = {
"qa": { # qa环境
"domain": "http://127.0.0.1:5000", # 变量名:变量值
"mysql_engine": mysql_engine("127.0.0.1", # host
"2306", # port
"root", # username
"123456", # password
"qa"), # dbname
},
"release": { # release环境
"domain": "https://release.com", # 变量名:变量值
"mysql_engine": mysql_engine("127.0.0.1",
"2306",
"root",
"123456",
"release"),
}
# 继续添加
}
# 定义类属性,敲代码时会自动补全
domain = mapping[env]["domain"]
mysql_engine = mapping[env]["mysql_engine"]
"""变量定义结束"""

return Clazz()

局部变量
就像正常的Python变量一样使用,没有特殊的语法。

环境切换
在conf.yaml中可以切换运行环境:

env: qa
环境之间的差别体现在环境变量,环境变量也是在fixtures/fixture_env_vars.py中进行预设的。默认有qa和release2个环境。

数据驱动
推荐使用pytest.mark.parametrize。

//TODO集成对excel、json、yaml文件读写方法。

断言
采用Python原生的assert断言。

//TODO整理assert用法。

测试报告
在pytest命令行添加参数--tep-reports就能一键生成Allure测试报告,并且会把请求入参和响应出参,记录在测试报告中。

pytest --tep-reports
自定义日志
编辑utils/http_client.py对日志进行自定义,用例中引用新版本request:

from utils.http_client import request
参考示例samples/http/test_request_monkey_patch.py。

Pairwise算法生成功能用例
Pairwise算法能针对多条件组合用例,从笛卡尔积中,根据两两组合过滤,生成更为精简的测试用例。

输入3个条件:

'M', 'O', 'P'
'W', 'L', 'I'
'C', 'E'
from tep.func import pairwise

def test_pairwise():
enum = [['M', 'O', 'P'], ['W', 'L', 'I'], ['C', 'E']]
result = pairwise(enum)
print(f"\npair total:{len(result)}")
for p in result:
print(p)
笛卡尔积有18种组合,经过Pairwise算法过滤后,只会保留9组用例:

cartesian product total:18
100% [■■■■■■■■■■]
pair total:9
('M', 'W', 'E')
('M', 'L', 'E')
('M', 'I', 'C')
('O', 'W', 'E')
('O', 'L', 'E')
('O', 'I', 'C')
('P', 'W', 'C')
('P', 'L', 'C')
('P', 'I', 'E')
录制流量生成自动化用例
①手动设置系统代理。

②命令行cd到utils目录下,在mitm.py中设置过滤域名。

③mitmdump -s mitm.py开始录制。

用例会自动生成到tests/mitm文件夹下。

原理篇
代码是最好的文档:

https://github.com/dongfanger/tep

//TODO完善代码注释

 

pypi库
tep可以通过pip直接安装,这是因为源码上传到了pypi官方库。上传借助了poetry来实现:

poetry install --no-dev
poetry build
poetry publish
执行这3条命令,然后输入pypi注册的用户名和密码即可。

集成第三方包
poetry包管理器可以通过命令安装包:

poetry install package
poetry remove package
集成以后的包会随着tep一起安装。

项目脚手架
tep能从系统命令行来调用,也是借助poetry来实现的:

# pyproject.toml
[tool.poetry.scripts]
tep = "tep.cli:main"
这相当于注册了系统命令,调用后会执行tep.cli:main函数:

import argparse
import sys

from tep import __description__, __version__
from tep.scaffold import init_parser_scaffold, main_scaffold


def main():
"""Parse command line options and run commands.
"""
parser = argparse.ArgumentParser(description=__description__)
parser.add_argument(
"-V", "--version", dest="version", action="store_true", help="show version"
)
subparsers = parser.add_subparsers(help="sub-command help")
sub_parser_scaffold = init_parser_scaffold(subparsers)

if len(sys.argv) == 1:
# tep
parser.print_help()
sys.exit(0)
elif len(sys.argv) == 2:
# print help for sub-commands
if sys.argv[1] in ["-V", "--version"]:
# tep -V
print(f"{__version__}")
elif sys.argv[1] in ["-h", "--help"]:
# tep -h
parser.print_help()
elif sys.argv[1] == "startproject":
# tep startproject
sub_parser_scaffold.print_help()
sys.exit(0)

args = parser.parse_args()

if args.version:
print(f"{__version__}")
sys.exit(0)

if sys.argv[1] == "startproject":
main_scaffold(args)

startproject会调用main_scaffold函数,这里面的逻辑很简单,就是创建文件夹和文件,文件内容是已经写好的样板代码。

变量池
变量池是在tep/fixture.py中实现的:

class TepVars:
def __init__(self):
self.vars_ = {}

def put(self, key, value):
self.vars_[key] = value

def get(self, key):
value = ""
try:
value = self.vars_[key]
except KeyError:
logger.error(f"env_vars doesnt have this key: {key}")
return value
它就是一个具有get和put方法的类,变量存在self.vars_这个全局字典中,所有脚本共享同一个变量池。

环境变量
环境配置是通过config来读取的:

@pytest.fixture(scope="session")
def config():
config_path = os.path.join(Project.dir, "conf.yaml")
with open(config_path, "r", encoding="utf-8") as f:
conf = yaml.load(f.read(), Loader=yaml.FullLoader)
return conf
它是个fixture,会在fixtures/fixture_env_vars.py中引用到:

@pytest.fixture(scope="session")
def env_vars(config):
class Clazz(TepVars):
env = config["env"]
这样就能设置环境变量了。

fixture自动导入
在conftest.py中,进行了fixture自动导入:

# 自动导入fixtures
_fixtures_dir = os.path.join(_project_dir, "fixtures")
_fixtures_paths = []
for root, _, files in os.walk(_fixtures_dir):
for file in files:
if file.startswith("fixture_") and file.endswith(".py"):
full_path = os.path.join(root, file)
import_path = full_path.replace(_fixtures_dir, "").replace("\\", ".").replace("/", ".").replace(".py", "")
_fixtures_paths.append("fixtures" + import_path)
pytest_plugins = _fixtures_paths
它会扫描fixtures目录下所有以fixture_开头和.py结尾的文件,然后以pytest_plugins形式添加到运行环境中。

requests猴子补丁
requests借助于装饰器打了猴子补丁,tep/client.py:

def tep_request_monkey_patch(req, *args, **kwargs):
start = time.process_time()
response = req(*args, **kwargs)
end = time.process_time()
elapsed = str(decimal.Decimal("%.3f" % float(end - start))) + "s"
log4a = "{}{} status:{} response:{} elapsed:{}"
try:
kv = ""
for k, v in kwargs.items():
# if not json, str()
try:
v = json.dumps(v, ensure_ascii=False)
except TypeError:
v = str(v)
kv += f" {k}:{v} "
args = list(args)
args += ["", ""]
method, url, *t = args
method_url = ""
if method:
method_url = f'method:"{method}" '
if url:
method_url += f'\nurl:"{url}" '
request_response = log4a.format(method_url, kv, response.status_code, response.text, elapsed)
logger.info(request_response)
allure.attach(request_response, f'request & response', allure.attachment_type.TEXT)
except AttributeError:
logger.error("request failed")
except TypeError:
logger.warning(log4a)
return TepResponse(response)


def request_wrapper(req):
def send(*args, **kwargs):
return tep_request_monkey_patch(req, *args, **kwargs)

return send


@request_wrapper
def request(method, url, **kwargs):
# 这是reqeusts原生方法

没有对requests做任何改动,只加了日志和报告内容。

一键生成Allure测试报告
--tep-reports是通过pytest plugin来实现的:

#!/usr/bin/python
# encoding=utf-8

import os
import shutil
import tempfile

import allure_commons
from allure_commons.logger import AllureFileLogger
from allure_pytest.listener import AllureListener
from allure_pytest.plugin import cleanup_factory

from tep.fixture import Project
from tep.func import current_time

allure_temp = tempfile.mkdtemp()


class Plugin:
@staticmethod
def pytest_addoption(parser):
parser.addoption(
"--tep-reports",
action="store_const",
const=True,
help="Create tep allure HTML reports."
)

@staticmethod
def _tep_reports(config):
if config.getoption("--tep-reports") and not config.getoption("allure_report_dir"):
return True
else:
return False

@staticmethod
def pytest_configure(config):
if Plugin._tep_reports(config):
test_listener = AllureListener(config)
config.pluginmanager.register(test_listener)
allure_commons.plugin_manager.register(test_listener)
config.add_cleanup(cleanup_factory(test_listener))

clean = config.option.clean_alluredir
file_logger = AllureFileLogger(allure_temp, clean)
allure_commons.plugin_manager.register(file_logger)
config.add_cleanup(cleanup_factory(file_logger))

@staticmethod
def pytest_sessionfinish(session):
if Plugin._tep_reports(session.config):
reports_dir = os.path.join(Project.dir, "reports")
new_report = os.path.join(reports_dir, "report-" + current_time().replace(":", "-").replace(" ", "-"))
if os.path.exists(reports_dir):
his_reports = os.listdir(reports_dir)
if his_reports:
latest_report_history = os.path.join(reports_dir, his_reports[-1], "history")
shutil.copytree(latest_report_history, os.path.join(allure_temp, "history"))
os.system(f"allure generate {allure_temp} -o {new_report} --clean")
shutil.rmtree(allure_temp)

通过pytest_sessionfinish钩子函数,在pytest运行结束时,生成测试报告。同时会把历史数据保留下来,以在Allure报告的趋势图中进行展示。

//TODO其他原理慢慢更新,欢迎提出疑问,不断补充。

附录
tep相比于pytest优势
【项目创建】

项目脚手架快速创建自动化项目;

良好的项目结构设计;

【上手简单】

遵循Python原生语法,没有额外负担;

提供丰富的接口自动化实践示例;

【优雅集成】

保留requests库用法,采用猴子补丁动态输出日志;

pytest命令行参数一键生成Allure测试报告;

【平台支持】

teprunner测试平台在线管理pytest脚本;

支持Git一键同步至平台;

tep测试平台化思路
teprunner是基于tep的测试平台。

从测试工具转变到测试平台,最重要是要想清楚用例的运行流程。从前端录入用例信息后,通过后端保存到数据库,再把数据组装出来,变成可执行的文件。teprunner的做法是,把pytest作为引擎,用例全部转化为文件,然后使用pytest命令运行用例。

用例解耦是实现平台化的关键原则。tep是按照一个.py文件一条用例的约定来编写脚本的,使得每个文件都是独立的可运行的。这就能很好的对应到,前端测试用例的增删改查。假如用例没有解耦,Python文件之间存在非常多的依赖,那么想做成Web平台是很困难的,在界面上根本无法操作。

项目脚手架为平台化提供了非常大的便利。在测试平台创建项目时,就会调用tep startproject创建一个项目脚手架,相当于给脚本运行初始化了一套隔离的运行环境,项目的用例之间互不干扰。

至于fixtures、环境变量等功能,如果做好了分层设计,这些都是水到渠成的事了。在做平台之前,只是为了多人协作方便,把conftest里面的fixture抽了出来,但是在平台化时,抽出来的fixtures正好可以做成一个单独的功能点。环境变量也是在做平台之前,只是想用yaml来管理配置,但是在平台化时,正好可以用来在前端切换环境,结合fixture_env_vars.py做成环境变量的功能。

找准测试平台定位才能游刃有余。测试平台只是一个壳子,做成什么样的平台,取决于对平台的定位,以及技术实现的能力。正是因为没有大牛的技术,无法做成大而全的测试平台,teprunner测试平台的才定位于pytest脚本在线管理平台。这对于tep来说,恰好是刚刚好的选择。

文章知识点与官方知识档案匹配,可进一步学习相关知识
Java技能树首页概览136384 人正在系统学习中

自动化代码美学
关注

0


0


1


tep 用户手册帮你从 unittest 过渡到 pytest_python引用tep.client是什...
11-30
tep 已经预置了登录相关代码,只需要打开fixtures\fixture_admin.py,修改 2 个地方的代码,就可以完成登录请求。 修改环境变量 编辑fixtures/fixture_admin.py: @pytest.fixture(scope="session") defenv_vars(config): classClazz: def_...
2022全网最全教程,一篇文章带你学会 Pytest 测试框架
11-21
1. 安装开始 直接使用pip安装就可以,pytest支持python的2.0或3.0版本 #!/usr/bin/python3 # 伊洛Yiluo # https://yiluotalk.com pip install -U pytest 检查版本,校验下是否安装成功 #!/usr/bin/python3 # 伊洛Yiluo # https...
Pytest+Allure+Jenkins 自动化测试报告
西门一刀的博客
955
基础篇—生成报告 在自动化测试执行之后,生成一个美观大方的测试报告,也是测试过程中,非常最要的一环。测试报告直接反应了测试过程中发现的问题,分析测试报告是解决问题的最重要手段。那么一个专业的测试报告应该长什么样呢?废话不多说,直接上图: 在上面这张测试报告中,整体用中文显示,易于阅读;左侧导航栏包含总览、分类、测试用例列表、图表等多个模块;右侧的总览页面中包含了用例数、成功率、历史趋势图、用例分类等多张表格;页面布局简约大方。 那么如何生成这样一份测试报告呢? 第一步,安装Python依赖库。两种方式任选
pytest封神之路第一步 tep介绍
自动化代码美学
1515
『 tep is a testing tool to help you write pytest more easily. Try Easy Pytest! 』 tep前身 tep的前身是接口自动化测试框架pyface,一款面向对象设计的测试框架,我写过一篇博客介绍。 测试框架 / 测试工具 tep的定位是 a testing tool,不是 a testing framework。 框架/工具,是有区别的。最大的区别,就是我自认为是没有足够的能力去自主开发一套“框架”!工具的能力,还是妥妥的! 自研的
【原创】爆肝23页教程,自研关键字驱动框架
11-10
tep关键字驱动框架教程 tep简介 tep是TryEasyPytest的首字母缩写,关键字驱动框架,专注于接口自动化测试,单个文件即可完成用例编写。 设计理念 ✔️稳定:基于成熟框架pytest,天生强大 ✔️规范:RobotFramework风格,井井有条 ...
pytest自动化测试框架tep环境变量、fixtures、用例三者之间的关系
12-4
tep是一款测试工具,在pytest测试框架基础上集成了第三方包,提供项目脚手架,帮助以写Python代码方式,快速实现自动化项目落地。 在tep项目中,自动化测试用例都是放到tests目录下的,每个.py文件相互独立,没有依赖,1个文件即1条用例,彼此分离...
pytest自动化测试框架tep环境变量、fixtures、用例三者之间的关系
最新发布
2301_79535544的博客
39
tep是一款测试工具,在pytest测试框架基础上集成了第三方包,提供项目脚手架,帮助以写Python代码方式,快速实现自动化项目落地。在tep项目中,自动化测试用例都是放到tests目录下的,每个.py文件相互独立,没有依赖,1个文件即1条用例,彼此分离。虽然用例也能相互引用,但是除非万不得已,一般不建议这么做,牵一发动全身,后期维护困难。用例的代码编写,思路是从上往下的,和pytest/unittest/script常规写法无异,不会有学习成本,一般也不会有问题。
tinyos tep131 中英对照
04-11
tinyos tep131 中英对照
【精选】当Pytest遇上MVC分层设计自动化用例就该这么写
11-21
TepCache是“缓存”,包括global_vars、env_vars、case_vars三个级别的变量池。 Step是一个泛化调用类,作用是打日志,调用第二个参数对应的步骤函数。 测试步骤 fromutils.cacheimportTepCache ...
手把手教你Pytest+Allure2.X定制报告详细教程,给自己的项目量身打造一...
12-4
pytest.main(['-s','-q','--alluredir','./report']) (3)添加feature,Report展示见下图。 2、Story定制详解 (1)代码实现 (2)参考代码 # coding=utf-8 # 1.先设置编码,utf-8可支持中英文,如上,一般放在第一行 ...
TEP
02-15
TEP
teprunner测试平台10篇原创PDF教程发布
自动化代码美学
262
001-pytest内核测试平台落地初体验本文介绍了我第一次做的测试平台的使用和原理,技术栈为Vue+Django+Django REST Framework+JWT+MySQL+pyte...
【精选】tep0.6.0更新聊聊pytest变量接口用例3个级别复用_自动化代码美 ...
11-18
tep是一款测试工具,在pytest测试框架基础上集成了第三方包,提供项目脚手架,帮助以写Python代码方式,快速实现自动化项目落地。fixture是pytest核心技术,本文聊聊如何使用fixture完成变量、接口、用例3个级别复用。
自动化工具 pytest 内核测试平台落地初体验
chengxuyuznguoke的博客
383
测试平台,有人说它鸡肋,有人说它有用,有人说它轮子,众说纷纭,不如从自身出发,考虑是否要做测试平台: 第 1 阶段,用 Python+requests 写接口自动化。 第 2 阶段,选择 unitttest 或 pytest,更熟悉 pytest 选了 pytest。 第 3 阶段,快速搭建 pytest 项目脚手架,封装 tep 测试工具。 第 4 阶段,通过 Git 管理测试脚本,多分支合并代码。 第 5 阶段,去除本地环境同步麻烦,方便团队共享脚本。
【pytest】修改allure报告中的logo及参数化
weixin_52358204的博客
1385
修改allure报告logo及allure参数化方法并生成本地链接
Tep.zip_Tep_pic18f4550_zip
09-21
pic18f4550 ethernet enc28j60
pytep:pyTEP是用于Python中的Tennessee Eastman流程的开源仿真API。 它简化了复杂模拟场景的设置,并提供了交互式模拟的选项
04-13
pyTEP:一个Python包,用于田纳西伊士曼过程的交互式仿真 重新编译TEP二进制文件 安装Python 3.7 什么是pyTEP? pyTEP是用于Python中的Tennessee Eastman流程的开源仿真API。 它简化了复杂模拟场景的设置,并提供了交互式模拟的选项。 通过pyTEP的高级API,用户可以设置仿真,更改操作条件并存储仿真数据,而无需了解模拟器的基本原理。 除了新引入的功能外,pyTEP还承诺比现有的TEP模拟器更具通用性和更直接的用法。 如何引用 Reinartz, C. and Enevoldsen, T.T. "pyTEP: A Python package for interactive simulations of the Tennessee Eastman process", 2021 安装指引 为了安装和运行pyTEP,必须安装适用于py
tinyos_tep
07-28
tinyos 应用方案tep 在应用tinyos中的实际问题中解决
TEP_Project_Part1
04-01
TEP_Project_Part1
田纳西伊始曼仿真过程(TEP)数据.rar
04-28
TE过程数据,用于故障检测与诊断,包括建模数据与21个纯故障数据和21个测试数据,在MATLAB下直接导入。
TRABALHO_TEP
04-07
实际工作I-TEP-UFLix 教授VinicíusMota DI / UFES 交货日期:11/04/2021交货地点: 由Repl.it提交; 并且也由AVA提供。 1.目标 这项第一项工作旨在发展创建抽象数据类型,库,组织和正确代码文档,内存管理和...
TestNG中的Listener和简单应用
Tison的博客
1573
在上一篇文章,介绍了失败用例重跑的方式,这只是一种解决问题的方法,主要在什么场景下,才能决定这个方法是否管用和适合。这篇来介绍下TestNG中的Listener,在理解了Listener之后,我们再来看看代码失败重跑的第二种方法。 什么是TestNG Listener 接触过Selenium的人可能听说过webdriver Listener,可能面试中也会被问到webdriver liste...
tep支持pytest-xdist分布式执行用例及合并Allure报告
自动化代码美学
807
tep近期更新频率较快,一方面是作者在积极投入到tep工具开发中;另一方面是我们聚集了20位小伙伴,一起合力打造EasyPytest测试平台,teprunner的FastAPI升级版本,依托于tep,帮你高效管理pytest测试用例。陆续也会有平台开发日志发布,欢迎持续关注。 预览内容: 1、pytest-xdist分布式执行用例,合并Allure报告; 2、global_vars全局变量配...
pytest代理录制
07-28
pytest并不直接支持代理录制功能。然而,你可以使用一些第三方工具来实现代理录制。其中一个常用的工具是mitm
————————————————
版权声明:本文为CSDN博主「自动化代码美学」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_45741835/article/details/123470182

posted on 2023-12-05 15:38  Raul2018  阅读(34)  评论(0编辑  收藏  举报