python - Ejecutar código antes y después de cada prueba en py.test?
(6)
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 desmontaje 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 comprobaré los archivos y en el desmontaje también verifico los archivos. Si hay archivos adicionales quiero que la prueba falle.
Echa un vistazo a los decoradores de Python https://wiki.python.org/moin/PythonDecorators
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.yield_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 / desmontaje 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 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/
Los accesorios son exactamente lo que quieres. Para eso están diseñados.
Si utiliza dispositivos de estilo pytest , o configuración y desmontaje (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 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 <function test1 at 0x10078cc20>
Testing hello world
postcheck <function test1 at 0x10078cc20>
precheck <function test2 at 0x10078ccb0>
Testing hello world 2
postcheck <function test2 at 0x10078ccb0>
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 <bound method type.my_test of <class ''__main__.TestClass''>>
Testing from class method
postcheck <bound method type.my_test of <class ''__main__.TestClass''>>
Puede usar los Ajustes de nivel de Módulo / desmontaje 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 ''''''