这里写目录标题
- Pytest
-
- Init
- Run
- Report
-
- --junitxml={report}.xml
-
- [1. testsuite](#1. testsuite)
-
- [1.1 在测试套件级别添加属性节点 record_testsuite_property](#1.1 在测试套件级别添加属性节点 record_testsuite_property)
- [2. testcase](#2. testcase)
-
- [2.1 记录测试的其他信息 record_property](#2.1 记录测试的其他信息 record_property)
- [2.2 向testcase元素添加额外的xml属性 record_xml_attribute](#2.2 向testcase元素添加额外的xml属性 record_xml_attribute)
- Hooks
- [other plugin 好玩的](#other plugin 好玩的)
Pytest
Init
Run
- 引进@pytest.mark.parametrize中ids导致编码乱码
python
def pytest_collection_modifyitems(items):
for item in items:
item.name = item.name.encode('utf-8').decode('unicode-escape')
item._nodeid = item._nodeid.encode('utf-8').decode('unicode-escape')
Report
--junitxml={report}.xml
https://docs.pytest.org/en/stable/reference/reference.html
pytest v6.0+ 默认
xunit2
不支持 testcase添加属性建议设置
- pytest.ini中配置
junit_family=xunit1
pytest -o junit_family=xunit1
text
junit_suite_name (string):
Test suite name for JUnit report
junit_logging (string):
Write captured log messages to JUnit report: one of no|log|system-out|system-err|out-err|all
junit_log_passing_tests (bool):
Capture log information for passing tests to JUnit report:
junit_duration_report (string):
Duration time to report: one of total|call
junit_family (string):
Emit XML for schema: one of legacy|xunit1|xunit2
bash
pytest -h
--junit-xml=path create junit-xml style report file at given path. # 报告地址
--junit-prefix=str prepend prefix to classnames in junit-xml output # classname前缀
> pytest demo --junit-xml=./report.xml --junit-prefix=xxx
xml
<?xml version="1.0" encoding="utf-8"?>
<testsuites>
<testsuite name="pytest" errors="0" failures="0" skipped="0" tests="2" time="0.113"
timestamp="2025-03-10T14:53:08.040765+08:00" hostname="Ding-Perlis-MP1Y70F1">
<testcase classname="xxx.set_classname" name="set_name" file="test_case.py" line="49" time="0.006"/>
<testcase classname="xxx.set_classname" name="set_name" file="test_case.py" line="49" time="0.001"/>
</testsuite>
</testsuites>
1. testsuite
1.1 在测试套件级别添加属性节点 record_testsuite_property
支持
xunit2
python
import pytest
@pytest.fixture(scope="session", autouse=True)
def log_global_env_facts(record_testsuite_property):
record_testsuite_property("ARCH", "PPC")
record_testsuite_property("STORAGE_TYPE", "CEPH")
class TestMe:
def test_foo(self):
assert True
output
xml
<testsuite errors="0" failures="0" name="pytest" skipped="0" tests="1" time="0.006">
<properties>
<property name="ARCH" value="PPC"/>
<property name="STORAGE_TYPE" value="CEPH"/>
</properties>
<testcase classname="test_me.TestMe" file="test_me.py" line="16" name="test_foo" time="0.000243663787842"/>
</testsuite>
2. testcase
2.1 记录测试的其他信息 record_property
请注意,使用此功能将中断对最新JUnitXML架构的架构验证。当与某些CI服务器一起使用时,这可能是一个问题
- 方法一
test_case.py
python
def test_function(record_property):
record_property("example_key", 1)
assert True
- 方法二
contest.py
python
# content of conftest.py
def pytest_collection_modifyitems(session, config, items):
for item in items:
for marker in item.iter_markers(name="test_id"):
test_id = marker.args[0]
item.user_properties.append(("test_id", test_id))
# content of test_function.py
import pytest
@pytest.mark.test_id(1501)
def test_function():
assert True
output
xml
<testcase classname="test_function" file="test_function.py" line="0" name="test_function" time="0.0009">
<properties>
<property name="example_key" value="1"/>
</properties>
</testcase>
<testcase classname="test_function" file="test_function.py" line="0" name="test_function" time="0.0009">
<properties>
<property name="test_id" value="1501"/>
</properties>
</testcase>
2.2 向testcase元素添加额外的xml属性 record_xml_attribute
record_xml_attribute 是一个实验性的特性,它的接口在未来的版本中可能会被更强大和通用的东西所取代。然而,功能本身将保持不变
请注意,使用此功能将中断对最新JUnitXML架构的架构验证。当与某些CI服务器一起使用时,这可能是一个问题
- 方法一
test_case.py
python
@pytest.mark.parametrize("case", case_data)
def test_case(case, record_xml_attribute):
record_xml_attribute('classname', 'set_classname') # 重写 value
record_xml_attribute('name', 'set_name') # 重写 value
record_xml_attribute('index', '123') # 新增 key, value
print("hello world")
assert True
- 方法二
contest.py
python
# edit to contest.py
@pytest.fixture(autouse=True)
def record_index(record_xml_attribute):
record_xml_attribute('index', '123') # 新增 key, value
- output
xml
<?xml version="1.0" encoding="utf-8"?>
<testsuites>
<testsuite name="pytest" errors="0" failures="0" skipped="0" tests="2" time="0.113"
timestamp="2025-03-10T14:53:08.040765+08:00" hostname="Ding-Perlis-MP1Y70F1">
<testcase classname="set_classname" name="set_name" file="test_case.py" line="49" index="123" time="0.006">
<system-out>
hello world
</system-out>
</testcase>
<testcase classname="set_classname" name="set_name" file="test_case.py" line="49" index="123" time="0.001"/>
</testsuite>
</testsuites>
Hooks
other plugin 好玩的
-
pytest_html_merger https://github.com/akavbathen/pytest_html_merger
pip install pytest_html_merger
合并pytest_html报告shellexport PATH="$HOME/.lcoal/bin:$PATH" pytest_html_merger -i /path/to/your/html/reports -o /path/to/output/report/merged.html
-
pytest-tally https://github.com/jeffwright13/pytest-tally
pip install pytest-tally
可在控制台、应用程序或浏览器中显示测试运行进度shellcd project # 与main.py同级 python main.py pytest xxx # tally tally-rich tally-flask tally-tk