首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >pytest-cov如何报告作为pexpect.spawn结果执行的python代码的覆盖率?

pytest-cov如何报告作为pexpect.spawn结果执行的python代码的覆盖率?
EN

Stack Overflow用户
提问于 2018-08-02 22:19:27
回答 2查看 3.2K关注 0票数 4

我有一个Python项目,它使用pytest-cov进行单元测试和代码覆盖率度量。

我的项目的目录结构是:

代码语言:javascript
复制
rift-python
+- rift                        # The package under test
|  +- __init__.py
|  +- __main__.py
|  +- cli_listen_handler.py
|  +- cli_session_handler.py
|  +- table.py
|  +- ...lots more...
+- tests                       # The tests 
|  +- test_table.py
|  +- test_sys_2n_l0_l1.py
|  +- ...more...
+- README.md
+- .travis.yml
+- ...

我使用Travis对每个签入运行pytest --cov=rift tests,并使用codecov查看代码覆盖结果。

正在测试的包提供一个命令行接口(CLI),它从stdin读取命令并在stdout上生成输出。它以python rift的形式启动。

测试目录包含两种类型的测试。

第一种测试类型是测试单个类的传统单元测试。例如,测试test_table.py导入table.py,并执行传统的pytest测试(使用断言等)。代码覆盖率度量与这些测试的预期工作一样: codecov准确地报告了裂缝包中的哪些行被测试覆盖了。

代码语言:javascript
复制
# test_table.py (codecov works)

import table

def test_simple_table():
    tab = table.Table()
    tab.add_row(['Animal', 'Legs'])
    tab.add_rows([['Ant', 6]])
    ...
    tab_str = tab.to_string()
    assert (tab_str == "+--------+------+\n"
                       "| Animal | Legs |\n"
                       "+--------+------+\n"
                       "| Ant    | 6    |\n"
                       "+--------+------+\n"
                       ...
                       "+--------+------+\n")

第二种类型的测试使用pexpect:它使用pexpect.spawn("python rift")启动裂谷包。然后使用pexpect.sendline将命令注入CLI (stdin),并使用pexpect.expect检查CLI (stdout)上命令的输出。测试功能运行良好,但codecov没有报告这些测试的代码覆盖率。

代码语言:javascript
复制
# test_sys_2n_l0_l1.py (codecov does not pick up coverage of rift package)
# Greatly simplified example

import pexpect

def test_basic():
    rift = pexpect.spawn("python rift")
    rift.sendline("cli command")
    rift.expect("expected output")  # Throws exception if expected output not seen

问:如何获得代码覆盖率度量来报告第二种类型的测试(使用pexpect )生成的裂缝包中的覆盖行?

注意:我忽略了一些我认为无关的细节,https://github.com/brunorijsman/rift-python的完整源代码(更新:这个回购现在包含了答案中建议的工作解决方案)。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-08-02 22:50:28

使用coverage run运行pexpect程序并收集数据:

如果你经常这样做:

代码语言:javascript
复制
pexpect.spawn("python rift")

那就去做:

代码语言:javascript
复制
pexpect.spawn("coverage run rift.py")

(来源)

测试之后,您可能希望将pexpect结果与“常规”单元测试结果结合起来。coverage.py可以将多个文件合并成一个用于报告的文件。

一旦创建了许多这样的文件,就可以将它们全部复制到一个目录中,并使用combine命令将它们组合成一个.coverage数据文件:

代码语言:javascript
复制
$ coverage combine

(来源)

测试的两个附加细节:

  • 在本例中的测试程序(test_sys_2n_l0_l1.py)中,必须确保在终止pexpect生成的时刻和终止测试本身的时刻之间存在延迟。否则,覆盖率将没有时间将结果写入.coverage。我添加了一个睡眠(1.0)。
  • 使用“覆盖运行--并行模式裂缝”。这是为了(a)确保.coverage不被以后的运行覆盖,和(b)使“覆盖率合并”工作(由"pytest --cov“自动运行)。
票数 2
EN

Stack Overflow用户

发布于 2018-10-14 13:01:39

基本上,您必须启用子进程覆盖跟踪

我建议使用子进程/轻松地启用此功能。

因此,建议/需要使用parallel = 1,并且您必须导出COVERAGE_PROCESS_START,例如export COVERAGE_PROCESS_START="$PWD/.coveragerc"

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51662884

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档