29. Шаблоны xUnit
В этой главе рассматриваются шаблоны, пред назначенные д ля
использования при работе с xUnit.
Проверка утверждений
Как убед иться в том, что тест работает правильно? Напишите
логическое выражение, которое автоматически под тверд ит ваше мнение
о том, что код работает.
Если мы хотим сд елать тесты полно стью автоматическими, значит,
абсолютно все пред положения о работе тестируемого код а необход имо
превратить в тесты, при этом результат выполнения этих тестов д олжен
говорить нам, работает код корректно или нет. Проще говоря, мы
д олжны облад ать возможно стью щелкнуть на кнопке и через короткое
время узнать, работает код корректно или нет. Отсюд а след ует, что
• в результате выполнения теста д олжно получиться логическое
значение: «истина» (True) указывает, что все в поряд ке, а «ложь» – что
произошло нечто непред вид енное;
• проверка результата кажд ого теста выполняется компьютером
автоматически при помощи какой-либо разновид но сти оператора
assert().
Мне
приход ило сь
вид еть
выражения
напод обие
assertTrue(rectangle.area()!= 0). Чтобы тест выполнился успешно, метод
area() д олжен вернуть любое ненулевое значение – это не очень
полезный тест. Делайте тесты более конкретными. Если площад ь
прямоугольника
д олжна
быть
равна
50,
так
и
пишите:
assertTrue(rectangle.area() == 50). Во многих реализациях xUnit
присутствует специальное выражение assert() д ля тестирования
равенства (эквивалентно сти). Отличительная его черта со стоит в том,
что вместо од ного логического параметра выражение assertEquals()
принимает д ва произвольных объекта и пытается опред елить, являются
ли они эквивалентными. Преимущество со стоит в том, что в случае
неуд ачи выражение assertEquals() сгенерирует более информативное
сообщение с указанием д вух несовпад ающих значений. Ожид аемое
значение, как правило, указывается первым. Например, пред ыд ущее
выражение в сред е JUnit можно переписать след ующим образом:
assertEquals(50, rectangle.area()).
Думать об объектах, как о черных ящиках, д о статочно тяжело.
Пред ставим, что у нас есть объект Contract, со стояние которого
хранится в поле status и может быть экземпляром класса Offered или
Running. В этом случае можно написать тест исход я из пред полагаемой
реализации:
Contract contract = new Contract(); // по умолчанию со стояние Offered
contract.begin(); // со стояние меняется на Running
assertEquals(Running.class, contract.status.class);
Этот тест слишком сильно зависит от текущей реализации объекта
status. Од нако тест д олжен завершаться успешно, д аже если поле status
станет логическим значением. Может быть, когд а status меняется на
Running, можно узнать д ату начала работы над контрактом:
assertEquals(…, contract.startDate()); // генерирует исключение, если
// status является экземпляром Offered
Я признаю, что пытаюсь плыть против течения, когд а настаиваю на
том, что все тесты д олжны быть написаны только с использованием
общед о ступного (public) протокола. Существует специальный пакет
JXUnit, который является расширением JUnit и позволяет тестировать
значения переменных, д аже тех, которые объявлены как закрытые.
Желание протестировать объект в рамках концепции белого ящика –
это не проблема тестирования, это проблема проектирования. Кажд ый
раз, когд а у меня возникает желание протестировать значение
переменной-члена, чтобы убед иться в работо спо собно сти код а, я
получаю возможно сть улучшить д изайн системы. Если я забываю о
своих опасениях и про сто проверяю значение переменной, я теряю
такую возможно сть. Иначе говоря, если ид ея об улучшении д изайна не
приход ит мне в голову, ничего не под елаешь. Я проверяю значение
переменной, смахиваю непрошеную слезу, вношу соответствующую
отметку в список зад ач и прод олжаю д вигаться вперед , над еясь, что
наступит д ень, когд а смогу найти под ход ящее решение.
Самая первая версия xUnit д ля Smalltalk (под названием SUnit)
облад ала очень про стыми выражениями assert. Если од но из выражений
терпело неуд ачу, автоматически открывало сь окно отлад чика, вы
исправляли код и прод олжали работу. Сред а разработки Java не
настолько совершенна, к тому же по строение приложений на Java часто
выполняется в пакетном режиме, поэтому имеет смысл д обавлять в
выражение assert() д ополнительную информацию о проверяемом
условии. Чтобы в случае неуд ачи выражения assert() можно было
вывести на экран д ополнительную информацию.
В JUnit это реализуется при помощи необязательного первого
параметра
[19]
. Например, если вы напишете assertTrue(«Должно быть
True», false) и тест не сработает, то вы увид ите на экране
приблизительно след ующее сообщение: Assertion failed: Должно быть
True. Обычно под обного сообщения д о статочно, чтобы направить вас
напрямую к источнику ошибки в код е. В некоторых группах
разработчиков д ействует жесткое правило, что все выражения assert()
д олжны снабжаться под обными информационными сообщениями.
Попробуйте оба варианта и само стоятельно опред елите, окупаются ли
д ля вас затраты, связанные с информационными сообщениями.
Do'stlaringiz bilan baham: |