Является ли покрытие филиала таким же полезным, как покрытие линии?

Моя организация делает упор на покрытие линии и филиала на 80%. У меня нет абсолютно никаких проблем с требованием о покрытии линии, но у филиала возникла проблема.

Давайте рассмотрим следующий случай:

if(decisionA && decisionB)
{
  // path A - do some complex ninja code stuff
}
else
{
  // path B - tell user i can't do anything
}

Итак, я написал 2 случая, первый из которых охватывает путь А, а второй - путь В. Это должно дать мне 100% покрытие линии. Тем не менее, это дает мне только 50% покрытия веток, так как я только покрыл (True && True) + (False && False), пропуская (True && False) + (False && True).

С моей точки зрения, значения решения А и решения В тривиальны и вряд ли стоит проверять. Тем не менее, общее требование в моей организации теперь означает, что мне придется написать 4 тестовых случая вместо 2. Принесите несколько if и вложенных if, и это становится сложным.

Мне кажется, что решение о том, решит ли он охватить случаи ветвления, должно приниматься самим разработчиком, если он считает, что важная логика (в случае кода ниндзя в части А) покрыта.

Что вы думаете об этом? Как вы думаете, какой будет приемлемый уровень охвата филиала? Оправдан ли мой страх по поводу обеспечения высокой степени покрытия ветвями или я недостаточно подчеркиваю качество кода? Я знаю, что это немного субъективный вопрос, но наверняка уже есть хорошие модели в этом отношении.

2 ответа

Решение

Во-первых, терминология: то, что вы описываете, - это не покрытие филиалов, а "покрытие нескольких условий" или "покрытие составных условий".

Вы определенно не хотите устанавливать стандарт для покрытия нескольких условий; это слишком много работы для слишком маленькой выгоды. Например, если ваше состояние a & b & c & d & eгде пять основных условий являются логическими значениями, вам нужно написать 32 теста, что просто нецелесообразно. Было бы более разумно использовать критерий охвата базовых условий: напишите один тест со всеми пятью ложными условиями, а затем один тест с каждым истинным условием, всего шесть.

Покрытие ветви означает, что тесты осуществляют все пути через каждую ветку, например, оба if и else в вашем примере. В вашем примере покрытие линии и ветви достигается двумя тестами; Покрытие филиала отличается, если нет else или существует более одной ветви на линии. Покрытие филиала гораздо проще достичь, чем покрытие нескольких (или базовых) условий, некоторые инструменты измеряют его, и было бы разумно установить для него стандарт вместо покрытия линии. Идея Рэдвальда хороша, хотя я обращаюсь к ней, запрещая конструкции, скрывающие решения в одной строке.

Покрытие ветви - более полезная метрика, чем покрытие линии, потому что изменения формата кода могут варьировать значение метрики покрытия линии.

Рассмотрим эти два фрагмента кода для случая, когда условие всегда выполняется:

 If (condition) {
    good();
 } else {
    bad();
 }

а также

 If (condition) {good();} else {bad();}

В обоих случаях покрытие филиала составляет 50%. Во втором случае охват линии составляет 100%, в первом случае - меньше.

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

Другие вопросы по тегам