Общий код выделен в виде отдельного метода. Среда xUnit гарантирует, что метод setUp() объекта TestCase будет обязательно вызван перед обращением к любому тестовому методу этого объекта. Теперь тестовые методы выглядят проще, однако, прежде чем понять их смысл, мы должны вспомнить о существовании метода setUp() и уточнить, что происходит внутри этого метода.
Какой из этих двух стилей предпочтительней? Попробуйте использовать каждый из них. Я фактически всегда выделяю общий код фикстуры и перемещаю его в метод setUp(), однако у меня хорошая память. Те, кто читает мои тесты, часто жалуются, что им приходится вспоминать слишком о многом. Значит, возможно, мне следует выделять меньшей объем кода, чтобы сделать тесты более понятными.
Взаимоотношения между подклассами класса TestCase и экземплярами этих подклассов являются наиболее запутанной стороной инфраструктуры xUnit. Каждый новый тип фикстуры требует создания нового подкласса класса TestCase. Каждая новая фикстура создается внутри экземпляра подкласса, используется один раз, а затем уничтожается.
В предыдущем примере, если мы хотим написать тесты для непустого прямоугольника (Rectangle), нам придется создать новый класс, который можно назвать, например, NormalRectangleTest. У этого класса будет свой собственный метод setUp(), в котором будет создан новый экземпляр Rectangle, необходимый ему для тестирования. Этот экземпляр Rectangle будет соответствовать непустому прямоугольнику. В общем случае, если я хочу использовать несколько отличающуюся фикстуру, я создаю новый подкласс класса TestCase.
Это означает, что не существует прямого простого соответствия между классами тестов и функциональными (тестируемыми) классами. Иногда одна фикстура используется для тестирования нескольких классов (подобное случается нечасто). Иногда для тестирования единственного функционального класса требуется создать две или три фикстуры. На практике в большинстве случаев получается, что количество классов тестов приблизительно совпадает с количеством функциональных классов. Однако это происходит вовсе не потому, что для каждого функционального класса вы создаете один-единственный класс теста.
Как осуществляется освобождение внешних ресурсов в фикстуре? Переопределите метод tearDown() и освободите в нем ресурсы, выделенные в ходе создания фикстуры.
Помните, что каждый тест должен оставить рабочую среду в том же состоянии, в котором она была до того, как тест начал работу. Например, если внутри теста вы открываете файл, вы должны позаботиться о том, чтобы закрыть его перед тем, как тест завершит работу. Вы можете написать:
testMethod(self):
file = File("foobar"). open()
try:
…âûïîëíèòü òåñò…
finally:
file.close()
Если файл используется в нескольких тестах, вы можете сделать его частью общей фикстуры:
setUp(self):
self.file = File("foobar"). open()
testMethod(self):
try:
…выполнить тест…
finally:
self.file.close()
Во-первых, возникает неприятное дублирование выражений finally – это означает, что мы упустили что-то в дизайне. Во-вторых, при написании подобного метода можно легко допустить ошибку, например забыть добавить ключевое слово finally или вообще забыть о необходимости закрытия файла. Наконец, в этом тесте существует три сбивающих с толку строки – try, finally и сама команда close, – эти выражения не относятся непосредственно к процедуре тестирования.
Инфраструктура xUnit гарантирует вызов метода под названием tearDown() после выполнения тестового метода. Метод tearDown() будет вызван вне зависимости от того, что случится внутри тестового метода (однако следует иметь в виду, что, если сбой произойдет в ходе выполнения метода setUp(), метод tearDown() вызываться не будет). Мы можем преобразовать предыдущий тест следующим образом:
setUp(self):
self.file = File("foobar"). open()
testMethod(self):
…выполнить тест…
tearDown(self):
self.file.close()
Что такое единичный тест? Это метод, имя которого начинается с префикса test.
В процессе разработки вам придется иметь дело с сотнями, а может быть, и тысячами тестов, как можно уследить за всеми этими тестами?
Языки объектно-ориентированного программирования обеспечивают трехуровневую организацию исходного кода:
• модуль (в языке Java –
• класс;
• метод.
Если мы пишем тесты как обычный исходный код, мы должны найти способ организации тестов с использованием элементов этой структуры. Если мы используем классы для представления фикстур, значит, методы этих классов являются естественным местом размещения тестирующего кода. Все тесты, использующие некоторую фикстуру, должны быть методами одного класса. Тесты, работающие с другой фикстурой, должны располагаться в другом классе.
Вильям Л Саймон , Вильям Саймон , Наталья Владимировна Макеева , Нора Робертс , Юрий Викторович Щербатых
Зарубежная компьютерная, околокомпьютерная литература / ОС и Сети, интернет / Короткие любовные романы / Психология / Прочая справочная литература / Образование и наука / Книги по IT / Словари и Энциклопедии