在 py.test 中是否可以报告测试运行中生成的任意值?
In py.test is it possible to report arbitrary values generated in the test runs?
我知道有用于 py.test 的性能测试和分析的插件,但是有没有办法生成任意值,这些值在测试后报告或以某种方式访问?
想象一下我有这样的测试
def test_minimum_learning_rate():
"""Make some fancy stuff and generate a learning performance value"""
learning_rate = fancy_learning_function().rate
pytest.report("rate", learning_rate)
assert learning_rate > 0.5
pytest.report(..)
行是我 喜欢 拥有的(但不存在,是吗?)
现在我想将 minimum_learning_rate[rate]
之类的内容与实际测试结果一起写入报告(或者至少在屏幕上)。
真的 Jenkins 的一些插件很不错,它可以根据该数据创建一个漂亮的图表。
有没有典型的措辞?我一直在寻找 kpi
、arbitrary values
、user defined values
,但还没有任何运气..
如果您只想输出一些调试值,print
调用结合 -s
参数就足够了:
def test_spam():
print('debug')
assert True
运行 pytest -s
:
collected 1 item
test_spam.py debug
.
如果您正在寻找可以更好地集成到 pytest
执行流程中的解决方案,请编写自定义挂钩。下面的例子应该会给你一些想法。
每次测试执行后打印自定义行
# conftest.py
def pytest_report_teststatus(report, config):
if report.when == 'teardown': # you may e.g. also check the outcome here to filter passed or failed tests only
rate = getattr(config, '_rate', None)
if rate is not None:
terminalreporter = config.pluginmanager.get_plugin('terminalreporter')
terminalreporter.ensure_newline()
terminalreporter.write_line(f'test {report.nodeid}, rate: {rate}', red=True, bold=True)
测试:
def report(rate, request):
request.config._rate = rate
def test_spam(request):
report(123, request)
def test_eggs(request):
report(456, request)
输出:
collected 2 items
test_spam.py .
test test_spam.py::test_spam, rate: 123
test_spam.py .
test test_spam.py::test_eggs, rate: 456
===================================================== 2 passed in 0.01 seconds =====================================================
测试执行后收集数据并打印
# conftest.py
def pytest_configure(config):
config._rates = dict()
def pytest_terminal_summary(terminalreporter, exitstatus, config):
terminalreporter.ensure_newline()
for testid, rate in config._rates.items():
terminalreporter.write_line(f'test {testid}, rate: {rate}', yellow=True, bold=True)
测试:
def report(rate, request):
request.config._rates[request.node.nodeid] = rate
def test_spam(request):
report(123, request)
def test_eggs(request):
report(456, request)
输出:
collected 2 items
test_spam.py ..
test test_spam.py::test_spam, rate: 123
test test_spam.py::test_eggs, rate: 456
===================================================== 2 passed in 0.01 seconds =====================================================
在 JUnit 中附加数据 XML 报告
使用 record_property
夹具:
def test_spam(record_property):
record_property('rate', 123)
def test_eggs(record_property):
record_property('rate', 456)
结果报告:
$ pytest --junit-xml=report.xml
...
$ xmllint --format report.xml
<testsuite errors="0" failures="0" name="pytest" skipped="0" tests="2" time="0.056">
<testcase classname="test_spam" file="test_spam.py" line="12" name="test_spam" time="0.001">
<properties>
<property name="rate" value="123"/>
</properties>
</testcase>
<testcase classname="test_spam" file="test_spam.py" line="15" name="test_eggs" time="0.001">
<properties>
<property name="rate" value="456"/>
</properties>
</testcase>
</testsuite>
我知道有用于 py.test 的性能测试和分析的插件,但是有没有办法生成任意值,这些值在测试后报告或以某种方式访问?
想象一下我有这样的测试
def test_minimum_learning_rate():
"""Make some fancy stuff and generate a learning performance value"""
learning_rate = fancy_learning_function().rate
pytest.report("rate", learning_rate)
assert learning_rate > 0.5
pytest.report(..)
行是我 喜欢 拥有的(但不存在,是吗?)
现在我想将 minimum_learning_rate[rate]
之类的内容与实际测试结果一起写入报告(或者至少在屏幕上)。
真的 Jenkins 的一些插件很不错,它可以根据该数据创建一个漂亮的图表。
有没有典型的措辞?我一直在寻找 kpi
、arbitrary values
、user defined values
,但还没有任何运气..
如果您只想输出一些调试值,print
调用结合 -s
参数就足够了:
def test_spam():
print('debug')
assert True
运行 pytest -s
:
collected 1 item
test_spam.py debug
.
如果您正在寻找可以更好地集成到 pytest
执行流程中的解决方案,请编写自定义挂钩。下面的例子应该会给你一些想法。
每次测试执行后打印自定义行
# conftest.py
def pytest_report_teststatus(report, config):
if report.when == 'teardown': # you may e.g. also check the outcome here to filter passed or failed tests only
rate = getattr(config, '_rate', None)
if rate is not None:
terminalreporter = config.pluginmanager.get_plugin('terminalreporter')
terminalreporter.ensure_newline()
terminalreporter.write_line(f'test {report.nodeid}, rate: {rate}', red=True, bold=True)
测试:
def report(rate, request):
request.config._rate = rate
def test_spam(request):
report(123, request)
def test_eggs(request):
report(456, request)
输出:
collected 2 items
test_spam.py .
test test_spam.py::test_spam, rate: 123
test_spam.py .
test test_spam.py::test_eggs, rate: 456
===================================================== 2 passed in 0.01 seconds =====================================================
测试执行后收集数据并打印
# conftest.py
def pytest_configure(config):
config._rates = dict()
def pytest_terminal_summary(terminalreporter, exitstatus, config):
terminalreporter.ensure_newline()
for testid, rate in config._rates.items():
terminalreporter.write_line(f'test {testid}, rate: {rate}', yellow=True, bold=True)
测试:
def report(rate, request):
request.config._rates[request.node.nodeid] = rate
def test_spam(request):
report(123, request)
def test_eggs(request):
report(456, request)
输出:
collected 2 items
test_spam.py ..
test test_spam.py::test_spam, rate: 123
test test_spam.py::test_eggs, rate: 456
===================================================== 2 passed in 0.01 seconds =====================================================
在 JUnit 中附加数据 XML 报告
使用 record_property
夹具:
def test_spam(record_property):
record_property('rate', 123)
def test_eggs(record_property):
record_property('rate', 456)
结果报告:
$ pytest --junit-xml=report.xml
...
$ xmllint --format report.xml
<testsuite errors="0" failures="0" name="pytest" skipped="0" tests="2" time="0.056">
<testcase classname="test_spam" file="test_spam.py" line="12" name="test_spam" time="0.001">
<properties>
<property name="rate" value="123"/>
</properties>
</testcase>
<testcase classname="test_spam" file="test_spam.py" line="15" name="test_eggs" time="0.001">
<properties>
<property name="rate" value="456"/>
</properties>
</testcase>
</testsuite>