Tricky! : -)
Проблема в том, что вы не можете знать, какая функция будет вызываться следующей, а не
без непосредственного вмешательства в код юнит-теста.
Однако, если это возможно, чтобы изменить каждый тестовый пример на другой метод,
это вызвало бы «настройку», выполненную на заказ для этого теста, а затем выполни
контрольный пример, это будет решено.
Другими словами: нужно автоматизировать изменение каждого тестового примера в объявленном вами классе.
в другую функцию, которая: выполняет персонализированные настройки, и они выполняют
Оригинальный тест. Это должно быть сделано во время создания класса.
Это может показаться сложным, но это скорее работа, подходящая для "метаклассов" - поскольку мы просто делаем то, для чего они предназначены: настройка создания класса.
Итак, изменив метакласс для вашего TestCase на тот, который проверяет каждый элемент в классе -
если это тест (т.е. если его имя начинается с «test»), создается новая функция-обертка
который выполняет вышеуказанные функции, вы можете получить его.
(Требуется еще один шаг: поскольку имя метода и (объект для) исходного метода теста должны оставаться неизменными после создания, необходимо создать одну промежуточную функцию, чтобы сохранить замыкание для каждого теста. Иначе переменные method_name
и original_method
в приведенном ниже коде будут установлены для имени и содержимого последней функции в классе в конце цикла for
)
Вот, пожалуйста:
# -*- coding: utf-8 -*-
import unittest
import logging
#template method:
def log_setup(self, name):
#self.hdl = logging.FileHandler('testcase_%s.log' % name, mode='w')
#log.addHandler(self.hdl)
self.name = name
class MetaTestCase(type):
def __new__(cls, cls_name, bases, dict):
for name, item in dict.items():
if name.startswith("test"):
def scope_freezer(method_name, original_method):
def wrapper(self, *args, **kw):
log_setup(self, method_name)
return original_method(self, *args, **kw)
return wrapper
dict[name] = scope_freezer(name, item)
return type.__new__(cls, cls_name, bases, dict)
class TestExample(unittest.TestCase):
__metaclass__ = MetaTestCase
def test_a(self):
print self.name
def test_b(self):
print self.name
def tearDown(self):
pass
#log.removeHandler(self.hdl)
unittest.main()
(чтобы упростить тестирование на моей стороне, я прокомментировал фактические строки регистрации - «отпечатки» работают нормально - любой код в функции log_setup будет работать с self
и name
, правильно установленными.)
И, конечно, вы можете выделить этот меткласс в другом модуле и просто импортировать его для использования в ваших тестах.