Трагедия стопроцентного покрытия кода

в 6:57, , рубрики: tdd, test-driven development, unit test, Блог компании Everyday Tools, тестирование, Тестирование веб-сервисов, Тестирование игр, Тестирование мобильных приложений, юнит-тестирование, юнит-тесты

Забавно, как всё меняется. Пятнадцать лет я свято придерживался принципов TDD (разработка через тестирование, или, как её раньше называли, подход test-first) или уж по крайней мере того взгляда, что разработчикам следует писать юнит-тесты. Но в последнее время я всё чаще говорю не «Это нужно затестить», а «Зачем вы писали этот тест?».

Трагедия стопроцентного покрытия кода - 1

Почему так?

Как-то раз, когда я проходил по офису, меня остановил один разработчик и попросил помочь с юнит-тестами. У него возникли какие-то сложности при использовании Mockito для тестирования вот этого кода:

Трагедия стопроцентного покрытия кода - 2

Мой ответ его, кажется, удивил. Я сказал: «Это не нужно тестировать».

«Конечно, нужно!» — ответил он. «Как я иначе узнаю, что всё работает?»

«Это совершенно прозрачный код. В нём ничего такого нет: ни атрибутов conditional, ни циклов, no трансформаций. Просто обычный кусок связующего кода».

«Но если не провести тест, кто угодно может прийти, внести какие-нибудь изменения и всё сломать!»

«Послушай, пусть даже этот воображаемый недотёпа или злодей действительно придёт и всё испортит — как ты думаешь, что он сделает, когда соответствующий юнит-тест провалится? Удалит, и все дела».

«Ну а если бы тебе пришлось писать тест?»

«В таком случае я бы вышел из положения вот так».

Трагедия стопроцентного покрытия кода - 3

«Но ты же не используешь Mockito!»

«И что? Mockito никак здесь тебе не помогает. Даже наоборот, мешается. С ним тест не станет ни проще, ни читабельнее».

«Но мы же решили, что будем проводить все тесты с помощью Mockito!»

Мой ответ: «…»

Когда я в следующий раз с ним столкнулся, он с гордостью поведал мне, что всё-таки сумел написать этот тест на Mockito. Я понимаю, какое удовлетворение испытываешь, когда получается заставить что-то работать, и всё же мне как-то взгрустнулось.

Другой пример

Другой раз меня подозвал разработчик, окрылённый высоким покрытием кода одного из своих новых приложений и вспыхнувшей любовью к BDD (разработке на основе поведения). Просматривая код, мы нашли такой тест на Cucumber:

Трагедия стопроцентного покрытия кода - 4

Тех, кто работал с Cucumber, не удивит объём вспомогательного кода, которого он требует:

Трагедия стопроцентного покрытия кода - 5
Трагедия стопроцентного покрытия кода - 6

И всё это ради того, чтобы протестировать следующее:

Трагедия стопроцентного покрытия кода - 7

Да-да, простой map lookup. Я был достаточно высокого мнения об этом разработчике, чтобы сказать без обиняков: «Столько времени потрачено впустую».

Он ответил: «Но мой начальник рассчитывает, что я буду писать тесты для всех классов».

«И во что это тебе обходится?»

«Обходится?»

«К тому же, этого не имеет никакого отношения к BDD».

«Знаю, но мы решили проводить все тесты при помощи Cucumber».

Мой ответ: «...».

Я понимаю, какое удовлетворение испытываешь, когда удаётся приспособить инструмент под свои нужды, и всё же мне как-то взгрустнулось.

В чём трагедия?

Трагедия в том, что двое талантливых разработчиков (я бы охотно сходил с ними на командное интервью) убивают время на подобные тесты — тесты, от которых никакого проку и которые следующим поколениям разработчиков из IG придётся поддерживать в рабочем состоянии.

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

Трагедия в том, что, когда «хорошая практика» становится общепринятой, мы будто забываем, как к ней пришли, какие преимущества она предлагает, и — самое-то главное — каких затрат она требует.

Вместо того, чтобы иметь это всё в виду, мы просто автоматически применяем её, особо не задумываясь, и в итоге получаем весьма посредственные результаты — теряем большую часть преимуществ, а платим при этом полную цену (иногда и с накруткой). Мой опыт говорит, что создание качественных юнит-тестов — работа непростая.

Так стоит ли обрабатывать код целиком?

Да, это должен проделать каждый… но только в рамках одного проекта.

У нас более чем достаточно примеров одной крайности: проектов без единого юнит-теста, и мы уже знаем, как мучительно с ними работать. Но мало у кого есть опыт взаимодействия с противоположной крайностью: проектов, где требуют стопроцентного покрытия кода и во всём придерживаются TDD. Юнит-тесты (особенно те, где реализуется подход test first) — отличная практика, но нам необходимо понимать, какие тесты полезны, а какие — только снижают продуктивность.

Помните: ничто не обходится нам даром, палочек-выручалочек не существует. Всегда лучше остановиться и подумать.

Автор: nanton

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js