9

让我们使用以下代码(conftest.py):

import random
def test_val():
    value = random.random()
    assert value < 0.5

运行py.test --junitxml=result.xml conftest.py生成result.xml(当测试通过时):

<?xml version="1.0" encoding="utf-8"?>
<testsuite errors="0" failures="0" name="" skips="0" tests="1" time="0.047">
<testcase classname="conftest" name="test_val" time="0.0"/>
</testsuite>

现在。我想做的是存储 in 生成的test_val()results.xml。有没有办法做到这一点?我似乎在pytest doc中找不到任何相关的内容。

4

3 回答 3

5

随附的 junitxml 插件没有添加此类数据的挂钩,但您可以将其打印到标准输出,因为它已添加到 junitxml 数据中。

所以只要你打印出日志,你至少就能知道数据。

于 2012-06-23T14:31:00.003 回答
3

您可以解决您的问题,但不能使用junitxml。

你可以用pytest-harvest这个。只需安装它,您就可以直接使用预定义的夹具:

import random

def test_val(results_bag):
    value = random.random()

    # save it (before test !)
    results_bag.value = value

    assert value < 0.5

def test_synthesis(module_results_df):
    """
    Shows that the `module_results_df` fixture already contains what you need
    """
    # drop the 'pytest_obj' column
    module_results_df.drop('pytest_obj', axis=1, inplace=True)

    print("\n   `module_results_df` dataframe:\n")
    print(module_results_df)

产量

>>> pytest -s -v

============================= test session starts =============================
collecting ... collected 2 items
tmp.py::test_val PASSED
tmp.py::test_synthesis 
   `module_results_df` dataframe:

          status  duration_ms     value
test_id                                
test_val  passed     0.999928  0.443547
PASSED

========================== 2 passed in 1.08 seconds ===========================

然后,您可以决定将数据帧转储为 csv 或专用文件中的任何其他格式。请注意,您不必在测试中编写上述内容,您可以从任何 pytest 挂钩(您可以访问上述固定装置或 pytestrequest.session对象的地方)来完成。

有关详细信息,请参阅文档。

最后,如果您还希望使用参数、固定装置、步骤……您可能希望查看这个数据科学基准示例

顺便说一句,我是作者;)

于 2018-12-19T17:04:09.853 回答
2

多年过去了,应该注意最好的解决方案。

来自 Pytest 的record_property夹具文档:

向调用测试添加额外的属性。

用户属性成为测试报告的一部分,可供配置的报告器使用,例如 JUnit XML。

夹具可通过名称、值调用。该值自动进行 XML 编码。

为通过和失败的案例捕获属性。

套房:

def test_passes(record_property):
    record_property("key", "value1")
    assert 1 == 1


def test_fails(record_property):
    record_property("key", "value2")
    assert 1 == 2

pytest运行时的结果--junitxml=result.xml

生成的 Junit 测试报告:

<?xml version="1.0" encoding="utf-8"?>
<testsuites>
    <testsuite name="pytest" errors="0" failures="1" skipped="0" tests="2" time="0.085"
               timestamp="2021-04-12T14:25:09.900867" hostname="DESKTOP">
        <testcase classname="test_something" name="test_passes" time="0.001">
            <properties>
                <property name="key" value="value1"/>
            </properties>
        </testcase>
        <testcase classname="test_something" name="test_fails" time="0.001">
            <properties>
                <property name="key" value="value2"/>
            </properties>
            <failure message="assert 1 == 2">record_property = &lt;function record_property.&lt;locals&gt;.append_property
                at 0x000001A1A9EB40D0&gt;

                def test_fails(record_property):
                record_property("key", "value2")
                &gt; assert 1 == 2
                E assert 1 == 2

                test_something.py:8: AssertionError
            </failure>
        </testcase>
    </testsuite>
</testsuites>

如果您运行的 Pytest 版本非常新,您会看到弃用警告

test_something.py::test_fails
  test_something.py:6: PytestWarning: record_property is incompatible with junit_family 'xunit2' (use 'legacy' or 'xunit1')
    def test_fails(record_property):

这是因为 Xunit 报告的架构发生了变化。来自 Pytest更改日志

  • 当与 junit_family=xunit2 一起使用时,record_property 现在会发出 PytestWarning:fixture 生成属性标记作为测试用例的子项,根据最新的模式 <https://github.com/jenkinsci/xunit-plugin/blob/master,这是不允许的/

要克服警告,您可以:

  1. 使用覆盖标志运行 Pytest-o junit_family="xunit1"或将此属性放在pytest.ini

  2. 使用record_testsuite_property会话范围的夹具。尽管如此,这仅允许将属性附加到测试套件级别。

于 2021-04-12T12:29:26.253 回答