当前位置: 首页 > 知识库问答 >
问题:

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

阴鸿才
2023-03-14

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

我的项目的目录结构是:

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测试,并使用codecov查看代码覆盖率结果。

正在测试的软件包提供了一个命令行界面(CLI),它从stdin读取命令并在stdout上生成输出。它以python-rift开头。

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

第一类测试是测试单个类的传统单元测试。例如,test_表。py导入表。py,并执行传统的pytest测试(使用assert等)。这些测试的代码覆盖率测量工作与预期的一样:codecov准确地报告测试覆盖或不覆盖rift包中的哪些行。

# 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。生成(“python rift”)以启动rift包。然后使用pexpect。sendline将命令注入CLI(stdin),并使用pexpect。希望检查CLI(stdout)上命令的输出。测试功能运行良好,但codecov没有报告这些测试的代码覆盖率。

# 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

问题:我如何获得代码覆盖率测量值来报告生成的rift包中的覆盖线,以便使用pexpect进行第二种类型的测试?

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


共有2个答案

锺功
2023-03-14

您基本上必须启用子流程覆盖率跟踪。

我建议使用https://pypi.org/project/coverage_enable_subprocess/ 要轻松实现这一点。

建议/要求使用parallel=1,您必须导出COVERAGE\u PROCESS\u START,例如export COVERAGE\u PROCESS\u START=“$PWD/.coveragerc”

司马同
2023-03-14
匿名用户

使用覆盖率run来运行您的pect程序并收集数据:

如果您通常这样做:

pexpect.spawn("python rift")

然后改为:

pexpect.spawn("coverage run rift.py")

(来源)

测试之后,您可能希望将pexpect结果与“常规”单元测试结果结合起来<代码>覆盖率。py可以将多个文件合并到一个文件中进行报告。

一旦创建了许多这样的文件,就可以将它们全部复制到一个目录中,并使用combine命令将它们合并为一个。覆盖范围数据文件

$ coverage combine

(来源)

测试中的两个额外细节:

>

  • 在本例中的测试程序(test_sys_2n_l0_l1.py)中,您必须确保在终止pect生成的时刻和终止测试本身的时刻之间有一个延迟。否则,覆盖率将没有时间将结果写入到. coverage。我添加了一个睡眠(1.0)。

    使用"覆盖运行-并行模式裂缝"。这是需要(a)确保。覆盖不会被以后的运行覆盖,(b)使覆盖组合工作(由pytest--cov自动运行)

  •  类似资料:
    • 考虑以下代码: 测试可按如下方式执行: 覆盖报告将考虑涵盖的所有第100%行,即使启用分支覆盖: 然而,这段代码有一个错误,那些有敏锐眼光的人可能已经看到了。如果它进入“其他”分支,将会有一个例外: 修复该错误很容易:将未定义的名称更改为文本。还可以很容易地添加另一个测试来揭示错误:。这也不是这个问题所要问的。我想知道如何找到尽管有100%的代码覆盖率报告但从未实际执行过的代码段。 使用条件表达式

    • 我不熟悉使用pytest和pytest cov,因为它已经从unittest覆盖范围切换过来。派克 我首先将自动测试设置为以这种方式运行: 这给了我这样的输出到终端: 然后我想生成一个xml报告,所以我更改了命令: 我遇到的问题是,在添加后,我不再得到任何输出到终端 查看pytest cov的文档,我发现: 这三个报告选项输出到文件而不在终端上显示任何内容:[继续显示xml、html和注释报告选项

    • 面对使用覆盖率运行pytest时出现的问题,我已经浏览了SO帖子,但无法解决此问题,我相信我在这里遗漏了一些东西。。 获取以下错误,其中用户是我项目的应用程序 我的测试。ini文件内容 [pytest]DJANGO_设置_模块=cloudstack。设置 python\u文件=测试。py测试*。py*\u测试。py addopts=-v--ignore=venv--cov=--cov报告=html

    • 当使用 生成覆盖率报告后,我的测试在代码覆盖率报告中显示为100%覆盖,如下所示 我尝试将测试移动到它自己的文件夹中,但仍然会得到相同的结果 实际的单元测试不应该出现在覆盖率报告中,并且扭曲了我的覆盖率。它应该只显示实际程序的覆盖范围。

    • 我使用jenkins的代码为每个插件生成覆盖率,并显示我喜欢的管道。是否有一个插件我可以使用它(例如Cobertura,但它似乎不受管道支持)?

    • Jacoco插件在jenkins报告中显示0%的覆盖率,但当我在本地系统中运行相同的命令时,Jacoco会正确生成报告。我正在使用以下命令: mvn-s xyz/settings.xml-f xyz/xyz/pom.xml清洁安装org.jacoco 所以当我在jenkins中运行这个命令时,它会生成错误的报告。我已经检查了它在工作区目录对应的项目在詹金斯。它显示每个项目的0%覆盖率。但是当我在本