Вызов тестового метода
Вызов метод а setUp перед обращением к метод у
Вызов метод а tearDown по сле обращения к метод у
Метод tearDown д олжен вызываться д аже в случае неуд ачи теста
Выполнение нескольких тестов
Отчет о результатах
Конечно же, мы по-прежнему работаем в стиле «сначала тесты».
Для нашего прототеста нам потребуется небольшая программа, которая
д олжна отображать на экране значение «истина», если произошло
обращение к тестовому метод у, и значение «ложь» в противном случае.
Теперь пред ставим, что у нас есть тест, который устанавливает флаг
внутри тестового метод а, в этом случае мы могли бы по сле выполнения
теста отобразить со стояние флага на экране и само стоятельно
убед иться в том, что флаг установлен правильно. Выполнив проверку
вручную, мы сможем попробовать автоматизировать процесс.
Итак, у нас наметилась след ующая стратегия. Мы созд аем объект,
который соответствует нашему тесту. В объекте сод ержится флаг. Перед
выполнением тестового метод а флаг д олжен быть установлен в
со стояние «ложь». Тестовый метод устанавливает флаг в со стояние
«истина». По сле выполнения тестового метод а мы д олжны проверить
со стояние флага. Назовем наш тестовый класс именем WasRun
[10]
, так
как объект этого класса буд ет сигнализировать нам о том, был ли
выполнен тестовый метод . Флаг внутри этого класса также буд ет
называться wasRun (это несколько сбивает с толку, од нако wasRun –
такое под ход ящее имя). Собственно объект (экземпляр класса WasRun)
буд ет называться про сто test. То есть мы сможем написать инструкцию
assert test.wasRun (assert – встроенная инструкция языка Python).
Язык программирования Python является интерпретируемым –
команд ы исполняются по мере чтения их из файла с исход ным код ом.
Поэтому, чтобы выполнить тестирование, мы можем написать
след ующий короткий файл и попробовать запустить его:
test = WasRun(«testMethod»)
print(test.wasRun)
test.testMethod()
print(test.wasRun)
Мы ожид аем, что эта миниатюрная программа напечатает None д о
выполнения тестового метод а и 1 – по сле. (В языке Python значение None
является аналогом null или nil и наряд у с числом 0 соответствует
значению «ложь».) Од нако программа не д елает того, что мы от нее
жд ем. И немуд рено – мы еще не опред елили класс WasRun (сначала
тесты!).
WasRun
class WasRun:
pass
(Ключевое слово pass используется в случае, если реализация класса
или метод а отсутствует.) Теперь интерпретатор сообщает нам, что в
классе WasRun нет атрибута с именем wasRun. Созд ание атрибута
происход ит в момент созд ания объекта (экземпляра класса), то есть в
процессе выполнения конструктора (д ля уд обства конструктор любого
класса называется __init__). Внутри конструктора мы присваиваем флагу
wasRun значение None (ложь):
WasRun
class WasRun:
def __init__(self, name):
self.wasRun = None
Теперь программа д ействительно отображает на экране значение
None, од нако по сле этого интерпретатор сообщает нам, что мы д олжны
опред елить в классе WasRun метод testMethod. (Было бы неплохо, если
бы сред а разработки автоматически реагировала на это: само стоятельно
созд авала бы функцию-заглушку и открывала ред актор с курсором,
установленным в теле этой функции. Не правд а ли, это было бы про сто
зд орово? Кстати, некоторые производ ители IDE уже д од умались д о
этого.)
WasRun
def testMethod(self):
pass
Запускаем файл и вид им на экране д ва значения: None и None
[11]
. Нам
хотело сь бы вид еть None и 1. Чтобы получить желаемый результат, в
теле метод а testMethod присвоим флагу wasRun желаемое значение:
WasRun
def testMethod(self):
self.wasRun = 1
Запускаем программу – то, что нужно! Мы получили желаемый
результат. Зеленая поло са – ур-р-ра! Нам пред стоит сложный
рефакторинг, од нако если мы вид им перед собой зеленую поло су, значит,
мы д обились прогресса.
Теперь, вместо того чтобы напрямую обращаться к нашему
тестовому метод у, мы д олжны использовать наш реальный интерфейс –
метод run(). Изменим тест след ующим образом:
test= WasRun(«testMethod»)
print(test.wasRun)
test.run()
print(test.wasRun)
Чтобы заставить тест работать, д о статочно во спользоваться
след ующей несложной реализацией:
WasRun
def run(self):
self.testMethod()
Наша тестовая программа снова печатает на экране то, что нам
нужно. Зачастую во время рефакторинга возникает ощущение, что
необход имо разд елить код , с которым вы работаете, на д ве части, чтобы
работать с ними по отд ельно сти. Если в конце работы они снова
сольются воед ино, – замечательно. Если нет, значит, вы можете о ставить
их отд ельно д руг от д руга. В д анном случае со временем мы планируем
созд ать класс TestCase, од нако вначале мы д олжны обо собить части
нашего примера.
След ующий этап – д инамический вызов метод а testMethod. Од ной
из приятных отличительных характеристик языка Python является
возможно сть использования имен классов и метод ов в качестве функций
(см.
созд ание
экземпляра
класса
WasRun).
Получив
атрибут,
соответствующий имени теста, мы можем обратиться к нему, как к
функции. В результате буд ет выполнено обращение к метод у с
соответствующим именем
[12]
.
WasRun
class WasRun:
def __init__(self, name):
self.wasRun = None
self.name = name
def run(self):
method = getattr(self, self.name)
method()
Это еще од ин шаблон рефакторинга: разработать код , который
работает с некоторым конкретным экземпляром, и обобщить его, чтобы
он мог работать со всеми о стальными экземплярами, д ля этого
константы заменяются переменными. В д анном случае роль константы
играет не некоторое значение, а фиксированный код (имя конкретного
метод а). Од нако принцип о стается тем же. В рамках TDD эта проблема
решается очень легко: метод ика TDD снабжает вас конкретными
работающими примерами, исход я из которых можно выполнить
обобщение. Это значительно проще, чем выполнять обобщение исход я
только из собственных умозаключений.
Теперь наш маленький класс WasRun занят решением д вух разных
зад ач: во-первых, он след ит за тем, был ли выполнен метод ; во-вторых,
он д инамически вызывает метод . Пришло время разд елить полномочия
(разд елить нашу работу на д ве разные части). Прежд е всего, созд ад им
пустой суперкласс TestCase и сд елаем класс WasRun производ ным
классом:
Do'stlaringiz bilan baham: |