Собственный лог-файл для каждого теста / Получить имя следующего теста - PullRequest
1 голос
/ 31 декабря 2010

Я хотел бы установить новый файл журнала для каждого теста. Примерно так:

import unittest
import logging

log = logging.getLogger()

class TestExample(unittest.TestCase):
    def setUp(self):
        next_testcase = ???
        self.hdl = logging.FileHandler(
                'testcase_%s.log' % next_testcase, mode='w')
        log.addHandler(self.hdl)

    def tearDown(self):
        log.removeHandler(self.hdl)

Как я могу узнать название теста?

Или как бы вы реализовали что-то подобное вышеописанному?

Ответы [ 2 ]

2 голосов
/ 31 декабря 2010

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, правильно установленными.)

И, конечно, вы можете выделить этот меткласс в другом модуле и просто импортировать его для использования в ваших тестах.

1 голос
/ 12 января 2011


import unittest
import logging

def log_setup(self, name):
    print name


class TestExample(unittest.TestCase):

    def test_method_name(self):
        print self.method_name

    def __getattribute__(self, name):
        safe_getattr =  super(TestExample, self).__getattribute__

        if name.startswith("test_"):
            self.method_name = name
            log_setup(self, name)

        return safe_getattr(name)



if __name__ == "__main__":
    unittest.main()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...