Я должен признать, что я был не очень хорошо с TDD (Test-Driven Development). Я просто не видел, как это может помочь мне поставить лучшее программное обеспечение. Продукты и решения, которые я разработал, были очень хорошими, и было приятно видеть, что они работают годами. Что еще мне нужно?
Но пришло время дать TDD еще одну попытку. Очевидно, что сегодня стало совершенно невозможно игнорировать эту тему, особенно когда люди уже говорят о непрерывном развертывании !
«Настоящим разработчикам не нужны юнит-тесты» ( видео ), они хорошо описывают, для чего нужен TDD. Если вы не видите значения в TDD, как я, пожалуйста, сделайте себе одолжение и посмотрите этот сеанс.
Некоторые основные выводы:
- Я предполагаю, что суть в том, что TDD не о том, чтобы сначала писать неудачные тесты, как я предполагал годами. Это способ спроектировать и внедрить систему не из головы или какой-то глупой спецификации проекта, а из реальных потребностей. Тесты — приятный побочный эффект, но на самом деле они показывают, как работает система. Я думаю , что это был «Groovy в действии» , который инициировал отличная традиция использования утверждает , как способ , чтобы продемонстрировать , что делает код. Что лучше описывает конечный результат?
assert "test" == str.test() // Or str.test() // prints "test"
Это может звучать как очевидная вещь, но мысленное переключение с «Тестов ради тестов» на «Проектирование и внедрение с помощью тестов» было моим первым просветлением, когда я смотрел видео.
- Есть три этапа создания TDD: красный, зеленый, рефакторинг. Во-первых, вы предоставляете демонстрацию новой функции. Это принимает форму провального теста, верно. Но, тем не менее, это демонстрация новой функции. Затем вы реализуете это. А потом вы убираете, рефакторите и убираете. Процесс очистки является критическим! Исходя из моего опыта, он широко и часто пропускается, когда люди переходят на «зеленую» фазу и принимают обязательства. Именно здесь продукты начинают плохо пахнуть, ясность теряется, вещи становятся грязными, и следующее, что вы слышите, — «никогда не трогай».
- Тестируйте поведение, а не реализацию. Другое распространенное мнение о модульных тестах — они должны тестировать методы класса и переходы состояний, т. Е. Текущую реализацию класса. Проблема с этим подходом состоит в том, что тесты ломаются каждый раз, когда изменяется реализация. И вместо соответствующего обновления тестов очень заманчиво комментировать их, <исключать> их запуск или просто @Ignore . Если кто-то тестирует функциональность и поведение, он не должен сломаться! Если есть необходимость тестировать приватных членов, то они, вероятно, делают слишком много и должны быть извлечены для своего собственного класса и своих собственных тестов. «Разработайте и внедрите с помощью тестов» снова.
- При выполнении обзора кода начинайте с тестов. Поскольку тесты являются ответом на вопрос «Что делает этот код?» имеет смысл сначала рассмотреть их, чтобы сконцентрироваться на значимых частях, а не на всем . Особенно, когда время ограничено и только соответствующий код должен быть просмотрен.
- Модульные тесты не являются заменой интеграционных тестов, приемочных испытаний и процессов обеспечения качества. Как было упомянуто выше, TDD на самом деле не служит цели тестирования, хотя называется так. Он не проверяет по-настоящему и не пытается найти ошибки, он только демонстрирует способность приложения что-то делать.
- Рассматривайте свои тесты как производственный код. Тесты не должны быть написаны как одноразовый код, который никогда не поддерживается и не обновляется. Тесты — это пользовательский интерфейс приложения, его главная страница, если хотите. И нам бы не хотелось, чтобы наша первая страница выглядела ужасно, не так ли?
Теперь, что действительно мешает мне заняться TDD, начиная с завтрашнего дня? Я бы сказал, отсутствие приверженности всех участников. Интеграция реального процесса TDD в организацию очень затратна . Потребуются месяцы, пока не будут созданы все инфраструктуры, и люди перестанут тратить заметное дополнительное время на написание тестов. Первоначально это создает огромные накладные расходы, особенно при работе с устаревшим кодом. В конце концов, дополнительное время, затрачиваемое на написание и сопровождение тестов, окупается созданием кода, который лучше разработан и имеет гораздо более высокое качество. В конце концов, именно так люди и получают непрерывное развертывание, о котором я упоминал выше — они начали с чего-то, верно?
Те, кто желает заплатить дополнительную цену за выполнение TDD, могут добраться до него. Конечно, тем, кому нужны новые функции каждые две недели, будет труднее.
PS
См. Следующий пост «Обновления JUnit» .