
本文共 9542 字,大约阅读时间需要 31 分钟。
Fixture
pytest fixture 官网:
Fixture是在测试函数运行前后,由pytest执行的外壳函数,代码可以定制,满足多变的测试需求,
功能包括:
- 定义传入测试中的数据集
- 配置测试前系统的初始状态
- 为批量测试提供数据源等
pytest fixture 使用
方法1:直接通过函数名,作为参数传递到方法中,有返回值import pytest@pytest.fixturedef login(): print("login....") return "login success" def test_add_cart2(login): print(login) print("添加购物车")
方法2:使用 @pytest.mark.usefixtures(‘login’),测试用例前加上装饰器,没有返回值
import pytest@pytest.fixturedef login(): print("login....") return "login success" @pytest.mark.usefixtures("login")def test_add_cart(): print("添加购物车")
pytest fixture参数
- autouse 自动应用。默认为False,设置为True自动应用。
- scope指定作用域(session>module>class>function)
- setup-show 回溯 fixture 的执行过程
import pytest@pytest.fixture(autouse=True)def login(): print("login....") return "login success"@pytest.fixture(scope="class")def goto_main(): print("goto mian page...")@pytest.fixture(scope="function")def login_out(): print("login out....")@pytest.mark.usefixtures("goto_main")class TestFixture: def test_01(self): print("test_01") def test_02(self): print("test_02") def test_03(self,login_out): print("test_03")
运行结果

test_fixture.py --setup-show
conftest.py
- conftest.py文件名固定
- conftest.py 文件就近生效
存放fixture
conftest.py
#conftest.pyimport pytest@pytest.fixture(scope="function")def setup_and_teardown(): print("计算开始".center(30,"*")) yield "计算中..." print("计算结束".center(30,"*"))
test_add.py
#test_add.pyimport pytestdef add(a,b): return a + bclass TestAdd: @pytest.mark.parametrize('a,b,expect',[[0.1,0.2,0.3],], ids=["浮点数相加"]) def test_add_float(self, a,b,expect,setup_and_teardown): print(setup_and_teardown) print("{}+{}={}".format(str(a),str(b),str(expect))) assert expect == round(add(a, b),2)
执行结果

pytest 插件
pip install pytest-ordering 控制用例的执行顺序pip install pytest-dependency 控制用例的依赖关系pip install pytest-xdist 分布式并发执行测试用例pip install pytest-rerunfailures 失败重跑pip install pytest-assume 多重较验pip install pytest-random-order 用例随机执行pip install pytest-html 测试报告
hook 函数(pytest定制插件必备)
官方文档:
hook执行顺序
root
└── pytest_cmdline_main ├── pytest_plugin_registered ├── pytest_configure │ └── pytest_plugin_registered ├── pytest_sessionstart │ ├── pytest_plugin_registered │ └── pytest_report_header ├── pytest_collection │ ├── pytest_collectstart │ ├── pytest_make_collect_report │ │ ├── pytest_collect_file │ │ │ └── pytest_pycollect_makemodule │ │ └── pytest_pycollect_makeitem │ │ └── pytest_generate_tests │ │ └── pytest_make_parametrize_id │ ├── pytest_collectreport │ ├── pytest_itemcollected │ ├── pytest_collection_modifyitems │ └── pytest_collection_finish │ └── pytest_report_collectionfinish ├── pytest_runtestloop │ └── pytest_runtest_protocol │ ├── pytest_runtest_logstart │ ├── pytest_runtest_setup │ │ └── pytest_fixture_setup │ ├── pytest_runtest_makereport │ ├── pytest_runtest_logreport │ │ └── pytest_report_teststatus │ ├── pytest_runtest_call │ │ └── pytest_pyfunc_call │ ├── pytest_runtest_teardown │ │ └── pytest_fixture_post_finalizer │ └── pytest_runtest_logfinish ├── pytest_sessionfinish │ └── pytest_terminal_summary └── pytest_unconfigure
说明原始链接
hook函数解决ids中文乱码问题:
conftest.py
#conftest.pyfrom typing import Listdef pytest_collection_modifyitems( session: "Session", config: "Config", items: List["Item"]) -> None: for item in items: item.name = item.name.encode('utf-8').decode('unicode-escape') item._nodeid = item.nodeid.encode('utf-8').decode('unicode-escape')
test_add.py
#test_add.pyimport pytestdef add(a,b): return a + bclass TestAdd: @pytest.mark.parametrize('a,b,expect',[[0.1,0.2,0.3],], ids=["浮点数相加"]) def test_add_float(self, a,b,expect,): print("{}+{}={}".format(str(a),str(b),str(expect))) assert expect == round(add(a, b),2)
执行结果,用例名称显示为中文了

