Покрытие кода

В связи с последними постами на тему тестирования и использования Mighty Moose, хотелось бы так же затронуть тему покрытия кода, которую менеджеры часто используют для оценки качества кода. Некоторые разработчики, неискушенные в вопросах тестирования могут так же думать, что покрытие кода одно из ключевых свойств отображающих насколько качественно написаны тесты. К авторам MightyMoose так же выдвигались требования и просьбы включить покрытие кода в продукт, но Грег яростно отпирается от этого, так как само по себе покрытие кода не говорить ни о чем совершенно.

Можно с относительной легкостью покрыть любой, сколь угодно большой проект тестами так, чтобы покрытие указывало на цифру близкую к 100, так, чтобы менеджер проекта был доволен результатом, но это никак не покажет реального положения дел, так как это может быть парочка глобальных тестов, которые по факту ничего не тестируют. В свою очередь анализатор покрытия кода при выполнении тестов промаркирует все рабочие методы и классы как вызванные в процессе теста и отобразит методы как покрытые.

Значение покрытия не дает ничего. НИЧЕГО.

Предлагаю рассмотреть несколько сценариев, когда покрытие кода не дает желаемого результата.

Пустое состояние

Начнем с самого простого, на чем можно проколоться, это когда вы в тесте проверяете не те вещи. Наиболее банальной вещью является наверно пример с вау фактором, когда на демонстрации тестов мы пишем простейшую процедуру, пишем тест через red-green-refactor подход, смотрим покрытие кода и получаем результат. Да, примеры очень простые, но со сложными тестами будет все еще хуже.

Оу, тест проходит! Самое простое что можно сделать. Попробуем написать еще один тест.

Тест ожидаемо падает, тогда меняем реализацию метода:

Тест снова проходит. До прохождения теста код не был покрыт, после прохождения – покрыт. Но значит ли это что тесты хорошие? Увижу ли я разницу, если я напишу такой тест:

Тест пройдет, код будет покрыт и разукрашен приятным зеленым цветом, но это все лишь украшательство, которое не дает реальной пользы. Правильно ли я написал тест, правильно ли я проверил данные, все это отходит на задний план, если тест прошел и покрытие есть, просто переходим к следующему куску кода и тесту. Так?

Дописывание существующего кода

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

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

Рефакторинг

При рефакторинге кода я должен быть уверен в тестах, чтобы смело менять код и видеть результат по тестам. Да, это отчасти перекликается с ситуацией дописывания существующего кода. В этой ситуации покрытие кода может добавлять ложной уверенности в безопасности изменений. При рефакторинге приходится пересматривать много собственного кода, переписывать много тестов и я могу забыть о части тестов связанных с кодом. Тесты могут тестировать несуществующие вещи, пустой результат. В общем, знание того что «что-то» тестирует метода, совершенно не помогает в деле.

Еще одной проблемой может быть стремление догнать покрытие до 100% даже у опытных разработчиков, когда тесты пишутся ради покрытия, а не для раскрытия системы. Надо перебарывать свою лень и писать значимые тесты, так как они дадут больше информации для размышления и нахождения других потенциально опасных сценариев.

 

Может быть гораздо полезнее знать сколько тестов покрывают метод, так как я все же надеюсь, что простая логика не даст вам написать 20+, 50+, 80+ абсолютно одинаковых тестов. Mighty Moose позволяет посчитать количество покрывающих тестов и выдать это в удобном виде. Так же инструмент позволяет вычислить степень риска при изменении метода. Т.е. может быть 50+ методов, но высокая степень риска, так как вы тестируете что-то не то. Вообще я не знаю каким образом MM считает степень риска, но полагаю идет анализ проверки конструкций и связанных переменных, насколько длинна цепочка вызовов и модификаций, насколько они сложны. Использование графов в ММ очень мощный инструмент для отслеживания степени покрытия метода тестами. Чем ближе тесты к тестируемому, тем в целом выше будет степень уверенности.

 

Но даже если ММ показывает зеленые круги и все радужно, не теряйте голову, помните о хорошей поговорке: when you assume you make an ass of u and me.

 

Hard’n’Heavy!

Violet Tape

Оставить комментарий