web-dev-qa-db-ja.com

py.testが別のディレクトリからスクリプトを実行する場合、coverage.pyはスクリプトをカバーしません

私はpythonスクリプトを取得し、コマンドライン引数を取り、いくつかのファイルを操作します。py.testを使用して次のテストを作成し、このスクリプトをそのペースで実行し、subprocess.call

次に、coverage.pyを使用してコードカバレッジを分析します。カバレッジ、pytest-covプラグイン(サブプロセス処理が組み込まれている)を介して使用される場合、スクリプトが表示されない/カバーされない場合py.testtmpdirフィクスチャで作成された一時的なテストディレクトリから呼び出されます。カバレッジは、スクリプトが存在するディレクトリで呼び出されたときにスクリプトを参照します(およびファイル名引数がリモートパスを指します)。

両方の状況で、私のテストに合格しました!カバレッジ3.6、pytest-2.3.5、pytest-cov 1.6、すべてPyPiから。

質問:スクリプトが別のディレクトリで実行されている場合でも、スクリプトを認識するためにカバレッジを取得するにはどうすればよいですか?これはカバレッジのバグですか、それとも実行できないことですか?後者、結局のところ、tmpdirがpy.testのストックメカニズムであるとしたら、驚くでしょう...

最小限の例:

スクリプトmy_script.pyを取得しました。このスクリプトは、コマンドライン引数を介して指定されたファイルarg_file.txtの内容をエコーするだけです。 2つの異なるテストで、これは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 =================================

カバレッジ:

~/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 =================================

ファイルは次のとおりです: https://Gist.github.com/bilderbuchi/6412754

編集:興味深いことに、-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 =================================
32
Christoph

これは、測定されたスクリプトを別のディレクトリから実行すると、相対パスがカバレッジを混乱させる問題であることが判明しました。カバレッジ結果ファイルは、プロジェクトのルートディレクトリではなく、そのディレクトリに配置されていました。

これを解決するために、pytest-covの使用をやめ、代わりに純粋なcoverageを使用しました。関係がある場合は、相対パスではなくフルパスを使用しました。

したがって、たとえばexport COVERAGE_PROCESS_START=/full/path/to/.coveragercを介してサブプロセスカバレッジを有効にするために必要な環境変数を定義します。 .coveragercでは、カバレッジ結果ファイルは、

     [run]
     data_file = /full/path/to/.coverage

また、--sourceおよび--includeオプションもフルパスを使用する必要があります。その後、正しいカバレッジ測定値を取得することができました。

5
Christoph

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
15
okurz

このブログによると: https://thomas-cokelaer.info/blog/2017/01/pytest-cov-collects-no-data-on-travis/

testsフォルダ内のすべての__init__.pyファイルを追加する必要があります!この解決策は私にとってはうまくいきます。

0
Jingpeng Wu

Toxのもう1つのオプションは、tox.iniPYTHONPATHを設定することです。

[testenv] setenv = PYTHONPATH = {toxinidir} commands = pytest --cov=<your package> - codecov

0
Midnighter