Я воспользовался свободой добавления номеров строк в ваш код, чтобы иметь возможность дать лучшее объяснение.В комментариях вы упомянули, что вы заинтересованы в освещении заявления.Операторы в ваших примерах кода находятся в строках 07, 09 и 11, а также в 18, 20 и 22. И, конечно, сами операторы if
также являются операторами (отсюда и название), но они все равно будут выполняться впри каждом выполнении соответствующей функции.
При одном выполнении функции oneParameter
будет выполняться ровно один из условных операторов: либо в строке 07, либо в строке 09, либо в строке 11. Это происходит из-заисключительный характер заявления if-else if-else
.Аналогично, при одном вызове функции twoParameter
будет выполняться либо оператор в строке 18, либо в строке 20, либо в строке 22.
Следовательно, чтобы охватить все операторы, необходимо вызвать каждую функциютри раза.Аргумент, который управляет фактической взятой ветвью, является в обоих случаях аргументом shape
.Это означает, что значение других аргументов не имеет отношения к тому, какой оператор будет выполняться.Тривиальный набор вызовов может быть следующим:
oneParameter("A", 0.0);
oneParameter("B", 0.0);
oneParameter("any other", 0.0);
twoParameter("N", 0.0, 0.0);
twoParameter("M", 0.0, 0.0);
twoParameter("any other", 0.0, 0.0);
Это пример минимального набора вызовов, который обеспечит 100% покрытие операторов.Что может быть удивительным, так это то, что это всего лишь звонки - даже нет оценки результатов.Когда мы говорим о тестовом покрытии, подразумевается, что соответствующие строки кода не только выполняются, но и что соответствующие результаты оцениваются как часть теста.Тогда это может выглядеть следующим образом:
assertEquals(0.0, oneParameter("A", 0.0));
assertEquals(0.0, oneParameter("B", 0.0));
assertEquals(-1.0, oneParameter("any other", 0.0));
assertEquals(0.0, twoParameter("N", 0.0, 0.0));
assertEquals(0.0, twoParameter("M", 0.0, 0.0));
assertEquals(-1.0, twoParameter("any other", 0.0, 0.0));
Несмотря на тот факт, что теперь он имеет 100% охват заявлений и также выполняет оценку результатов, он все еще далек от того, чтобы быть высококачественным набором тестов.Причина в следующем: модульное тестирование обычно выполняется с основной целью поиска ошибок в коде.Однако приведенный выше набор тестов не совсем подходит для поиска каких-либо интересных ошибок.Чтобы дать вам несколько примеров возможных ошибок, которые этот набор тестов не найдет:
- По ошибке были заменены вычисления в функции
oneParameter
для "A"
и "B"
. - В функции
twoParameter
для "N"
операция *
была ошибочно заменена на +
. - В функции
twoParameter
для "N"
вместо умножения x1
на x2
, выражение умноженное x1
на x1
. - В функции
twoParameter
для "M"
константа была установлена на 0.05
вместо правильного 0.5
.
Это всего лишь примеры возможных ошибок.Поэтому для того, чтобы серьезно отнестись к поиску возможных ошибок, нужно думать не только о покрытии.На самом деле, могут быть даже части кода, которые вообще не подходят для тестирования с помощью модульного тестирования - хотя в вашем простом примере это не так.Примерами таких частей кода являются недостижимый код (например, ветвь по умолчанию оператора switch, добавленного для устойчивости) или код, который состоит только из взаимодействий с другими компонентами, и в этом случае тестирование интеграции является более подходящим подходом.Поэтому достижение 100% охвата зачастую не имеет смысла, даже если вы искренне стремитесь получить пакет качественных юнит-тестов.
Охват, тем не менее, является ценной информацией для разработчиков, которые заинтересованы в том, чтобы они рассмотрели все соответствующие сценарии в своем коде.К сожалению, охват гораздо менее ценен, если судить о качестве набора тестов с управленческой точки зрения: в этом контексте он часто сводится к простому проценту, и разработчики вынуждены создавать тесты, пока не будет достигнут определенный процент охвата.- но достаточно часто, не давая им достаточной подготовки, времени и поддержки, чтобы правильно провести тестирование.Как следствие, чтобы достичь покрытия, скажем, 80%, весь тривиальный код (геттеры и сеттеры и т. П.) Может быть «протестирован» для увеличения охвата.Однако тестирование самого сложного и трудного для тестирования 20% кода откладывается из-за нехватки времени (хотя это, вероятно, код, в котором скрыты ошибки).И даже те 80%, которые были покрыты, могут быть протестированы плохо, как с минимальным набором тестов, который я показал выше.