我有一个Python项目,使用pytest-cov进行单元测试和代码覆盖率测量。
我的项目目录结构如下:
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),它从标准输入读取命令并在标准输出上产生输出。它的启动方式是python rift
。
测试目录包含两种类型的测试。
第一种类型的测试是传统的单元测试,用于测试单个类。例如,test_table.py测试文件导入table.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.spawn("python rift")
启动rift包。然后,它使用 pexpect.sendline
将命令注入CLI(标准输入),并使用 pexpect.expect
检查CLI(标准输出)中的命令输出。测试功能正常,但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
问题:如何使用pexpect获取代码覆盖率测量结果,以报告第二类测试中生成的rift软件包中的已覆盖行?
注意: 我省略了几个我认为不相关的细节,完整的源代码可在https://github.com/brunorijsman/rift-python中找到(更新:此存储库现在包含答案中建议的工作解决方案)。
pytest-cov
测量到的覆盖率的有效夹具示例,应该与您想要的差不多。 - hoefling