Как стать автором
Обновить

Test Infected

Время на прочтение5 мин
Количество просмотров4.6K

Все, все будут писать тесты


Уже 3 года прошло, с тех пор как я увидел свою первую красную полоску. Что меня дернуло начать писать тесты, уже не важно. Я начал собирать информацию, перечитал весь wiki.agiledev.ru и торжественно запустил свой первый тест на SimpleTest. Конечно, эти тесты были ужасны, да и архитектура тоже (в моем сегодняшнем понимании). Тогда я, наверное, словил большинство ошибок, но зато замечательно провел время :)

Потом перешел на PHPUnit — просто было интересно, чем он отличается от SimpleTest и что в нем такого «навороченного».
А lime — гадость. Чего ребята из Symfony в него так вцепились? Понимаю ветка 1.*, наследие и все такое. Но 2.0 можно было бы и на PHPUnit начинать.
Да, мне это было интересно. Я активно писал тесты, даже честно пытался делать это перед тем, как писать код. Что-то не получалось, читал разные статьи на тему, как надо и не надо писать тесты, перечитывал wiki.agiledev.ru. Но внутри явно чего-то не хватало.

Потом мне в руки попала книга Мартина «Быстрая разработка ПО» (как всегда случайно, а может закономерно, для того, у кого есть Путь).
Этот дядька заразил меня аджайлом, показал, что такое настоящее ООП и дал хорошего пинка в направлении TDD. У меня до сих пор где-то в архивах лежит версия программы для расчета количества очков для игры в боулинг, написанная с помощью TDD (кому интересно, ссылка в конце статьи).

С тех пор я стал другим :) Во мне появился стержень и самодостаточность, теперь мне не обязательно было читать чужие статьи, чтобы увидеть недостатки в своем коде и тестах. Подобно Миямото Мусаси я мог познавать истину не обращаясь к помощи учителей.
Сейчас мой код тоже дерьмо, но теперь я отдаю себе в этом отчет.

И только я уже собрался вознестись к небесам, как Кент Бек, показал мне такой фокус, от которого я в восторге до сих пор. Вы когда-нибудь писали фреймворк для тестирования через тестирование с помощью этого же фреймворка? Т. е. вы пишете код, с помощью которого вы его пишете. Я пробовал — это незабываемое удовольствие. Кент Бек рекомендует так начинать изучение нового языка — писать свой xUnit на новом языке. Ruby меня ждет.

Там же, у Бека, я встретил термин «test infected». Так вот, я заразный :)

Зачем я пишу тесты


Затем, что я параноик и всего боюсь. Когда я написал тест, я уверен, что:
1. Программа работает именно так, как я ожидаю (каждый программист всегда проверяет это, только по-разному, и не всегда самым эффективным способом).
2. Можно вносить изменения в любую часть системы, и при этом у меня ничего не сломается. Или я сразу об этом узнаю и легко исправлю.

Поэтому:
  • Я не боюсь вносить изменения в любую часть системы и проводить любой рефакторинг.
  • Я постоянно провожу рефакторинг кода, это неотъемлемая и обязательная часть моей работы.
  • Код не обрастает дерьмом жиром и не сопротивляется изменениям.
  • Я всегда легко, быстро и безболезненно вношу любые изменения и не испытываю при этом ни страха, ни отвращения ни к результату, ни процессу.
  • Количество ошибок при этом резко снижается, а те ошибки, что есть, легко диагностируются и исправляются.
  • Я не трачу кучу времени на отладку, тестирование и исправление ошибок.
  • Я пишу код, который легко протестировать, а это очень сильно влияет на архитектуру полученного решения. Если код сопротивляется тестированию, я понимаю, что у меня проблемы с архитектурой.
  • Проблемы интеграции? Что это? Подтянул ветку к мастеру, все тесты прошли. Всё.
  • И что самое главное — мне ПРИЯТНО работать с таким кодом. А если там есть недочеты (а они там всегда есть), я уверен, что когда код покрыт тестами, я исправлю это в любой удобный момент.

Путь

  • Ценность системы заключается в тестах, поскольку только тесты описывают ее поведение. При этом, код может быть совершенно любым (но пригодным для тестирования). Код без тестов ничего не стоит, он омерзителен и уродлив по-умолчанию.

  • Тест -> Прототип -> Рефакторинг
    Тест -> Прототип -> Рефакторинг
    Тест -> Прототип -> Рефакторинг
    Не обращайте внимания, если на вас косо смотрят, когда вы это бормочете.

  • Тесты надо писать в начале. Тест, написанный после кода, ничего не стоит и является только обузой.

  • Сначала тест должен упасть. Это тест теста. Если тест не упал, я не могу быть уверен, что он упадет, когда надо.

  • Тесты пишут, чтобы их запускать. Тест, который не запускают… а оно вам вообще надо, впустую тратить свое время и чьи-то деньги?

  • Я запускаю тесты каждые 5 минут: по одному, группой, весь набор. Перед тем как начать работу, я запускаю полный набор. Перед каждым коммитом я запускаю полный набор. Когда я долго не запускаю тесты, минут 6, мне становится не по себе. Даже если я ничего не написал за это время, я запускаю полный набор, а потом еще раз. Может быть я псих, но теперь я спокойный псих, уверенный в том, все в порядке.

  • Тесты должны проходить очень быстро. Как тогда я их буду запускать каждые 5 минут? Как тогда мне объяснить разработчику, вопрошающе потирающему ушибленное место, что перед коммитом надо запускать полный набор тестов?

  • Я люблю баги и обожаю тестировщиков — они их находят (баги). Тогда у меня появляется возможность написать новый тест или исправить существующий. И после этого я уверен, что этот баг НИКОГДА не повторится. Еще на на один шаг я приблизился к идеалу.

  • И напоследок: рефакторинг, Рефакторинг, РЕФАКТОРИНГ.

Как писать хорошие тесты? Если у Вас есть Путь, это вопрос времени.
Вот, как-то так.

Как заключение


Небольшой список литературы:Задачки, для тех кто хочет поразвлечься:
  • Напишите программу для подсчета очков игры в боулинг. Правила можно посмотреть здесь.
  • Напишите (test first) свой xUnit — фреймворк для тестирования. Кто вообще не знаком с принципами модульного тестирование, лучше для начала прочитать Кента Бека. Да и для тех кто знает, это не помешает.
Теги:
Хабы:
+45
Комментарии40

Публикации