Экстремальное программирование. Разработка через тестирование | страница 68



Отчет о неудачных тестах

Перехват и отчет об ошибках setUp

Создать объект TestSuite автоматически на основе класса TestCase


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

Однако вначале восстановим корректное выполнение четырех не неудачных тестов (эти тесты используют старый интерфейс функции run() без аргументов):


TestCaseTest

def testTemplateMethod(self):

test = WasRun("testMethod")

result = TestResult()

test.run(result)

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

def testResult(self):

test = WasRun("testMethod")

result = TestResult()

test.run(result)

assert("1 run, 0 failed" == result.summary())

def testFailedResult(self):

test = WasRun("testBrokenMethod")

result = TestResult()

test.run(result)

assert("1 run, 1 failed" == result.summary())

def testFailedResultFormatting(self):

result = TestResult()

result.testStarted()

result.testFailed()

assert("1 run, 1 failed" == result.summary())


Обратите внимание, что каждый из тестов создает экземпляр класса TestResult – эту операцию можно выполнить однократно внутри метода setUp(). Благодаря реализации этой идеи мы упростим тесты, однако сделаем их несколько более сложными в прочтении:


TestCaseTest

def setUp(self):

self.result = TestResult()

def testTemplateMethod(self):

test = WasRun("testMethod")

test.run(self.result)

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

def testResult(self):

test = WasRun("testMethod")

test.run(self.result)

assert("1 run, 0 failed" == self.result.summary())

def testFailedResult(self):

test = WasRun("testBrokenMethod")

test.run(self.result)

assert("1 run, 1 failed" == self.result.summary())

def testFailedResultFormatting(self):

self.result.testStarted()

self.result.testFailed()

assert("1 run, 1 failed" == self.result.summary())

def testSuite(self):

suite = TestSuite()

suite.add(WasRun("testMethod"))

suite.add(WasRun("testBrokenMethod"))

suite.run(self.result)

assert("2 run, 1 failed" == self.result.summary())

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

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

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

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

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

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

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

Отчет о неудачных тестах

Перехват и отчет об ошибках setUp

Создать объект TestSuite автоматически на основе класса TestCase


Все эти бесчисленные ссылки self выглядят ужасно, однако без этого в языке Python никак не обойтись. Если бы этот язык изначально был объектно-ориентированным, наверное, в этих ссылках не было бы надобности, а ссылки на глобальные переменные требовали бы квалификации. Однако язык Python изначально является интерпретируемым языком с добавленной в него поддержкой объектов (надо отметить, что поддержка объектов в этом языке реализована великолепно). В результате по умолчанию переменные считаются глобальными, а явные ссылки на self – необходимыми.