Вчера был на тренинге Kevlin Henny под названием «Programming with GUTs». (Кевлин автор нескольких книг, например «Things Every Programming Should Know»)
«GUT» – это сокращение от Good Unit Tests.
Также я узнал выражения «Programming with BUTs» (Brittle Unit Tests) и «Programming with NUTs» (No Unit Tests).
Итак, «…with GUTS» - это хорошо, «…with BUTs» - хуже, «…with NUTs» - безумие.
Вся эта терминология построена на игре слов guts, butt и nuts в английском языке, которые своим двойным смыслом примерно отражают ситуацию в проекте, когда тестирование находится на указанном уровне (Good, Brittle, No).
Дядька очень интересно ведет беседу, нескучно. Вовремя переходит от приколов к важным выводам, что, например, что ошибки – это не зло, а данность (процесс создания программа сложен, и ошибки – это часть процесса), поэтому очень важно уметь использоваться их для своих целей. Глупо исправлять баг, не написав для него unit- или regression- тест, так как без теста информация, которую несет в себе баг-репорт, будет потеряна по исправления ошибки.
Не могу сказать, что я узнал что-то радикально новое для себя, хотя услышал несколько интересных мыслей и аналогий.
Например, дежурный вопрос менеджера (не очень умного менеджера) проекта: «А если мы будем практиковать TDD в разработке, это замедлит процесс?». И ваш правильный и политический верный ответ будет решительное «ДА!». «А правда, что написание тестов вместе с кодом призвано затормозить работу разработчика?». «ДА!!!».
В короткой перспективе – да, но в долгосрочной – нет, а совсем наоборот.
Есть хорошая аналогия. Можно ли доехать из места А в место Б на машине, у которой нет традиционных тормозов (а например, только ручник)? Теоретически да. Очень очень медленно, правильно используя торможение двигателем и ручником. Задача будет решена, но очень не быстро, и вероятность облажаться очень высока. А вот если машину оборудовать нормальными тормозами (~unit-тестами), цель которых останавливать машину (и увеличивать время достижения цели), то они также позволят активно разгоняться между торможениями, и как результат – приехать быстрее.
Мораль – тесты позволяют взять ваш код под контроль, превратить его из телеги, несущейся с горы на огромной скорости, в гоночный болид, который ездит также быстро, как и останавливается. Тесты радикально затормозят вас, когда это нужно. Но с другой стороны они позволят не дрожать всем телом, когда надо потрогать какой-то очень важный кусок кода (например, библиотеку строчек), а спокойно провести рефакторинг и проверить результаты.
Все эти посылы просто TDD очевидны и однозначно разумны, но я был поражен до глубины души, когда кто-то таки спросил из зала, а если я, мол, просто буду писать много комментариев, чтобы всем было понятно, что код делает. И это был не вопрос-прикол. Кто-то спросил это на полном серьезе.
По поводу комментариев была приведена также интересная аналогия. Комментарии в коде – это золото. Но золото обесценивается, когда его становится слишком много. Комментариев много бывает (особенно бесполезных).
На лабах было интересное задание. Программисту дается задание написать класс и unit-тесты для него. Затем эти тесты уже без кода класса даются другому программисту, и его просят воспроизвести функционал класса, основываясь только на тестах к нему. Результаты порой «радуют» даже продвинутых бойцов TDD.
Вывод как всегда простой: тестируйте как можно раньше, тестируйте чаще, тестируйте автоматизировано. Тестирование – это часть работы программиста в первую очередь, а тестера – во вторую.
P.S. Небольшое задание для интересующихся. Допустим, вы написали собственный алгоритм сортировки. Как его тестировать? Каковы будут критерии проверки, что результат такой, какой вы ожидаете?