Покрытие кода всегда было показателем тестирования количества строк, которые успешно выполняются в рамках процедуры тестирования, но что на самом деле говорит вам ваш процент покрытия кода?

Я кратко попытался ответить на вопрос Является ли стопроцентное покрытие кода показателем надежности и качества кода?. Я продемонстрировал конвейер тестирования с использованием CodeCov и GitHub Actions, чтобы визуализировать, как работает покрытие, и использовать это как попытку ответить на вопрос. В этой статье я подробно расскажу о том, что может сказать ваша метрика покрытия кода и чего от нее ожидать.



В заключение, чем выше процент покрытия кода, тем выше показатель того, что ваша процедура тестирования обработала большое количество строк кода. Он измеряет надежность, безопасность или совместимость? Не обязательно — это метрика, позволяющая понять, какой охват достигнут производителями тестирования вашей кодовой базы. С другой стороны, что происходит со 100-процентным покрытием кода?

Покрытие кода как показатель

Я не говорю, что покрытие кода не нужно. Наоборот, я считаю, что покрытие кода всегда должно измеряться в каждом проекте. Во всяком случае, покрытие кода — это простая метрика, но она должна быть четко определена, чтобы служить надежной и стабильной основой для тестируемого кода. Другими словами, эта метрика так же хороша, как ваш тип языка программирования, производители тестирования, бизнес-логика и интеграции. Я знаю, что видеть более высокий процент покрытия в репозитории — это цепляюще и интересно. Вы автоматически думаете: «Вау! Это хорошо проверенное и надежное репо». Но вы, вероятно, найдете некоторые открытые проблемы, открытые запросы на вытягивание и некоторые ошибки здесь и там. Что это значит? Почему это происходит?

С другой стороны, покрытие кода само по себе не является методом тестирования. Это измерение того, сколько строк кода выполняется после вызова определенной функции. Покрытие кода эквивалентно частоте совпадений и частоте промахов в компьютерной архитектуре. Сколько обращений — выполненных строк кода — по сравнению с обращениями — невыполненных строк кода. Однако частота совпадений в архитектуре компьютера может определять производительность кэширующей памяти, а процент покрытия кода — нет.

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

Непроверенный код

У вас все еще может быть 100% покрытие кода с непроверенным кодомАмр Галал, инженер-программист. Помните тот репозиторий, который был запоминающимся и надежным? Представьте, что какому-то разработчику поручили реализовать конечную точку API, но по какой-то причине она не была протестирована. Покрытие в этом случае обманчиво, потому что вызова API из процедуры тестирования не произошло, а это означает, что точка входа, в которой покрытие будет измерять ошибочные строки кода, на самом деле не имела места.

Означает ли это, что вам может сойти с рук непроверенный код? Прежде всего, у вас не должно быть непроверенного кода. Другими словами, какой бы метод тестирования вы ни использовали — модульные тесты, интеграционные тесты и т. д., вы не должны отправлять блоки кода без проверки основы логики и любых интеграций, необходимых блоку кода.

Поиск данных

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

Однако эта настройка затем попадает под интеграционные тесты. Другими словами, проверка успешности прохождения процедуры тестирования между несколькими объектами. Если вы не расширите покрытие на обе сущности, где процентная метрика может измерять достоверность каждой сущности по отдельности и интеграцию между ними, вы все равно будете измерять модульный тест, предполагающий настройку.

Чтобы представить это в простом контексте, представьте, что тестируется статический API с разбивкой на страницы, что означает, что количество страниц и элементов статически задается дизайном. Что касается серверной части, то покрытие будет результатом тестовых случаев, верно? В этом случае вы тестируете API, верно? Проверяет ли процедура тестирования настройку извлечения данных или нет? Потому что если это не так, это будет Непроверенный код, и наоборот. Таким образом, у вас может быть более высокий охват ваших строк кода, но при этом возникнут проблемы с поиском и интеграцией данных.

Отказоустойчивость

Большинство проектов становятся отказоустойчивыми. Самый быстрый способ достичь этого — попытаться обработать как можно больше угловых случаев. Обработка ошибок — важный фактор в каждом проекте, и тесты должны это учитывать.

Но разве это то, что касается тестирования? Не совсем! Позволь мне объяснить.

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

Что это значит? Мой проект плохо протестирован? Но у меня охват высокий!

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

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

Представьте себе разработчика, работающего над новой функцией в проекте. Затем разработчик пишет несколько процедур тестирования и отправляет свой код. Что должно произойти с покрытием кода? Увеличивать? Снижаться? Оставайся таким же?

Как разработчик, вы можете использовать покрытие кода в качестве флага для своих процедур тестирования, новых функций и общей логики. Покрытие кода может помочь вам обнаружить части логики, которые вы не тестировали, поэтому — Непроверенный код. Наоборот, разработчик теперь понял бы, как теперь вносить изменения в тестовые блоки. С другой стороны, если покрытие кода увеличивается или остается прежним, это относительно хорошо, так как вы находитесь вне логики, заложенной тестами и проектом. Однако сама база тестирования не может быть измерена по влиянию на покрытие кода.

Наконец, если вы протестировали каждый крайний случай, каждую интеграцию для новой функции и охват вашего кода не изменился и не увеличился, вы в чистоте *относительно*!

Спасибо!