Ich habe ein Python-Skript erhalten, das Befehlszeilenargumente verwendet und mit einigen Dateien arbeitet .. __ Ich schreibe nachfolgende Tests mit py.test
, indem es dieses Skript durchläuft und es mit subprocess.call
ausführt.
Jetzt möchte ich die Codeabdeckung mit coverage.py
. Coverage analysieren, wenn sie über das pytest-cov
-Plugin (das über eine integrierte Subprozessverarbeitung verfügt) verwendet wird. Sieht mein Skript nicht, wenn es von einem temporären Aufruf aufgerufen wird testverzeichnis erstellt mit py.test
s tmpdir
fixture . Coverage sieht mein Skript, wenn es in dem Verzeichnis aufgerufen wird, in dem es sich befindet (und das Argument Dateiname auf einen entfernten Pfad zeigt).
In beiden Situationen bestehen meine Tests! Abdeckung 3.6, pytest-2.3.5, pytest-cov 1.6, alle von PyPi.
Frage: Wie kann ich mein Skript erkennen, auch wenn es in einem anderen Verzeichnis ausgeführt wird? Ist dies ein Fehler in der Berichterstattung oder etwas, das einfach nicht möglich ist? Würde mich wundern, wenn letztere tmpdir
ein Aktienmechanismus von py.test ist ...
Minimales Beispiel:
Ich habe ein Skript my_script.py
erhalten, das nur den Inhalt einer über das Befehlszeilenargument angegebenen arg_file.txt
-Datei wiedergibt. In zwei verschiedenen Tests wird dies einmal in einer tmpdir
und einmal am Ort des Skripts aufgerufen. Beide Tests bestehen, aber beim tmpdir-Test bekomme ich keine Abdeckungsinformationen!
Testlauf:
~/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 =================================
Deckung:
~/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 =================================
Die Dateien sind hier: https://Gist.github.com/bilderbuchi/6412754
Edit: Interessanterweise gibt es auch beim Ausführen der Abdeckungstests mit -s
mehr merkwürdige Ausgaben - die Abdeckung warnt, dass No data was collected
, wenn offensichtlich gesammelt wurde, und im tmpdir
-Test warnt 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 =================================
Dies stellte sich als Problem der relativen Pfade heraus, die die Abdeckung verwirren, wenn das gemessene Skript aus einem anderen Verzeichnis ausgeführt wird. Coverage-Ergebnisdateien landeten in diesem Verzeichnis und nicht im Stammverzeichnis des Projekts.
Um dieses Problem zu lösen, habe ich auf pytest-cov
verzichtet und stattdessen reine coverage
verwendet. Ich habe vollständige Pfade anstelle von relativen Pfaden verwendet, wo immer dies relevant ist.
So z.B. definiert die Umgebungsvariable, die erforderlich ist, um die Abdeckung von Unterprozessen über export COVERAGE_PROCESS_START=/full/path/to/.coveragerc
zu aktivieren. Im .coveragerc
wird die Coverage-Ergebnisdatei über angegeben
[run]
data_file = /full/path/to/.coverage
und alle --source
- und --include
-Optionen sollten auch vollständige Pfade verwenden ..__ Dann war es möglich, eine korrekte Überdeckungsmessung zu erhalten.
Ich habe das gleiche Problem festgestellt, als ich "py.test --cov ..." von tox aufgerufen habe. Ich habe auf dieser Seite einen Hinweis gefunden: http://blog.ionelmc.ro/201/05/05/25/python-packaging/ obwohl dies nicht explizit erwähnt wird. Wenn Sie "--develop" für tox verwenden, wird sichergestellt, dass die Erfassung der Abdeckungsdaten aus demselben Verzeichnis wie die Abdeckungsanalyse aufgerufen wird .. _ Dieser Abschnitt in tox.ini hat es mir ermöglicht, eine Testumgebung für die Abdeckung bereitzustellen :
[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
diesem Blog zufolge: https://thomas-cokelaer.info/blog/2017/01/pytest-cov-collects-no-data-on-travis/
Sie sollten alle __init__.py
Dateien in tests
Ordner! Diese Lösung funktioniert bei mir.
Eine weitere Option bei tox besteht darin, die PYTHONPATH
in tox.ini
einzustellen:
[testenv]
setenv =
PYTHONPATH = {toxinidir}
commands =
pytest --cov=<your package>
- codecov