Все, все будут писать тесты
Уже 3 года прошло, с тех пор как я увидел свою первую красную полоску. Что меня дернуло начать писать тесты, уже не важно. Я начал собирать информацию, перечитал весь wiki.agiledev.ru и торжественно запустил свой первый тест на SimpleTest. Конечно, эти тесты были ужасны, да и архитектура тоже (в моем сегодняшнем понимании). Тогда я, наверное, словил большинство ошибок, но зато замечательно провел время :)
Потом перешел на PHPUnit — просто было интересно, чем он отличается от SimpleTest и что в нем такого «навороченного».
А lime — гадость. Чего ребята из Symfony в него так вцепились? Понимаю ветка 1.*, наследие и все такое. Но 2.0 можно было бы и на PHPUnit начинать.Да, мне это было интересно. Я активно писал тесты, даже честно пытался делать это перед тем, как писать код.
Потом мне в руки попала книга Мартина «Быстрая разработка ПО» (как всегда случайно, а может закономерно, для того, у кого есть Путь).
Этот дядька заразил меня аджайлом, показал, что такое настоящее ООП и дал хорошего пинка в направлении TDD. У меня до сих пор
С тех пор я стал другим :) Во мне появился стержень и самодостаточность, теперь мне не обязательно было читать чужие статьи, чтобы увидеть недостатки в своем коде и тестах. Подобно Миямото Мусаси я мог познавать истину не обращаясь к помощи учителей.
Сейчас мой код тоже дерьмо, но теперь я отдаю себе в этом отчет.
И только я уже собрался вознестись к небесам, как Кент Бек, показал мне такой фокус, от которого я в восторге до сих пор. Вы
Там же, у Бека, я встретил термин «test infected». Так вот, я заразный :)
Зачем я пишу тесты
Затем, что я параноик и всего боюсь. Когда я написал тест, я уверен, что:
1. Программа работает именно так, как я ожидаю (каждый программист всегда проверяет это, только по-разному, и не всегда самым эффективным способом).
2. Можно вносить изменения в любую часть системы, и при этом у меня ничего не сломается. Или я сразу об этом узнаю и легко исправлю.
Поэтому:
- Я не боюсь вносить изменения в любую часть системы и проводить любой рефакторинг.
- Я постоянно провожу рефакторинг кода, это неотъемлемая и обязательная часть моей работы.
- Код не обрастает
дерьмомжиром и не сопротивляется изменениям. - Я всегда легко, быстро и безболезненно вношу любые изменения и не испытываю при этом ни страха, ни отвращения ни к результату, ни процессу.
- Количество ошибок при этом резко снижается, а те ошибки, что есть, легко диагностируются и исправляются.
- Я не трачу кучу времени на отладку, тестирование и исправление ошибок.
- Я пишу код, который легко протестировать, а это очень сильно влияет на архитектуру полученного решения. Если код сопротивляется тестированию, я понимаю, что у меня проблемы с архитектурой.
- Проблемы интеграции? Что это? Подтянул ветку к мастеру, все тесты прошли. Всё.
- И что самое главное — мне ПРИЯТНО работать с таким кодом. А если там есть недочеты (а они там всегда есть), я уверен, что когда код покрыт тестами, я исправлю это в любой удобный момент.
Путь
- Ценность системы заключается в тестах, поскольку только тесты описывают ее поведение. При этом, код может быть совершенно любым (но пригодным для тестирования). Код без тестов ничего не стоит, он омерзителен и уродлив
по-умолчанию .
- Тест -> Прототип -> Рефакторинг
Тест -> Прототип -> Рефакторинг
Тест -> Прототип -> Рефакторинг
Не обращайте внимания, если на вас косо смотрят, когда вы это бормочете.
- Тесты надо писать в начале. Тест, написанный после кода, ничего не стоит и является только обузой.
- Сначала тест должен упасть. Это тест теста. Если тест не упал, я не могу быть уверен, что он упадет, когда надо.
- Тесты пишут, чтобы их запускать. Тест, который не запускают… а оно вам вообще надо, впустую тратить свое время и
чьи-то деньги?
- Я запускаю тесты каждые 5 минут: по одному, группой, весь набор. Перед тем как начать работу, я запускаю полный набор. Перед каждым коммитом я запускаю полный набор. Когда я долго не запускаю тесты, минут 6, мне становится не по себе. Даже если я ничего не написал за это время, я запускаю полный набор, а потом еще раз. Может быть я псих, но теперь я спокойный псих, уверенный в том, все в порядке.
- Тесты должны проходить очень быстро. Как тогда я их буду запускать каждые 5 минут? Как тогда мне объяснить разработчику, вопрошающе потирающему ушибленное место, что перед коммитом надо запускать полный набор тестов?
- Я люблю баги и обожаю тестировщиков — они их находят (баги). Тогда у меня появляется возможность написать новый тест или исправить существующий. И после этого я уверен, что этот баг НИКОГДА не повторится. Еще на на один шаг я приблизился к идеалу.
- И напоследок: рефакторинг, Рефакторинг, РЕФАКТОРИНГ.
Вот,
Как заключение
Небольшой список литературы:
- Роберт К. Мартин, Джеймс В. Ньюкирк, Роберт С. Косс «Быстрая разработка программ. Принципы, примеры, практика»
- wiki.agiledev.ru
- Кент Бек «Экстремальное программирование. Разработка через тестирование»
- Кент Бек «Экстремальное программирование»
- Джерард Мессарош «Шаблоны тестирования xUNIT»
- Vincent Massol, Ted Husted «JUnit in Action»
- Напишите программу для подсчета очков игры в боулинг. Правила можно посмотреть здесь.
- Напишите (test first) свой xUnit — фреймворк для тестирования. Кто вообще не знаком с принципами модульного тестирование, лучше для начала прочитать Кента Бека. Да и для тех кто знает, это не помешает.