Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

253
Vistas
Cómo parametrizar un dispositivo Pytest

Considere la siguiente Pytest:

 import pytest class TimeLine(object): instances = [0, 1, 2] @pytest.fixture def timeline(): return TimeLine() def test_timeline(timeline): for instance in timeline.instances: assert instance % 2 == 0 if __name__ == "__main__": pytest.main([__file__])

La prueba test_timeline usa un accesorio Pytest, timeline , que a su vez tiene el atributo instances . Este atributo se repite en la prueba, de modo que la prueba solo pasa si la afirmación se cumple para cada instance en timeline.instances .

Sin embargo, lo que realmente me gustaría hacer es generar 3 pruebas, 2 de las cuales deberían pasar y 1 fallaría. He intentado

 @pytest.mark.parametrize("instance", timeline.instances) def test_timeline(timeline): assert instance % 2 == 0

pero esto conduce a

 AttributeError: 'function' object has no attribute 'instances'

Según tengo entendido, en los accesorios de Pytest, la función 'se convierte' en su valor de retorno, pero esto parece no haber sucedido aún en el momento en que se parametriza la prueba. ¿Cómo puedo configurar la prueba de la manera deseada?

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

Esto es realmente posible a través de la parametrización indirecta .

Este ejemplo hace lo que quieres con pytest 3.1.2:

 import pytest class TimeLine: def __init__(self, instances): self.instances = instances @pytest.fixture def timeline(request): return TimeLine(request.param) @pytest.mark.parametrize( 'timeline', ([1, 2, 3], [2, 4, 6], [6, 8, 10]), indirect=True ) def test_timeline(timeline): for instance in timeline.instances: assert instance % 2 == 0 if __name__ == "__main__": pytest.main([__file__])

También vea esta pregunta similar .

over 4 years ago · Santiago Trujillo Denunciar

0

en lugar de la parametrización indirecta, o mi solución hacky a continuación que involucra la herencia, también puede usar el argumento params para @pytest.fixture() - creo que esta es la solución más simple, ¿quizás?

 import pytest class TimeLine: def __init__(self, instances=[0, 0, 0]): self.instances = instances @pytest.fixture(params=[ [1, 2, 3], [2, 4, 5], [6, 8, 10] ]) def timeline(request): return TimeLine(request.param) def test_timeline(timeline): for instance in timeline.instances: assert instance % 2 == 0

https://docs.pytest.org/en/latest/how-to/fixtures.html#parametrización-de-fixtures

over 4 years ago · Santiago Trujillo Denunciar

0

Este es un tema confuso, porque la gente tiende a pensar que los accesorios y los parámetros son lo mismo. No se recopilan y ni siquiera se recopilan en la misma fase de la ejecución de pytest. Por diseño, los parámetros deben recopilarse cuando se recopilan las pruebas (la lista de nodos de prueba está en construcción), mientras que los accesorios deben ejecutarse cuando se ejecutan los nodos de prueba (la lista de nodos de prueba es fija y no se puede modificar). Por lo tanto, los contenidos de los dispositivos no se pueden usar para cambiar la cantidad de nodos de prueba: esta es la función de los parámetros. Vea también mi respuesta detallada aquí .

Esta es la razón por la cual su pregunta no tiene solución "tal cual": debe colocar las instancias de la Timeline de tiempo en un parámetro, no en un accesorio. Me gusta esto:

 import pytest class TimeLine(object): instances = [0, 1, 2] @pytest.fixture(params=TimeLine().instances) def timeline(request): return request.param def test_timeline(timeline): assert timeline % 2 == 0

La respuesta de Kurt Peek menciona otro tema que en mi humilde opinión agrega confusión aquí porque no está directamente relacionado con su pregunta. Dado que se menciona, e incluso se acepta como la solución, permítanme elaborar: de hecho, en pytest, no puede usar un accesorio en un @pytest.mark.parametrize . Pero incluso si pudieras, eso no cambiaría nada.

Dado que esta función ahora está disponible en pytest-cases (soy el autor), puede probarlo usted mismo. La única forma de hacer que su ejemplo funcione incluso con esa función sigue siendo la misma: eliminar la lista del dispositivo. Entonces terminas con:

 import pytest from pytest_cases import parametrize, fixture_ref class TimeLine(object): instances = [0, 1, 2] @pytest.fixture(params=TimeLine().instances) def timeline(request): return request.param @parametrize("t", [fixture_ref(timeline)]) def test_timeline(t): assert t % 2 == 0

Que es lo mismo que el ejemplo anterior con una capa adicional, probablemente inútil. Nota: ver también esta discusión .

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda