python - setup - ¿Cómo puedo repetir cada prueba varias veces en una prueba py.test?
pytest vs unittest (5)
Basándome en la sugerencia de Frank T, encontré una solución muy simple en el reclamo pytest_generate_tests ():
parser.addoption (''--count'', default=1, type=''int'', metavar=''count'', help=''Run each test the specified number of times'')
def pytest_generate_tests (metafunc):
for i in range (metafunc.config.option.count):
metafunc.addcall()
Ahora, ejecutar "py.test --count 5" hace que cada prueba se ejecute cinco veces en la sesión de prueba.
Y no requiere cambios en ninguna de nuestras pruebas existentes.
Gracias Frank T!
Quiero ejecutar cada elemento py.test seleccionado un número arbitrario de veces, secuencialmente.
No veo ningún mecanismo estándar de py.test para hacer esto.
pytest_collection_modifyitems()
hacer esto en el gancho pytest_collection_modifyitems()
. Modifiqué la lista de elementos pasados para especificar cada elemento más de una vez. La primera ejecución de un elemento de prueba funciona como se esperaba, pero eso parece causar algunos problemas para mi código.
Además, preferiría tener un objeto de prueba único para cada ejecución, ya que uso id (artículo) como clave en varios códigos de informe. Desafortunadamente, no puedo encontrar ningún código py.test para duplicar un elemento de prueba, copy.copy()
no funciona, y copy.deepcopy()
obtiene una excepción.
¿Alguien puede sugerir una estrategia para ejecutar una prueba varias veces?
Basado en lo que he visto aquí, y dado que ya he realizado un filtrado de pruebas en pytest_collection_modifyitems
, mi método de elección es el siguiente. En conftest.py
def pytest_addoption(parser):
parser.addoption (''--count'', default=1, type=''int'', metavar=''count'', help=''Run each test the specified number of times'')
def pytest_collection_modifyitems(session, config, items):
count = config.option.count
items[:] = items * count # add each test multiple times
El módulo pytest-repeat existe para este propósito, y recomiendo usar módulos cuando sea posible, en lugar de volver a implementar su funcionalidad.
Para usarlo, simplemente agregue pytest-repeat
a sus requirements.txt
o pip install pytest-repeat
, luego ejecute sus pruebas con --count n
.
Para ejecutar cada prueba varias veces, parametrizaremos cada prueba a medida que se generan.
Primero, agreguemos la opción del analizador (incluya lo siguiente en uno de sus conftest.py):
def pytest_addoption(parser):
parser.addoption(''--repeat'', action=''store'',
help=''Number of times to repeat each test'')
Ahora agregamos un gancho "pytest_generate_tests". Aquí es donde ocurre la magia.
def pytest_generate_tests(metafunc):
if metafunc.config.option.repeat is not None:
count = int(metafunc.config.option.repeat)
# We''re going to duplicate these tests by parametrizing them,
# which requires that each test has a fixture to accept the parameter.
# We can add a new fixture like so:
metafunc.fixturenames.append(''tmp_ct'')
# Now we parametrize. This is what happens when we do e.g.,
# @pytest.mark.parametrize(''tmp_ct'', range(count))
# def test_foo(): pass
metafunc.parametrize(''tmp_ct'', range(count))
Corriendo sin la bandera de repetición:
(env) $ py.test test.py -vv
============================= test session starts ==============================
platform darwin -- Python 2.7.5 -- py-1.4.20 -- pytest-2.5.2 -- env/bin/python
collected 2 items
test.py:4: test_1 PASSED
test.py:8: test_2 PASSED
=========================== 2 passed in 0.01 seconds ===========================
Corriendo con la bandera de repetición:
(env) $ py.test test.py -vv --repeat 3
============================= test session starts ==============================
platform darwin -- Python 2.7.5 -- py-1.4.20 -- pytest-2.5.2 -- env/bin/python
collected 6 items
test.py:4: test_1[0] PASSED
test.py:4: test_1[1] PASSED
test.py:4: test_1[2] PASSED
test.py:8: test_2[0] PASSED
test.py:8: test_2[1] PASSED
test.py:8: test_2[2] PASSED
=========================== 6 passed in 0.01 seconds ===========================
Otras lecturas:
Una posible estrategia es parametrizar la prueba en cuestión, pero no usar explícitamente el parámetro.
Por ejemplo:
@pytest.mark.parametrize(''execution_number'', range(5))
def run_multiple_times(execution_number):
assert True
La prueba anterior debe ejecutarse cinco veces.
Consulte la documentación de parametrización: https://pytest.org/latest/parametrize.html