python - simbolicas - Derivar una clase de TestCase arroja dos errores
introduccion al calculo con python (2)
Tengo algunos códigos básicos de configuración / desmontaje que quiero reutilizar en un montón de pruebas unitarias. Así que tuve la brillante idea de crear algunas clases derivadas para evitar repetir el código en cada clase de prueba.
Al hacerlo, recibí dos errores extraños. Uno, no puedo resolver. Aquí está el que no tiene solución:
AttributeError: ''TestDesktopRootController'' object has no attribute ''_testMethodName''
Aquí está mi clase base:
import unittest
import twill
import cherrypy
from cherrypy._cpwsgi import CPWSGIApp
class BaseControllerTest(unittest.TestCase):
def __init__(self):
self.controller = None
def setUp(self):
app = cherrypy.Application(self.controller)
wsgi = CPWSGIApp(app)
twill.add_wsgi_intercept(''localhost'', 8080, lambda : wsgi)
def tearDown(self):
twill.remove_wsgi_intercept(''localhost'', 8080)
Y aquí está mi clase derivada:
import twill
from base_controller_test import BaseControllerTest
class TestMyController(BaseControllerTest):
def __init__(self, args):
self.controller = MyController()
BaseControllerTest.__init__(self)
def test_root(self):
script = "find ''Contacts''"
twill.execute_string(script, initial_url=''http://localhost:8080/'')
El otro error extraño es:
TypeError: __init__() takes exactly 1 argument (2 given)
La "solución" a eso fue agregar la palabra "args" a mi función __init__
en la clase derivada. ¿Hay alguna manera de evitar eso?
Recuerda, tengo dos errores en este.
En el BaseController
de __init__
, debe llamar a __init__
de unittest.TestCase
tal como lo hizo en TestMyController
.
La llamada a construir un TestCase desde el marco puede estar pasando un argumento. La mejor manera de manejar esto para derivar clases es:
class my_subclass(parentclass):
def __init__(self, *args, **kw):
parentclass.__init__(self, *args, **kw)
...
Es porque estás anulando __init__()
incorrectamente. Es casi seguro que no desea anular __init__()
en absoluto; deberías hacer todo en setUp()
. He estado usando unittest
por más de 10 años y creo que nunca he anulado __init__()
.
Sin embargo, si realmente necesita reemplazar __init__()
, recuerde que no controla dónde se llama a su constructor, el marco lo llama por usted. Así que tienes que proporcionar una firma a la que pueda llamar. Desde el código fuente ( unittest/case.py
), esa firma es:
def __init__(self, methodName=''runTest''):
La forma segura de hacerlo es aceptar cualquier argumento y simplemente pasarlos a la clase base. Aquí está una implementación de trabajo:
class BaseTest(unittest.TestCase):
def __init__(self, *args, **kwargs):
unittest.TestCase.__init__(self, *args, **kwargs)
def setUp(self):
print "Base.setUp()"
def tearDown(self):
print "Base.tearDown()"
class TestSomething(BaseTest):
def __init__(self, *args, **kwargs):
BaseTest.__init__(self, *args, **kwargs)
self.controller = object()
def test_silly(self):
self.assertTrue(1+1 == 2)