如果py.test从另一个目录执行它,则coverage.py不包括脚本

Chr*_*oph 32 python coverage.py pytest

我有一个python脚本,它接受命令行参数,使用一些文件.我正在编写成功的测试,py.test将这个脚本放在其脚本中,并执行它subprocess.call.

现在我想分析代码覆盖率coverage.py.覆盖范围,通过使用时pytest-cov的插件(其中有子装卸内置),没有看到/覆盖我的剧本时,它从创建一个临时目录测试名为py.testtmpdir夹具.Coverage 在其所在的目录中调用时会看到我的脚本(并且filename参数指向远程路径).

在这两种情况下,我的测试通过!覆盖范围3.6,pytest-2.3.5,pytest-cov 1.6,全部来自PyPi.

问题:即使在另一个目录中执行脚本,如何识别我的脚本?这是覆盖范围内的错误,还是一些无法做到的事情?如果后者毕竟tmpdir是py.test的股票机制,那会感到惊讶......

最小的例子:

我有一个脚本my_script.py,它只是回应arg_file.txt通过命令行参数提供的文件的内容.在两个不同的测试中,这一次在a中调用tmpdir,一次在脚本的位置调用.两个测试都通过了,但是在tmpdir测试中,我没有得到任何覆盖信息!

测试运行:

~/pytest_experiment$ py.test -s
=================================== test session starts ====================================
platform linux2 -- Python 2.7.4 -- pytest-2.3.5
plugins: cov
collected 2 items 

tests/test_in_scriptdir.py 
set_up: In directory /tmp/pytest-52/test_10
Running in directory /home/cbuchner/pytest_experiment
Command: ./my_script.py /tmp/pytest-52/test_10/arg_file.txt
--Contents of arg_file.txt--

.
tests/test_in_tmpdir.py 
set_up: In directory /tmp/pytest-52/test_11
Running in directory /tmp/pytest-52/test_11
Command: /home/cbuchner/pytest_experiment/my_script.py arg_file.txt
--Contents of arg_file.txt--

.

================================= 2 passed in 0.06 seconds =================================
Run Code Online (Sandbox Code Playgroud)

覆盖范围:

~/pytest_experiment$ py.test --cov=my_script.py tests/test_in_scriptdir.py=================================== test session starts ====================================
platform linux2 -- Python 2.7.4 -- pytest-2.3.5
plugins: cov
collected 1 items 

tests/test_in_scriptdir.py .
--------------------- coverage: platform linux2, python 2.7.4-final-0 ----------------------
Name        Stmts   Miss  Cover
-------------------------------
my_script       3      0   100%

================================= 1 passed in 0.09 seconds =================================
~/pytest_experiment$ py.test --cov=my_script.py tests/test_in_tmpdir.py=================================== test session starts ====================================
platform linux2 -- Python 2.7.4 -- pytest-2.3.5
plugins: cov
collected 1 items 

tests/test_in_tmpdir.py .Coverage.py warning: No data was collected.

--------------------- coverage: platform linux2, python 2.7.4-final-0 ----------------------
Name    Stmts   Miss  Cover
---------------------------

================================= 1 passed in 0.09 seconds =================================
Run Code Online (Sandbox Code Playgroud)

文件在这里:https://gist.github.com/bilderbuchi/6412754

编辑: Interstingly,当运行覆盖测试时-s,也有更好奇的输出 - 覆盖警告No data was collected,显然它被收集,并在tmpdir测试中警告Module my_script.py was never imported.

~/pytest_experiment$ py.test -s --cov=my_script.py tests/test_in_scriptdir.py
=================================== test session starts ====================================
platform linux2 -- Python 2.7.4 -- pytest-2.3.5
plugins: cov
collected 1 items 

tests/test_in_scriptdir.py 
set_up: In directory /tmp/pytest-63/test_10
Running in directory /home/cbuchner/pytest_experiment
Command: ./my_script.py /tmp/pytest-63/test_10/arg_file.txt
--Contents of arg_file.txt--

Coverage.py warning: No data was collected.
.
--------------------- coverage: platform linux2, python 2.7.4-final-0 ----------------------
Name        Stmts   Miss  Cover
-------------------------------
my_script       3      0   100%

================================= 1 passed in 0.09 seconds =================================
~/pytest_experiment$ py.test -s --cov=my_script.py tests/test_in_tmpdir.py=================================== test session starts ====================================
platform linux2 -- Python 2.7.4 -- pytest-2.3.5
plugins: cov
collected 1 items 

tests/test_in_tmpdir.py 
set_up: In directory /tmp/pytest-64/test_10
Running in directory /tmp/pytest-64/test_10
Command: /home/cbuchner/pytest_experiment/my_script.py arg_file.txt
--Contents of arg_file.txt--

Coverage.py warning: Module my_script.py was never imported.
Coverage.py warning: No data was collected.
Coverage.py warning: Module my_script.py was never imported.
Coverage.py warning: No data was collected.
.Coverage.py warning: No data was collected.

--------------------- coverage: platform linux2, python 2.7.4-final-0 ----------------------
Name    Stmts   Miss  Cover
---------------------------

================================= 1 passed in 0.09 seconds =================================
Run Code Online (Sandbox Code Playgroud)

小智 15

从tox调用"py.test --cov ..."时遇到了同样的问题.我在这个页面上找到了一个提示:http://blog.ionelmc.ro/2014/05/25/python-packaging/,尽管它没有明确提到这一点.对tox使用"--develop"将确保从覆盖率分析的同一目录中调用覆盖数据收集.tox.ini中的这一部分使我有一个覆盖测试环境:

[tox]
envlist = ...,py34,cov

[testenv:cov]
# necessary to make cov find the .coverage file
# see http://blog.ionelmc.ro/2014/05/25/python-packaging/
usedevelop = true
commands = py.test --cov=<MODULE_NAME>
deps = pytest pytest-cov
Run Code Online (Sandbox Code Playgroud)

  • 这使得测试不那么彻底,因为您没有测试setup.py生成的dist. (2认同)

Chr*_*oph 5

当从另一个目录运行测量的脚本时,这被证明是相对路径混淆覆盖的问题.覆盖率结果文件最终在该目录中,而不是项目的根目录.

为了解决这个问题,我停止使用pytest-cov,coverage而是使用纯粹的.我使用完整路径而不是相关路径.

因此,例如,定义启用子进程覆盖所需的环境变量export COVERAGE_PROCESS_START=/full/path/to/.coveragerc.在.coveragerc,通过指定覆盖结果文件

     [run]
     data_file = /full/path/to/.coverage
Run Code Online (Sandbox Code Playgroud)

而且任何--source--include选项也应该使用完整路径.然后就可以获得正确的覆盖率测量.

  • 我担心这不是一个普遍接受的答案,因为如果你有持续的整合,这是行不通的,我们需要一个合适的解决方案. (26认同)
  • @Christoph:您经常无法控制(也不必控制)构建/提取源的确切位置(无论构建步骤是否相关).因此需要依赖相对路径. (7认同)