我有一个 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),它从 stdin 读取命令并在 stdout 上生成输出。它开始于python rift
.
测试目录包含两种类型的测试。
第一种类型的测试是测试单个类的传统单元测试。例如,测试 test_table.py 导入 table.py,并执行传统的 pytest 测试(使用断言等)。代码覆盖率测量按这些测试的预期工作: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")
启动裂痕包。然后它使用pexpect.sendline
将命令注入 CLI (stdin) 并使用pexpect.expect
检查 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
问题:如何使用 pexpect 获取代码覆盖率测量结果来报告第二种类型测试的生成的 rift 包中覆盖的行?
注意:我省略了一些我认为不相关的细节,完整的源代码位于https://github.com/brunorijsman/rift-python(更新:此存储库现在包含答案中建议的工作解决方案)