в котором будет отмечаться последовательность выполнения методов. Каждый метод будет добавлять в конец журнала соответствующую запись. Таким образом, просмотрев журнал, мы сможем установить порядок выполнения методов.

Вызов тестового метода

Вызов метода setUp перед обращением к методу

Вызов метода tearDown после обращения к методу

Метод tearDown должен вызываться даже в случае неудачи теста

Выполнение нескольких тестов

Отчет о результатах

Строка журнала в классе WasRun

WasRun

def setUp(self):

self.wasRun = None

self.wasSetUp = 1

self.log = "setUp "

Теперь можно изменить метод testSetUp(), чтобы вместо флага он проверял содержимое журнала:

TestCaseTest

def testSetUp(self):

self.test.run()

assert("setUp " == self.test.log)

После этого мы можем удалить флаг wasSetUp. Мы также можем добавить в журнал запись о выполнении метода:

WasRun

def testMethod(self):

self.wasRun = 1

self.log = self.log + "testMethod "

В результате нарушается работа теста testSetUp(), так как в момент выполнения этого метода журнал содержит строку «setUp testMethod». Изменяем ожидаемое значение:

TestCaseTest

def testSetUp(self):

self.test.run()

assert("setUp testMethod " == self.test.log)

Теперь этот тест выполняет работу обоих тестов, поэтому можно удалить testRunning и переименовать testSetUp:

TestCaseTest

def setUp(self):

self.test = WasRun("testMethod")

def testTemplateMethod(self):

self.test.run()

assert("setUp testMethod " == self.test.log)

Мы используем экземпляр класса WasRun всего в одном месте, поэтому необходимо отменить добавленный ранее хитрый трюк, связанный с setUp():

TestCaseTest

def testTemplateMethod(self):

test = WasRun("testMethod")

test.run()

assert("setUp testMethod " == test.log)

Нет ничего страшного в том, что мы сделали рефакторинг, исходя из нескольких ранних соображений, а чуть позже отменили его, – подобная ситуация складывается достаточно часто. Некоторые предпочитают подождать, пока у них накопится достаточное количество оснований для рефакторинга, иными словами, они оттягивают выполнение рефакторинга, чтобы быть полностью уверенными в его необходимости. Они поступают так потому, что не любят аннулировать результаты проделанной работы. Однако я предпочитаю не отвлекаться на рассуждения о том, не придется ли в будущем отменять то или иное исправление, необходимое мне в настоящем. Вместо этого я предпочитаю сосредоточиться на дизайне. По этой причине я рефлекторно делаю рефакторинг тогда, когда считаю нужным, ни капли не опасаясь, что сразу после этого мне, возможно, придется отменить его.

Вызов тестового метода

Вызов метода setUp перед обращением к методу

Вызов метода tearDown после обращения к методу

Метод tearDown должен вызываться даже в случае неудачи теста

Выполнение нескольких тестов

Отчет о результатах

Строка журнала в классе WasRun

Теперь мы готовы к реализации метода tearDown(). Ага! Опять я вас поймал! Теперь мы готовы к тестированию метода tearDown():

TestCaseTest

def testTemplateMethod(self):

test = WasRun("testMethod")

test.run()

assert("setUp testMethod tearDown " == test.log)

Он потерпел неудачу. Чтобы заставить его работать, выполняем несложные добавления:

TestCase

def run(self, result):

result.testStarted()

self.setUp()

exec "self." + self.name + "()"

self.tearDown()

WasRun

def setUp(self):

self.log = "setUp "

def testMethod(self):

self.log = self.log + "testMethod "

def tearDown(self):

self.log = self.log + "tearDown "

Неожиданно мы получаем ошибку не в классе WasRun, а в классе TestCaseTest. У нас нет «пустой» реализации метода teardown() в классе TestCase:

TestCase

def tearDown(self):

pass

Мы начинаем получать пользу от разрабатываемой инфраструктуры. Замечательно! Никакого рефакторинга не требуется. Очевидная реализация, созданная нами после обнаружения ошибки, сработала, и код получился чистым.

Вызов тестового метода

Вызов метода setUp перед обращением к методу

Вызов метода tearDown после обращения к методу

Метод tearDown должен вызываться даже в случае неудачи теста

Выполнение нескольких тестов

Отчет о результатах

Строка журнала в классе WasRun

Далее мы перейдем к формированию отчета о результатах выполнения тестов. Вместо использования встроенного в Python механизма обработки ошибок мы планируем реализовать и использовать собственный механизм наблюдения за работой тестов.

В данной главе мы

• перешли от использования флагов к использованию журнала;

• создали тесты для метода tearDown() и реализовали этот метод с использованием нового механизма журналирования;

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

21. Учет и контроль

Вызов тестового метода

Вызов метода setUp перед обращением к методу

Вызов метода tearDown после обращения к методу

Метод tearDown должен вызываться даже в случае неудачи теста

Выполнение нескольких тестов

Отчет о результатах

Строка журнала в классе WasRun

Метод tearDown() должен выполняться, даже когда в процессе выполнения теста возникло исключение. Однако чтобы добиться этого, мы должны перехватывать исключения. (Честно говоря, я уже пытался реализовать это, но у меня не получилось, и я вернул все на свои места.) Если при реализации перехвата исключений мы допустим ошибку, мы можем не заметить этого, так как стандартный механизм доклада об исключениях не будет функционировать.

Работая в стиле TDD, важно понимать, что особое значение имеет порядок, в котором вы реализуете тесты. Выбирая тест, над которым я буду работать дальше, я стараюсь выбрать тот, который, во-первых, послужит для меня источником новых знаний, а во-вторых, достаточно прост, чтобы я был уверен в том, что могу заставить его работать. Если я добиваюсь успешного выполнения этого теста, но захожу в тупик при реализации следующего, я вполне могу выполнить откат назад на два шага. Было бы неплохо, если бы среда разработки оказывала мне в этом помощь. Например, было бы неплохо, если бы в момент срабатывания всех тестов автоматически создавалась резервная копия всего исходного кода,

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату