Наконец-то! Разработка через тестирование для меня важнее, чем Scrum и XP вместе взятые. Можете отнять у меня дом, телевизор, собаку, но только попробуйте запретить использование TDD! Если вам не нравится TDD, тогда просто не подпускайте меня близко, иначе я всё равно привнесу его в проект втихую:)
Курс TDD за 10 секунд:
Несколько фактов о TDD:
• Разработка через тестирование — это
• TDD оказывает глубокое положительное влияние на дизайн системы.
• Чтобы TDD стало приносить пользу в новом проекте, необходимо приложить немало усилий. Особенно много тратится на интеграционные тесты методом «черного ящика». Но эти усилия окупаются
• Потрать достаточно времени, но сделай так, чтобы писать тесты
Мы используем следующие инструменты для разработки через тестирование:
• jUnit / httpUnit / jWebUnit. Мы присматриваемся к TestNG и Selenium.
• HSQLDB в качестве встроенной БД в памяти (in-memory) для тестовых целей.
• Jetty в качестве встроенного web-контейнера в памяти (in-memory) для тестовых целей.
• Cobertura для определения степени покрытия кода тестами.
• Spring framework для написания различных типов тестовых фикстур (в т. ч. с использованием моков (mock-object) и без, с внешней БД и БД в памяти (in-memory) и т. д.)
В наших наиболее сложных продуктах (с точки зрения TDD) у нас реализованы автоматизированные приёмочные тесты методом «черного ящика». Эти тесты загружают всю систему в память, включая базы данных и web-сервера, и взаимодействуют с системой только через внешние интерфейсы (например, через
HTTP).
Такой подход позволяет получить быстрые циклы «разработка-сборка-тест». Он так же выступает в качестве страховки, придавая разработчикам уверенность в успешности частого рефакторинга кода. В свою очередь, это обеспечивает простоту и элегантность дизайна даже в случае разрастания системы.
TDD и новый код
Мы используем TDD для всех новых проектов, даже если это означает, что фаза развёртывания рабочего окружения проекта потребует больше времени (потому что нужно больше усилий на настройку и поддержку тестовых утилит). Нетрудно понять, что выгода перевесит любой предлог
TDD и существующий код
Я уже говорил, что TDD — это непросто, но что
В своё время мы потратили много времени в попытках автоматизировать интеграционное тестирование одной из сложных систем, код которой мы унаследовали в ужасном состоянии и без единого теста.
При выходе каждого релиза мы выделяли команду тестировщиков, которые выполняли весь набор сложных регрессионных тестов и тестов производительности. Регрессионное тестирование выполнялось преимущественно вручную, что существенно замедляло процессы разработки и выпуска релизов. Тогда нашей целью стало автоматизировать все эти тесты. Однако, побившись пару месяцев головой об стену, мы поняли, что не приблизились к цели ни на йоту.
Тогда мы изменили подход. Мы признали тот факт, что автоматизировать регрессионное тестирование нам не по силам, и задали себе вопрос: «Как можно уменьшить время тестирования?». Это была игровая система, и мы выяснили, что большую часть времени тестирующая команда тратит на тривиальные задачи, такие как настройку тестового турнира или ожидание начала турнира. Поэтому мы создали утилиты для выполнения этих операций. Маленькие, доступные нажатием горячих клавиш скрипты, которые выполняли всю подготовительную работу, позволяя тестировщикам сосредоточиться непосредственно на тестировании.
А вот эти усилия уже окупились сполна! По уму мы должны были поступить так с самого начала. Но мы были настолько зациклены на автоматизации, что забыли про эволюционный подход, в котором первым шагом было бы создание окружения, позволяющего сделать
Усвоенный урок: Если от ручного регрессионного тестирования отказаться нельзя, но очень хочется его автоматизировать — лучше не надо (ну разве что это действительно очень просто). Вместо этого сделайте всё для облегчения процесса ручного тестирования.
Эволюционный дизайн
Это значит начать с простого дизайна и постоянно улучшать его, а не пытаться сделать всё идеально с первого раза и больше ничего и никогда не трогать.
С этим мы справляемся достаточно хорошо. Мы уделяем достаточно времени рефакторингу и улучшению существующего дизайна, и очень редко занимаемся детальным проектированием на годы вперёд. Иногда мы, конечно, можем напортачить, в результате чего плохой дизайн настолько врастает в систему, что рефакторинг превращается в действительно большую задачу. Но, в целом, мы полностью довольны этим подходом.
Если практиковать TDD, то, по большому счёту, постоянное улучшение дизайна получается само собой.
Непрерывная интеграция (Continuous integration)