Когда вы пишете тесты согласно трем правилам разработки через тестирование, это клево. Каждый новый тест — это вызов. Каждое успешное прохождение теста — это маленький праздник. Когда вы следуете трем правилам, ваша работа представляется чередой маленьких вызовов и праздников. Нет чувства неблагодарной работы, вместо этого вы понимаете, что даете жизнь чему-то новому.
Полнота
Но вернемся к тестам, которые выполняют после того, как все уже готово. Кто-то зачем-то обязал вас написать эти тесты, причем вы уже протестировали все вручную и знаете, что все работает. Вы переходите от теста к тесту, не удивляясь тому, что программа спокойно проходит тесты.
Неизбежно вы дойдете до теста, который будет трудно написать. Его трудно написать, потому что во время написания кода вы забыли о тестируемости, а структура кода такова, что его просто так не протестируешь. Чтобы написать тест к этому коду, надо поменять структуру кода. Придется разорвать некоторые связи, добавить несколько абстракций, а может, и перенаправить некоторые вызовы функций и аргументы. Кажется, что переделана гора работы, потому что вы и так знаете, что код работает.
У вас плотный график, и есть работа поважнее. Поэтому вы откладываете тест. Вы убеждаете себя, что в нем нет необходимости и написать его можно попозже. И вот теперь у вас пробел в тестовом наборе.
И поскольку вы оставляли пробелы в тестовом наборе, вы подозреваете, что все остальные тоже так делают. Когда вы запускаете тестовый набор и видите, что он пройден успешно, вы покрякиваете, ухмыляетесь или насмешливо отмахиваетесь, потому что знаете: прохождение тестов не означает, что программа работает.
Когда программа проходит такой набор тестов, нельзя принять решение. Все сведения, которые мы получаем от прохождения тестов… — это то, что работает все, что тестировалось.
Неполнота тестов оставляет вас без вариантов. Но если вы будете следовать тем самым трем правилам, каждая строка кода будет написана так, что тест будет пройден. Таким образом, тестовый набор станет полным. Когда программа проходит набор тестов, можно принять решение. Решение о развертывании.
Вот это цель! Мы хотим создать набор автоматизированных тестов, который даст уверенность, что развертывание программного обеспечения безопасно.
И снова хочу сказать, я не пишу вам тут картину маслом. Соблюдение трех правил позволит создать полный тестовый набор, но и тут нельзя быть на 100 % уверенным. Есть ситуации, когда три правила разработки через тестирование неуместны. Эти ситуации выходят за рамки этой книги, скажу лишь, что они ограниченны, и есть решения, которые смягчают их. В результате даже самые прилежные приверженцы наших трех правил вряд ли смогут создать тестовый набор, который будет выполнен на 100 %.
Но в 100 %-ной полноте тестов нет необходимости для принятия решения о развертывании. Значения в 95 % вполне достаточно — и такая полнота тестов поистине достижима.
Я создавал настолько полные тестовые наборы, что они позволяли принять решение о развертывании. Я видел, как многие другие делают то же самое. В каждом из таких случаев полнота не достигала 100 %, но ее хватало, чтобы принять решение о развертывании.
Внимание
Полнота тестов — это показатели для команды, а не для руководства. Менеджеры вряд ли знают, что на самом деле означают эти показатели.
Еще раз внимание
Проектирование
Помните ту функцию, которую было трудно протестировать, а код уже до этого тестировали вручную? Может, ее трудно протестировать потому, что она связана с задачами, которые вы не хотите запускать в тесте? Например, это может быть включение рентгеновского аппарата или удаление рядов из базы данных. Функцию тяжело протестировать, потому что она спроектирована не так, чтобы это можно было сделать легко. Вы сначала пишете код, а потом пишете тесты задним числом. Тестируемость конструкции была тем, о чем вы думали в последнюю очередь, когда писали код.