pytest框架fixtureconftesthookpytest.iniallure
Posted IT界的测试混子
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了pytest框架fixtureconftesthookpytest.iniallure相关的知识,希望对你有一定的参考价值。
Fixture
pytest fixture 官网:
https://docs.pytest.org/en/stable/fixture.html#fixture
Fixture是在测试函数运行前后,由pytest执行的外壳函数,代码可以定制,满足多变的测试需求,
功能包括:
- 定义传入测试中的数据集
- 配置测试前系统的初始状态
- 为批量测试提供数据源等
pytest fixture 使用
方法1:直接通过函数名,作为参数传递到方法中,有返回值
import pytest
@pytest.fixture
def login():
print("login....")
return "login success"
def test_add_cart2(login):
print(login)
print("添加购物车")
方法2:使用 @pytest.mark.usefixtures(‘login’),测试用例前加上装饰器,没有返回值
import pytest
@pytest.fixture
def 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.py
import pytest
@pytest.fixture(scope="function")
def setup_and_teardown():
print("计算开始".center(30,"*"))
yield "计算中..."
print("计算结束".center(30,"*"))
test_add.py
#test_add.py
import pytest
def add(a,b):
return a + b
class 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定制插件必备)
官方文档:
https://docs.pytest.org/en/latest/reference/reference.html?highlight=hooks#hooks
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
说明原始链接
https://github.com/pytest-dev/pytest/issues/3261
hook函数解决ids中文乱码问题:
conftest.py
#conftest.py
from typing import List
def 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.py
import pytest
def add(a,b):
return a + b
class 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 = debug
python_files = test_*
python_classes = Test*
python_functions = test_*
addopts = --clean-alluredir -v --alluredir=./result
testpaths = test_path
log_cli = 1
makers 注册mark标记
修改测试用例收集的命名规则
- python_files = test_*
- python_classes = Test*
- python_functions = test_*
addopts 增加pytest运行时默认参数,省去重复工作
testpaths 指定测试目录
log_cli 控制台实时输出日志
更多参数详解使用pytest --help查看
allure
文档:
https://docs.qameta.io/allure/#
allure 下载地址:
https://repo1.maven.org/maven2/io/qameta/allure/allure-commandline/2.13.8/
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'<head></head><body>增加html内容</body>', 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 smoke
python_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=./result
addopts = --clean-alluredir -v --alluredir=./result
testpaths = ./
test_allure.py
#test_allure.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# pip install allure-pytest
import allure
# pip install pytest
import pytest
def 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.py
import os
import allure
import pytest
from typing import List
def 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'<head></head><body>增加html内容</body>', 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.py
allure generate --clean ./result --report-dir ./report
插入html文件
插入图片
关联link,可点击跳转
以上是关于pytest框架fixtureconftesthookpytest.iniallure的主要内容,如果未能解决你的问题,请参考以下文章
pytest文档71-pytest+yaml实现接口自动化框架