测试pytest插件时如何获得覆盖率报告?

Tho*_*ood 10 python coverage.py pytest tox pytest-cov

语境

我正在更新一个测试覆盖率很差的继承存储库。repo 本身是一个 pytest 插件。我已经将 repo 更改为与tox一起使用pytest-cov,并将“原始”测试转换pytester为在测试插件时按照 pytest 文档中的建议使用。

测试和 tox 构建等效果很好。但是,覆盖率报告了类定义、导入等的错误未命中。这是因为代码本身是作为 pytest 实例化的一部分导入的,并且在测试实际开始之前不会被“覆盖”。

我已经阅读了 pytest 文档、pytest-cov 和覆盖率文档以及 tox 文档,并尝试了几种配置,但都无济于事。我已经用尽了可能会导致我找到一个好的解决方案的谷歌关键字组合池。

存储库布局

pkg_root/
    .tox/
        py3/
            lib/
                python3.7/
                    site-pacakges/
                        plugin_module/
                            supporting_module.py
                            plugin.py
                            some_data.dat
    plugin_module/
        supporting_module.py
        plugin.py
        some_data.dat
    tests/
        conftest.py
        test_my_plugin.py
    tox.ini
    setup.py
    
Run Code Online (Sandbox Code Playgroud)

一些带有评论的相关片段:

配置文件

[pytest]
addopts = --cov={envsitepackagesdir}/plugin_module --cov-report=html
testpaths = tests
Run Code Online (Sandbox Code Playgroud)

这个配置给我一个错误,没有收集数据;在这种情况下不会创建 htmlcov。

如果我只是使用--cov,我会得到(预期的)非常嘈杂的覆盖范围,它显示了功能命中和未命中,但是上面报告了导入、类定义等的错误未命中。

conftest.py

pytest_plugins = ['pytester']  # Entire contents of file!
Run Code Online (Sandbox Code Playgroud)

test_my_plugin.py

def test_a_thing(testdir):
    testdir.makepyfile(
        """
            def test_that_fixture(my_fixture):
                assert my_fixture.foo == 'bar'
        """
    )
    result = testdir.runpytest()
    result.assert_outcomes(passed=1)
Run Code Online (Sandbox Code Playgroud)

我怎样才能得到准确的报告?有没有办法推迟插件加载,直到 pytester 测试需要它?

Akh*_*rou 42

您无需 . 即可实现您想要的目标pytest-cov

\n
\n
\xe2\x9d\xaf coverage run --source=<package> --module pytest --verbose <test-files-dirs> && coverage report --show-missing\n
Run Code Online (Sandbox Code Playgroud)\n
或者更短
\n
\xe2\x9d\xaf coverage run --source=<package> -m pytest -v <test-files-dirs> && coverage report -m\n
Run Code Online (Sandbox Code Playgroud)\n
示例:(针对您的目录结构)
\n
\xe2\x9d\xaf coverage run --source=plugin_module -m pytest -v tests && coverage report -m\n
Run Code Online (Sandbox Code Playgroud)\n
======================= test session starts ========================\nplatform darwin -- Python 3.9.4, pytest-6.2.4, py-1.10.0, pluggy-0.13.1 -- /Users/johndoe/.local/share/virtualenvs/plugin_module--WYTJL20/bin/python\ncachedir: .pytest_cache\nrootdir: /Users/johndoe/projects/plugin_module, configfile: pytest.ini\ncollected 1 items\n\ntests/test_my_plugin.py::test_my_plugin PASSED               [100%]\n\n======================== 1 passed in 0.04s =========================\nName                            Stmts   Miss  Cover   Missing\n-------------------------------------------------------------\nplugin_module/supporting_module.py  4      0   100%\nplugin_module/plugin.py             6      0   100%\n-------------------------------------------------------------\nTOTAL                              21      0   100%\n
Run Code Online (Sandbox Code Playgroud)\n

为了获得更好的输出,您可以使用:

\n
\xe2\x9d\xaf coverage html && open htmlcov/index.html\n
Run Code Online (Sandbox Code Playgroud)\n

覆盖率 HTML 报告

\n
\n

文档

\n
\xe2\x9d\xaf coverage -h\n\xe2\x9d\xaf pytest -h\n
Run Code Online (Sandbox Code Playgroud)\n

coverage

\n
\n

run-- 运行 Python 程序并测量代码执行情况。

\n
\n

-m, --module--- 显示每个模块中未执行的语句的行号。

\n

--source=SRC1,SRC2,--- 要测量的代码包或目录的列表。

\n
\n

report-- 报告模块的覆盖率统计数据。

\n
\n

-m, --show-missing--- 显示每个模块中未执行的语句的行号。

\n
\n

html-- 创建 HTML 报告。

\n
\n

pytest

\n
\n

-v, --verbose——增加冗长程度。

\n
\n


Ned*_*der 15

不使用 pytest-cov 插件,而是使用 coverage 来运行 pytest:

coverage run -m pytest ....
Run Code Online (Sandbox Code Playgroud)

这样,覆盖将在 pytest 之前开始。

  • 这会创建一个“.coverage” SQLite 数据库文件,可以使用“覆盖率报告”读取该文件。 (5认同)