Мой подход заключается в том, чтобы помнить, что модульное тестирование предназначено для поиска определенных типов ошибок. Как только вы достаточно уверены, что ваши юнит-тесты улавливают все эти ошибки, все готово. Уровень доверия, который вам нужен, может варьироваться в зависимости от тестируемой системы и может даже потребовать других методов, таких как формальные доказательства и т. Д.
Существуют систематические подходы, которые помогают вам вывести тестовые случаи, особенно с целью найти ошибки, которые могут присутствовать, например, граничное тестирование (которое помогает при поиске многих ошибочных ошибок) или эквивалентное разбиение .
Анализ покрытия может помочь вам определить сценарии выполнения (и соответствующие им потенциальные ошибки), которые вы пропустили, но достижение определенного уровня покрытия, вероятно, не является полезной целью по нескольким причинам:
Не каждая ошибка может или должна быть найдена при юнит-тестировании. Например, для утечек памяти вы скорее используете проверку памяти. Для доступа за пределы вы используете статический анализ или проверку памяти. Для тестирования взаимодействий с другими компонентами или с аппаратным обеспечением вы скорее проводите интеграционное тестирование: код, который имеет дело только с взаимодействиями, должен охватываться интеграционным тестированием, но не обязательно модульным тестированием.
Можно решить, что некоторые ошибки слишком маловероятны, чтобы тратить ваше время на создание для них тестов. Имейте в виду, что вы можете тратить каждый час своего времени только один раз, и вы должны делать то, что имеет наибольшую вероятность ошибок. Таким образом, выполнение статического анализа и работа с результатами может лучше использовать ваше время, чем написание тестовых примеров для тривиальных геттеров и сеттеров - хотя это простой способ увеличить охват тестами ...