В процеса на писане на тестер за мутации „Off By One“ за любимата ми рамка за тестване на мутации (NinjaTurtles), аз написа следния код, за да предостави възможност за проверка на коректността на моята реализация:
public int SumTo(int max)
{
int sum = 0;
for (var i = 1; i <= max; i++)
{
sum += i;
}
return sum;
}
сега това изглежда достатъчно просто и не ми направи впечатление, че ще има проблем при опит за мутиране на всички буквални целочислени константи в IL. В крайна сметка има само 3 (0
, 1
и ++
).
ГРЕШНО!
При първото изпълнение стана много очевидно, че никога няма да работи в този конкретен случай. Защо? Тъй като промяната на кода на
public int SumTo(int max)
{
int sum = 0;
for (var i = 0; i <= max; i++)
{
sum += i;
}
return sum;
}
само добавя 0 (нула) към сумата и това очевидно няма ефект. Друга история, ако беше множеството, но в този случай не беше.
Сега има доста лесен алгоритъм за изчисляване на сумата от цели числа
sum = max * (max + 1) / 2;
което бих могъл лесно да проваля мутациите, тъй като добавянето или изваждането на 1 от която и да е от константите там ще доведе до грешка. (като се има предвид, че max >= 0
)
И така, проблемът е решен за този конкретен случай. Въпреки че не направи това, което исках за теста на мутацията, който беше да провери какво ще се случи, когато загубя ++
- на практика безкраен цикъл. Но това е друг проблем.
И така - Моят въпрос: Има ли някакви тривиални или нетривиални случаи, при които цикъл, започващ от 0 или 1, може да доведе до неуспех на теста „мутация изключена с единица“, която не може да бъде преработена (тестван код или тест) по подобен начин? (примери моля)
Забележка: Тестовете за мутация са неуспешни, когато пакетът от тестове премине успешно след прилагане на мутация.
Актуализация: пример за нещо по-малко тривиално, но нещо, което все още може да преработи теста, така че да се провали, ще бъде следното
public int SumArray(int[] array)
{
int sum = 0;
for (var i = 0; i < array.Length; i++)
{
sum += array[i];
}
return sum;
}
Тестът за мутация срещу този код би се провалил при промяна на var i=0
на var i=1
, ако тестовият вход, който сте му дали, е new[] {0,1,2,3,4,5,6,7,8,9}
. Променете обаче тестовия вход на new[] {9,8,7,6,5,4,3,2,1,0}
и тестът за мутация ще се провали. Така че успешният рефактор доказва тестването.