He heredado un código que implementa pytest.mark.skipif
para algunas pruebas. Al leer los documentos de Pytest, soy consciente de que puedo agregar condiciones, posiblemente verificar las variables de entorno o usar funciones más avanzadas de pytest.mark
para controlar grupos de pruebas juntas. Desafortunadamente, nada en los documentos hasta ahora parece resolver mi problema.
Estoy buscando simplemente desactivar cualquier omisión de prueba, pero sin modificar ningún código fuente de las pruebas. Solo quiero ejecutar pytest en un modo en el que no se respete ningún indicador de omisión de prueba. ¿Existe tal solución con pytest?
3 respuestas
Una solución fácil es hacer un parche de mono pytest.mark.skipif
en tu conftest.py
:
import pytest
old_skipif = pytest.mark.skipif
def custom_skipif(*args, **kwargs):
return old_skipif(False, reason='disabling skipif')
pytest.mark.skipif = custom_skipif
Una solución alternativa para ignorar las marcas de omisión es eliminarlas mediante programación. Cree un conftest.py
con el siguiente contenido:
def pytest_collection_modifyitems(items):
for item in items:
for node in reversed(item.listchain()):
node.own_markers = [m for m in node.own_markers if m.name not in ('skip', 'skipif')]
Sin embargo, esto interfiere con los elementos internos pytest
y puede romperse fácilmente en las actualizaciones pytest
; la forma correcta de ignorar los saltos debería ser definir su mecanismo de salto personalizado, por ejemplo:
@pytest.hookimpl(tryfirst=True)
def pytest_runtest_setup(item):
mark = item.get_closest_marker(name='myskip')
if mark:
condition = next(iter(mark.args), True)
reason = mark.kwargs.get('reason', 'custom skipping mechanism')
item.add_marker(pytest.mark.skipif(not os.getenv('PYTEST_RUN_FORCE_SKIPS', False) and condition, reason=reason), append=False)
Anote las pruebas con @pytest.mark.myskip
en lugar de @pytest.mark.skip
y @pytest.mark.myskip(condition, reason)
en lugar de @pytest.mark.skipif(condition, reason)
:
@pytest.mark.myskip
def test_skip():
assert True
@pytest.mark.myskip(1 == 1, reason='my skip')
def test_skipif():
assert True
En una ejecución regular, myskip
se comportará de la misma manera que pytest.mark.skip
/ pytest.mark.skipif
. La configuración PYTEST_RUN_FORCE_SKIPS
lo deshabilitará:
$ PYTEST_RUN_FORCE_SKIPS=1 pytest -v
...
test_spam.py::test_skip PASSED
test_spam.py::test_skipif PASSED
...
Por supuesto, no debes usar pytest.mark.skip
/ pytest.mark.skipif
ya que no serán influenciados por la PYTEST_RUN_FORCE_SKIPS
env var.
Ok, la implementación no permite esto con cero modificaciones. Necesitarás un marcador personalizado. Agregue lo siguiente a su conftest.py
y luego cambie todas las marcas skipif
a custom_skipif
. Use pytest --no-skips
.
import pytest
from _pytest.mark.evaluate import MarkEvaluator
def pytest_addoption(parser):
parser.addoption(
"--no-skips", action="store_true", default=False, help="disable custom_skip marks"
)
@hookimpl(tryfirst=True)
def pytest_runtest_setup(item):
if item.config.getoption('--no-skips'):
return
# Check if skip or skipif are specified as pytest marks
item._skipped_by_mark = False
eval_skipif = MarkEvaluator(item, "custom_skipif")
if eval_skipif.istrue():
item._skipped_by_mark = True
pytest.skip(eval_skipif.getexplanation())
for skip_info in item.iter_markers(name="custom_skip"):
item._skipped_by_mark = True
if "reason" in skip_info.kwargs:
pytest.skip(skip_info.kwargs["reason"])
elif skip_info.args:
pytest.skip(skip_info.args[0])
else:
pytest.skip("unconditional skip")
item._evalxfail = MarkEvaluator(item, "xfail")
check_xfail_no_run(item)
La implementación se copia y modifica desde pytest en skipping.py.
Preguntas relacionadas
Nuevas preguntas
python
Python es un lenguaje de programación multipropósito, de tipificación dinámica y de múltiples paradigmas. Está diseñado para ser rápido de aprender, comprender y usar, y hacer cumplir una sintaxis limpia y uniforme. Tenga en cuenta que Python 2 está oficialmente fuera de soporte a partir del 01-01-2020. Aún así, para preguntas de Python específicas de la versión, agregue la etiqueta [python-2.7] o [python-3.x]. Cuando utilice una variante de Python (por ejemplo, Jython, PyPy) o una biblioteca (por ejemplo, Pandas y NumPy), inclúyala en las etiquetas.