python - cobertura.py no cubre el script si py.test lo ejecuta desde otro directorio
coverage.py (3)
Esto resultó ser un problema de rutas relativas que confunden la cobertura cuando el script medido se ejecuta desde otro directorio. Los archivos de resultados de cobertura terminaron en ese directorio, en lugar del directorio raíz del proyecto.
Para resolver esto, dejé de usar pytest-cov
, y en su lugar usé coverage
pura. Usé rutas completas en lugar de rutas relativas donde sea relevante.
Entonces, por ejemplo, defina la variable de entorno necesaria para habilitar la cobertura del subproceso a través de la export COVERAGE_PROCESS_START=/full/path/to/.coveragerc
. En .coveragerc
, el archivo de resultados de cobertura se especifica a través de
[run]
data_file = /full/path/to/.coverage
y cualquier --source
e --include
debe usar rutas completas. Luego fue posible obtener una medición de cobertura correcta.
Obtuve un script de python que toma argumentos de línea de comandos, trabajando con algunos archivos. Estoy escribiendo pruebas py.test
con py.test
poniendo este script a su ritmo, ejecutándolo con subprocess.call
.
Ahora quiero analizar la cobertura de código con coverage.py
. La cobertura, cuando se usa a través del pytest-cov
(que tiene incorporado el manejo de subprocesos), no ve / cubre mi script cuando se llama desde un directorio de prueba temporal creado con el accesorio tmpdir
. La cobertura ve mi script cuando se llama en el directorio en el que reside (y el argumento del nombre de archivo apunta a una ruta remota).
En ambas situaciones, mis exámenes pasan ! Cobertura 3.6, pytest-2.3.5, pytest-cov 1.6, todo desde PyPi.
Pregunta: ¿Cómo puedo obtener cobertura para reconocer mi script incluso si se ejecuta en otro directorio? ¿Es este un error en la cobertura, o algo que simplemente no es posible hacer? Me sorprendería que este último, después de todo, tmpdir
sea un mecanismo común de py.test ...
Ejemplo mínimo:
my_script.py
un script my_script.py
que solo hace eco del contenido de un archivo arg_file.txt
proporcionado a través del argumento de línea de comandos. En dos pruebas diferentes, esto se llama una vez en un tmpdir
, y una vez en la ubicación del script. Ambas pruebas pasan, pero en la prueba tmpdir, ¡no recibo información de cobertura!
Prueba de funcionamiento:
~/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 =================================
Cobertura:
~/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 =================================
Los archivos están aquí: https://gist.github.com/bilderbuchi/6412754
Edit: Interstingly, cuando se ejecutan las pruebas de cobertura con -s
, también hay resultados más curiosos: la cobertura advierte que No data was collected
, cuando obviamente se recopilaron, y en la prueba tmpdir
advierte que el 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 =================================
Me encontré con el mismo problema al llamar "py.test --cov ..." de tox. Encontré una pista en esta página: http://blog.ionelmc.ro/2014/05/25/python-packaging/ aunque no menciona esto explícitamente. El uso de "--develop" para tox se asegurará de que la recopilación de datos de cobertura se llame desde el mismo directorio que el análisis de cobertura. Esta sección en tox.ini hizo que me funcionara tener un entorno de prueba para la cobertura:
[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
Otra opción con tox es configurar PYTHONPATH
en tox.ini
:
[testenv] setenv = PYTHONPATH = {toxinidir} commands = pytest --cov=<your package> - codecov