pytest.ini
使用mark标记用例时,会有以下提示
PytestUnknownMarkWarning: Unknown pytest.mark.debug - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/mark.html
@pytest.mark.debug![]()
解决:
pytest.ini[pytest]markers = debug
再执行

[pytest]markers = debugpython_files = test_*python_classes = Test*python_functions = test_*addopts = --clean-alluredir -v --alluredir=./resulttestpaths = test_pathlog_cli = 1
makers 注册mark标记
修改测试用例收集的命名规则
- python_files = test_*
- python_classes = Test*
- python_functions = test_*
addopts 增加pytest运行时默认参数,省去重复工作
testpaths 指定测试目录 log_cli 控制台实时输出日志
更多参数详解使用pytest --help查看

allure
文档:
allure 下载地址:
allure安装
(1)需要先安装java 环境
(2) windows下载zip包,解压后把bin目录加入环境变量 Mac可以用brew安装brew install allure
(3)安装 allure-pytest库
pip install allure-pytest
allure特性
在报告中看到测试功能,子功能,或场景,测试步骤包括测试附加信息
- 功能加上@allure.feature(‘功能名称’)
- 子功能加上@allure.story(‘子功能名称’)
- 步骤加上@allure.step(‘功能名称’)
- @allure.attach(‘具体文本信息’),需要附加信息,可以是数据、文本、图片、视频、网页
- 运行时限制过滤 pytest 文件名 --allure-features’购物车功能’ --allure-stories’加入购物车’
注解@allure.feature与@allure.story相当于父子关系
特性-step
测试过程中每个步骤,一般放在具体的逻辑方法中。可以放在关键步骤中,在报告中显示,在app、web自动化测试当中,建议切换到每一个新的页面做一个step
- @allure.step() 只能以装饰器的形式放在类或方法上面
- with allure.step() 可以在测试用例方法里面
特性 -testcase
关联测试用例,可以直接给测试用例的地址链接
TEST_CASE_LINK = "https://www.baidu.com"@allure.testcase(TEST_CASE_LINK ,"test case title")def test_with_testcase_link() pass
按重要级别进行一定范围的测试
- 通过附件mark标记
- 通过allure.feature,allure.story来标记
- 通过allure.severity来附加标记 (级别Trivial:不重要 ,Minor不太重要,Normal 正常问题 Critical 严重 Blocker 阻塞) 步骤:
- 在测试方,函数和类上加 @allure.severity(allure.severity_level.TRIVIAL)
- 执行时 pytest -s -v 文件名 --allure-severities normal,critical
allure运行不同测试用例
- 按mark标记运行
pytest -m smoke --clean-alluredir -v --alluredir=./result
- 按feature运行
pytest --allure-features="pay" --clean-alluredir -v --alluredir=./result
- 按story运行
pytest --allure-stories="pay" --clean-alluredir -v --alluredir=./result
- 按severity运行
pytest --allure-severities blocker,critical --clean-alluredir -v --alluredir=./result
allure.attach文件、截图、html
allure.attcah显示许多不同类型提供的附件
(1)在测试报告里附加网页 allure.attach(body内容,name,attachment_type,extension)allure.attach(body=r'增加html内容', name="attach增加html内容", attachment_type=allure.attachment_type.HTML)
(2)在测试报告里附加图片
allure.attach.file(source,name,attachment_type,extension)allure.attach.file(source=png_path, name="attach增加PNG内容", attachment_type=allure.attachment_type.PNG)
allure --help查看更多参数
#### allure生成报告
#--alluredir,指定生成结果路径pytest [测试文件] -s -q --alluredir=./result/
查看测试报告,三种方式
(1)在线查看报告,会直接打开默认浏览器展示当前报告,执行以下allure serve ./result/
(2)先从结果生成报告,再打开index.html
#从结果生成报告allure generate ./result/ -o ./report/ --clean#打开报告allure open -h 127.0.0.1 -p 8888 ./report/
(3)先生成html报告,再从pycharm中右键点击index.html>【Open in Browser】>选择浏览器,打开报告。注意:直接双击html无效
#从结果生成报告allure generate ./result/ -o ./report/ --clean
test allure demo
pytest.ini
;pytest.ini[pytest]markers = debug smokepython_files = test_* python_classes = Test*python_functions = test_*;addopts = -m smoke --clean-alluredir -v --alluredir=./result;addopts = --allure-severities blocker,critical --clean-alluredir -v --alluredir=./result;addopts = --allure-stories="pay" --clean-alluredir -v --alluredir=./resultaddopts = --clean-alluredir -v --alluredir=./resulttestpaths = ./
test_allure.py
#test_allure.py#!/usr/bin/env python# -*- coding: utf-8 -*-# pip install allure-pytestimport allure# pip install pytestimport pytestdef choose_goods(): print("选择商品")def add_cart(): print("添加购物车")def pay(): print("支付")def clearn_cart(): print("清除购物车")def collect_goods(): print("收藏商品")@allure.feature("功能模块-购物车功能")class TestGoodsCart: @pytest.mark.smoke @allure.severity(allure.severity_level.BLOCKER) @allure.story("pay") # @allure.story("子功能-加购商品并支付") @allure.title("测试用例名称-加购商品并支付成功") def test_add_cart_and_pay(login,attach_html): with allure.step("step1:选择商品"): choose_goods() with allure.step("step2:加入购物车"): add_cart() with allure.step("step3:支付"): pay() with allure.step("断言"): assert 1 == 2 @allure.severity(allure.severity_level.CRITICAL) @allure.story("子功能-清除购物车") @allure.title("测试用例名称-清除购物车") def test_clearn_cart(login,attach_png): with allure.step("step1:选择商品"): choose_goods() with allure.step("step2:清除购物车"): clearn_cart() with allure.step("断言"): assert 1 == 1 @allure.testcase("https://www.taobao.com/","关联用例title") @allure.story("子功能-购物车商品转收藏") @allure.title("测试用例名称-购物车商品转收藏") def test_collect_goods(login): with allure.step("step1:选择商品"): choose_goods() with allure.step("step2:收藏购物车商品"): collect_goods() with allure.step("断言"): assert 1 == 1
conftest.py
#conftest.pyimport osimport allureimport pytestfrom typing import Listdef pytest_collection_modifyitems( session: "Session", config: "Config", items: List["Item"]) -> None: for item in items: item.name = item.name.encode('utf-8').decode('unicode-escape') item._nodeid = item.nodeid.encode('utf-8').decode('unicode-escape')@pytest.fixture()def login(): print("login".center(30,"*")) return "login success..."@pytest.fixture()def attach_html(): allure.attach(body=r'增加html内容', name="attach增加html内容", attachment_type=allure.attachment_type.HTML)png_path = os.path.join(os.path.split(os.path.abspath(__file__))[0],"taobao.png")@pytest.fixture()def attach_png(): allure.attach.file(source=png_path, name="attach增加PNG内容", attachment_type=allure.attachment_type.PNG)
执行
pytest test_allure.pyallure generate --clean ./result --report-dir ./report
插入html文件

插入图片

关联link,可点击跳转

发表评论
最新留言
关于作者
