суббота, 14 декабря 2013 г.

Исповедь про тесты в разработке.

Сегодняшнюю запись я хочу озаглавить старой "поговоркой":
"Админы делятся на две категории:  те кто ещё не делают бэкап и те кто уже уго делает".

Как супер полезны тесты гласит каждая первая запись о них. Читаешь - глаз радуется.
Потом начинается фалометрия с test coverage. Что обязательно оно должно быть в 146% и пр. пр.
Я заниматься этим сейчас не хочу. Расскажу я про психологические аспекты при внедрение тестирования. Соответтвенно далее идут всё рассказываю про себя.

Боязнь забыть суть

Очень простая и здравая идея не делать тесты, если код делать 10 минут. Читается он легко уровней абстракции всего ничего. Радость просто. Для того, что бы понять код через месяц потребуется пять минут. А что если код вы делаете к примеру два раза в день по 2 часа. А это значит, что ваш объем кода достигнет таких объемов при котором: 
"# TODO: Надо тут поправить кое-что " -  будет вызывать у вас смутные подозрения, что вы этот кусок уже подзабыли. И на воспоминание этого "кое-что" уйдёт много времени...

А при чём тут тесты? 
Резонный вопрос, вроде бы ни причём, если вы не тестируете логику приложения. А когда вы её тестируете, то взглянув на тесты вы быстро понимаете приложение и кусок того, что надо сделать.
Вывод: тесты должны покрывать логику и граничные условия.

Боязнь изменения кода

Честно, я много раз ловил себя на том, что я уже не помню как этот кусок работает, суть не очень помню... хотя вроде тут совсем чуть-чуть поправить-то надо было... И спустя 3-4 часа это "чуть-чуть" плавно перерастает в "ОГОГО". Всё это было до тестов. С тестами я могу править кусок и не так сильно бояться за целостность приложения. Оно упало и мне надо подогнать под тесты и при баге добавить тест.

Вывод: тесты уменьшают ваш внутренний страх.

Нежелание возвращаться к коду

У меня такое было часто, до тестов. Почему? Страх изменения кода играл в этом ключевую роль. Я боялся, очень. Правда сказать я и сейчас боюсь, но куда меньше. Просто несоизмеримо меньше.

Ну это всё голые слова и ничего более

Я ничего ни кому доказывать не хочу, кроме как себе любимому.
Сделал я просто, взял и замерил два проекта приблизительных по объему и качеству кода. Т.к. всё это с двух моих проектов, которые делались в приблизительно одинаковый промежуток времени, то я смело считаю, что могу делать такое сравнение.
Замеры делал просто. Я брался за код, только в выходные. И не ранее чем через 2 недели для каждого проекта. Засекал время по следующим параметрам:
1. Сколько у меня уходит времени поправить баг?
2. Сколько у меня уходит времени сделать TODO(обычно это фичи или улучшения) в коде?
3. Сколько у меня уходит времени внести глобальные правки (разработать новый модуль)?

Стадии при разработки были такие
a. Понять суть задачи
b. Найти код который за неё отвечает
c. Запустить и посмотреть, что и как он делает сейчас.
d. Внести изменения.
e. Проверить и если что-то идёт не так, то вернуться к пункту "d".

Первый, второй и третий пункты одинаковы, по этому их время - константа. Обычно это около 15 минут для меня.
А дальше мы видим итерации, вот их я и считал. Вот данные по 2 пункту (TODO):
1. Количество итераций: Без тестов: 5-8 итераций. С тестами 12-16 итераций.
2. Время занимаемое на итерацию: Без тестов от 20 до 30 минут. С тестами от 5 до 10 минут.
Итог: без тестов от 1.5 часов до 4 часов, с тестами 1 часа до 3 часов.
Я стал замечать за собой, что после итерации я запускаю тесты и только когда они проходят иду уже смотреть конечный результат. Именно по этому итераций стало существенно больше, но все они стали проходить гораздо чаще. Мне морально проще смотреть промежуточный результат, когда код прошёл тесты.
Вывод: для меня тесты уменьшили срок выполнения задачи в 1.5-2 раза. Хотя на написание тестов в начале(3 пункт) я трачу в 1.5-2 раза больше времени, но само это время на порядок(около десяти раз) меньше, чем то время, которое я трачу на отладку без тестов.

Что мне это дало?

Я перестал относиться к коду, как к УГ на которое мне сейчас надо убить уйму времени.
Я стал его рассматривать как задорные какушки, которые быстро и красиво можно поправить. И теперь мне стало легче.

Тестировать всё и вся!

Часто в статьях вижу, что тестами надо покрывать всё и вся. И тогда у нас будет coverage(покрытие) на все сто и мы точно застрахованы от всяких там ошибок.
Но вот вопрос. А что же надо покрыть и нужное ли мы тестируем? И вот тут возникает множество вопросов ответы на которое очень зависят от контекста задачи.
А для себя я определил что и в каких рамках я тестировать обязан.