test setup example python class python-2.7 object py.test pytest

python - example - pytest setup



¿Cómo configuro y desmonto correctamente mi clase de pytest con pruebas? (5)

Estoy usando selenio para las pruebas de extremo a extremo y no puedo entender cómo usar los métodos setup_class y teardown_class .

Necesito configurar el navegador en el método setup_class , luego realizar un montón de pruebas definidas como métodos de clase y finalmente cerrar el navegador en el método teardown_clas .

Pero lógicamente parece una mala solución, porque de hecho mis pruebas no funcionarán con la clase, sino con el objeto. Paso self param dentro de cada método de prueba, para poder acceder a los vars de los objetos:

class TestClass: def setup_class(cls): pass def test_buttons(self, data): # self.$attribute can be used, but not cls.$attribute? pass def test_buttons2(self, data): # self.$attribute can be used, but not cls.$attribute? pass def teardown_class(cls): pass

E incluso parece no ser correcto crear una instancia de navegador para la clase. Debería crearse para cada objeto por separado, ¿verdad?

Entonces, ¿necesito usar los métodos __init__ y __del__ lugar de setup_class y teardown_class ?


Como sugirió @Bruno, el uso de accesorios pytest es otra solución accesible para ambas clases de prueba o incluso para funciones de prueba simples. Aquí hay un ejemplo que prueba las funciones de python2.7 :

import pytest @pytest.fixture(scope=''function'') def some_resource(request): stuff_i_setup = ["I setup"] def some_teardown(): stuff_i_setup[0] += " ... but now I''m torn down..." print stuff_i_setup[0] request.addfinalizer(some_teardown) return stuff_i_setup[0] def test_1_that_needs_resource(some_resource): print some_resource + "... and now I''m testing things..."

Entonces, ejecutar test_1... produce:

I setup... and now I''m testing things... I setup ... but now I''m torn down...

Tenga en cuenta que stuff_i_setup está referenciado en el dispositivo, lo que permite que ese objeto se setup y torn down para la prueba con la que interactúa. Puede imaginar que esto podría ser útil para un objeto persistente, como una base de datos hipotética o alguna conexión, que debe borrarse antes de que se ejecute cada prueba para mantenerlos aislados.


Cuando escribe "pruebas definidas como métodos de clase" , ¿realmente se refiere a métodos de clase (métodos que reciben su clase como primer parámetro) o simplemente métodos regulares (métodos que reciben una instancia como primer parámetro)?

Como su ejemplo usa self para los métodos de prueba, supongo que este último, por lo que solo necesita usar setup_method en setup_method lugar:

class Test: def setup_method(self, test_method): # configure self.attribute def teardown_method(self, test_method): # tear down self.attribute def test_buttons(self): # use self.attribute for test

La instancia del método de prueba se pasa a setup_method y teardown_method , pero se puede ignorar si su código de configuración / desmontaje no necesita conocer el contexto de prueba. Más información se puede encontrar here .

También le recomiendo que se familiarice con los accesorios de py.test, ya que son un concepto más poderoso.


Esto podría ayudar http://docs.pytest.org/en/latest/xunit_setup.html

En mi conjunto de pruebas, agrupo mis casos de prueba en clases. Para la configuración y desmontaje que necesito para todos los casos de prueba en esa clase, utilizo los setup_class(cls) clase setup_class(cls) y teardown_class(cls) .

Y para la configuración y el desmontaje que necesito para cada caso de prueba, uso el setup_method(method) y el setup_method(method) teardown_method(methods)

Ejemplo:

lh = <got log handler from logger module> class TestClass: @classmethod def setup_class(cls): lh.info("starting class: {} execution".format(cls.__name__)) @classmethod def teardown_class(cls): lh.info("starting class: {} execution".format(cls.__name__)) def setup_method(self, method): lh.info("starting execution of tc: {}".format(method.__name__)) def teardown_method(self, method): lh.info("starting execution of tc: {}".format(method.__name__)) def test_tc1(self): <tc_content> assert def test_tc2(self): <tc_content> assert

Ahora, cuando ejecuto mis pruebas, cuando comienza la ejecución de TestClass, registra los detalles de cuándo comienza la ejecución, cuándo finaliza la ejecución y lo mismo para los métodos.

Puede agregar otros pasos de configuración y desmontaje que pueda tener en las ubicaciones respectivas.

¡Espero eso ayude!


Según la finalización de Fixture / ejecución del código de desmontaje, el uso de addfinalizer es "histórico".

Como nota histórica, otra forma de escribir código de desmontaje es aceptando un objeto de solicitud en su función de dispositivo y puede llamar a su request.addfinalizer una o varias veces:

La mejor práctica actual para la configuración y desmontaje es usar el yield

import pytest @pytest.fixture() def resource(): print("setup") yield "resource" print("teardown") class TestResource(object): def test_that_depends_on_resource(self, resource): print("testing {}".format(resource))

Ejecutarlo da como resultado

$ py.test --capture=no pytest_yield.py === test session starts === platform darwin -- Python 2.7.10, pytest-3.0.2, py-1.4.31, pluggy-0.3.1 collected 1 items pytest_yield.py setup testing resource .teardown === 1 passed in 0.01 seconds ===