Ejecutar código antes y después de cada prueba en py.test?

Quiero ejecutar configuraciones adicionales y verificaciones antes y después de cada prueba en mi conjunto de pruebas. He mirado a los accesorios, pero no estoy seguro de si son el enfoque correcto. Necesito ejecutar el código de configuración antes de cada prueba y debo ejecutar las comprobaciones de desassembly después de cada prueba.

Mi caso de uso es verificar si el código no se limpia correctamente: deja archivos temporales. En mi configuración revisaré los archivos y en el desassembly también verifico los archivos. Si hay archivos adicionales quiero que la prueba falle.

Los accesorios de py.test son un método técnicamente adecuado para lograr tu propósito.

Solo necesitas definir un accesorio como ese:

@pytest.fixture(autouse=True) def run_around_tests(): # Code that will run before your test, for example: files_before = # ... do something to check the existing files # A test function will be run at this point yield # Code that will run after your test, for example: files_after = # ... do something to check the existing files assert files_before == files_after 

Al declarar su aparato con autouse=True , se invocará automáticamente para cada función de prueba definida en el mismo módulo.

Dicho esto, hay una advertencia. Afirmar en la configuración / desassembly es una práctica controvertida. Tengo la impresión de que a los principales autores de py.test no les gusta (a mí tampoco me gusta, por lo que puede influir en mi propia percepción), por lo que es posible que tengas algunos problemas o bordes ásperos a medida que avanzas.

Los accesorios son exactamente lo que quieres. Para eso están diseñados.

Si utiliza dispositivos de estilo pytest , o configuración y desassembly (módulo, clase o nivel de método), los dispositivos de estilo xUnit, dependen de las circunstancias y del gusto personal.

Por lo que estás describiendo, parece que podrías usar los accesorios de PyTest Autouse .
O el nivel de función del estilo xUnit setup_function () / teardown_function () .

Pytest te tiene completamente cubierto. Tanto es así que tal vez sea una manguera de fuego de información.

Puede usar los Ajustes de nivel de Módulo / desassembly de Aparatos de Pytest.

Aquí está el enlace

http://pytest.org/latest/xunit_setup.html

Funciona de la siguiente manera:

  def setup_module(module): """ setup any state specific to the execution of the given module.""" def teardown_module(module): """ teardown any state that was previously setup with a setup_module method.""" Test_Class(): def test_01(): #test 1 Code 

setup_module a setup_module antes de esta prueba y teardown_module después de que se complete la prueba.

Puede incluir este accesorio en cada script de prueba para ejecutarlo para cada prueba.

SI desea usar algo que es común a todas las pruebas en un directorio, puede usar el paquete o el nivel de los accesorios de nivel de directorio.

http://pythontesting.net/framework/nose/nose-fixture-reference/#package

En el archivo __init__.py del paquete puede incluir lo siguiente

  def setup_package(): '''Set up your environment for test package''' def teardown_package(): '''revert the state ''' 

Puede usar decoradores pero programáticamente, por lo que no necesita poner el decorador en cada método.

Estoy asumiendo varias cosas en el siguiente código:

Los métodos de prueba se denominan todos como: “testXXX ()” El decorador se agrega al mismo módulo donde se implementan los métodos de prueba.

 def test1(): print ("Testing hello world") def test2(): print ("Testing hello world 2") #This is the decorator class TestChecker(object): def __init__(self, testfn, *args, **kwargs): self.testfn = testfn def pretest(self): print ('precheck %s' % str(self.testfn)) def posttest(self): print ('postcheck %s' % str(self.testfn)) def __call__(self): self.pretest() self.testfn() self.posttest() for fn in dir() : if fn.startswith('test'): locals()[fn] = TestChecker(locals()[fn]) 

Ahora si llamas a los métodos de prueba …

 test1() test2() 

La salida debe ser algo como:

 precheck  Testing hello world postcheck  precheck  Testing hello world 2 postcheck  

Si tiene métodos de prueba como métodos de clase, el enfoque también es válido. Por ejemplo:

 class TestClass(object): @classmethod def my_test(cls): print ("Testing from class method") for fn in dir(TestClass) : if not fn.startswith('__'): setattr(TestClass, fn, TestChecker(getattr(TestClass, fn))) 

La llamada a TestClass.my_test() se imprimirá:

 precheck > Testing from class method postcheck > 

Echa un vistazo a los decoradores de Python https://wiki.python.org/moin/PythonDecorators

Los accesorios por defecto tienen scope=function . Entonces, si solo usas una definición como

 @pytest.fixture def fixture_func(self) 

El valor predeterminado es (scope = ‘function’).

Por lo tanto, cualquier finalización en la función de accesorio se llamará después de cada prueba.

Ref: 1. http://programeveryday.com/post/pytest-creating-and-using-fixtures-for-streamlined-testing/