Для модульных тестов (с использованием модуля unittest
), в которых используется тестовый стенд App Engine , мне нужны setUp
и tearDown
методы для активации и деактивации тестового стенда соответственно (слегка упрощенно)
class SomeTest(unittest.TestCase):
def setUp(self):
self.testbed = testbed.Testbed()
self.testbed.activate()
def tearDown(self):
self.testbed.deactivate()
def testSomething(self):
...
Это быстро становится бременем для написания.Я мог бы написать базовый класс TestCaseWithTestbed
, но тогда мне нужно было бы не забывать вызывать метод суперкласса каждый раз, когда мне нужен пользовательский setUp
в одном из тестовых случаев.
Я думал, что это будетболее элегантно решить это с помощью декоратора класса.Поэтому я хотел бы написать:
@WithTestbed
class SomeTest(unittest.TestCase):
def testSomething(self):
...
С этим декоратором испытательный стенд должен быть волшебным образом активирован.Итак ... как реализовать декоратор WithTestbed
?В настоящее время у меня есть следующее:
def WithTestbed(cls):
class ClsWithTestbed(cls):
def setUp(self):
self.testbed = testbed.Testbed()
self.testbed.activate()
cls.setUp(self)
def tearDown(self):
cls.tearDown(self)
self.testbed.deactivate()
return ClsWithTestbed
Это работает для простых случаев, но имеет некоторые серьезные проблемы:
- Имя класса теста становится
ClsWithTestbed
, и это отображаетсяв тестовом выводе. - Конкретные тестовые классы, вызывающие
super(SomeTestClass, self).setUp()
, заканчиваются бесконечной рекурсией, потому что SomeTestClass
теперь равно WithTestbed
.
Янемного смутно из-за манипуляций с Python во время выполнения.Итак, как это сделать правильно?