Ejecutar setUp solo una vez para un conjunto de pruebas automatizadas

Mi versión de Python es 2.6.

Me gustaría ejecutar el método de configuración de prueba solo una vez, ya que hago las tareas necesarias para todas las pruebas.

Mi idea fue crear una variable booleana que se configurará como “verdadera” después de la primera ejecución y luego deshabilitar más de una llamada al método de configuración.

class mySelTest(unittest.TestCase):   setup_done = False   def setUp(self):     print str(self.setup_done)            if self.setup_done:       return     self.setup_done = True     print str(self.setup_done) 

La salida:

 False True --- Test 1 --- False True --- Test 2 --- 

¿Por qué esto no funciona? ¿Yo me perdí algo?

Puede usar setUpClass para definir métodos que solo se ejecutan una vez por testsuite.

La respuesta de Daniel es correcta, pero aquí hay un ejemplo para evitar algunos errores comunes que encontré, como no llamar a super() en setUpClass() cuando TestCase es una subclase de unittest.TestCase (como en django.test o falcon.testing ).

La documentación para setUpClass() no menciona que debe llamar a super() en tales casos. Recibirá un error si no lo hace, como se ve en esta pregunta relacionada .

 class SomeTest(TestCase): def setUp(self): self.user1 = UserProfile.objects.create_user(resource=SomeTest.the_resource) @classmethod def setUpClass(cls): """ get_some_resource() is slow, to avoid calling it for each test use setUpClass() and store the result as class variable """ super(SomeTest, cls).setUpClass() cls.the_resource = get_some_resource() 

No intente deshacer las llamadas para configurar, solo llámelo una vez.

Por ejemplo:

 class MyClass(object): ... def _set_up(): code to do one-time setup _set_up() 

Esto llamará a _set_up () cuando se cargue el módulo por primera vez. Lo he definido como una función de nivel de módulo, pero también podría convertirlo en un método de clase de MyClass.

Si terminó aquí debido a la necesidad de cargar algunos datos para las pruebas … entonces, en cuanto esté usando Django 1.9+, vaya a setUpTestData :

 class MyTests(TestCase): @classmethod def setUpTestData(cls): # Set up data for the whole TestCase cls.foo = Foo.objects.create(bar="Test") def test1(self): self.assertEqual(self.foo.bar, 'Test') 

Coloque todo el código que desee configurar una vez fuera del mySelTest.

 setup_done = False class mySelTest(unittest.TestCase): def setUp(self): print str(setup_done) if setup_done: return setup_done = True print str(setup_done) 

Otra posibilidad es tener una clase Singleton que setUp() en setUp() , que solo ejecutará el código __new__ una vez y devolverá la instancia del objeto para el rest de las llamadas. Ver: ¿Existe una forma simple y elegante de definir singletons?

 class Singleton(object): _instance = None def __new__(cls, *args, **kwargs): if not cls._instance: cls._instance = super(Singleton, cls).__new__( cls, *args, **kwargs) # PUT YOUR SETUP ONCE CODE HERE! cls.setUpBool = True return cls._instance class mySelTest(unittest.TestCase): def setUp(self): # The first call initializes singleton, ever additional call returns the instantiated reference. print(Singleton().setUpBool) 

Sin embargo, tu forma de trabajar también funciona.

setup_done es una variable de clase, no una variable de instancia.

Lo estás haciendo referencia como una variable de instancia:

self.setup_done

Pero necesitas referenciarlo como una variable de clase:

mySelTest.setup_done

Aquí está el código corregido:

 class mySelTest(unittest.TestCase): setup_done = False def setUp(self): print str(mySelTest.setup_done) if mySelTest.setup_done: return mySelTest.setup_done = True print str(mySelTest.setup_done)