Troška teórie na začiatok
Mutačné testovanie (alebo tiež analýza mutácií) sa používa pri návrhoch nových testov v agilnom procese vývoja softvéru. Vyhodnocuje sa nimi kvalita existujúcich Unit testov. Mutačné testovanie vyvoláva zmenu testovaného kódu, tzv. mutácie. Každá zmutovaná verzia kódu sa nazýva mutant a testy, ktoré majú za úlohu odhaliť mutantov tým, že odhalia odlišné správanie zmutovaného kódu od pôvodnej-originálnej verzie sa nazýva zabíjanie mutantov.
Testovacie suity sú potom merané percentom zabitých mutantov. Nové testy môžu byť navrhnuté aj tak, aby zabíjali ďalších možných mutantov a zároveň odhaľovali tzv. „weak tests“ – slabé testy.
Mutácie kódu sú založené na definovaní tzv. „operátorov mutácie“, ktoré buď napodobňujú typické chyby v programovaní (napríklad použitie zlého operátora alebo názvu premennej), alebo mutáciou vytvoria chyby kódu (ako je napríklad delenie nulou každého výrazu v testovanej metóde). Cieľom je pomôcť testerom a developerom vytvoriť lepšie testy, alebo nájsť nedostatky v testovacích dátach použitých pri testoch.
Krátky priklad
Majme testovaciu Java triedu (Calculator.java)
public class Calculator {
int valueDisplayed;
public Calculator() {
this.valueDisplayed = 0;
}
public Calculator(final int initialValue) {
this.valueDisplayed = initialValue;
}
public void add(final int x) {
this.valueDisplayed += x;
}
public void subtract(final int x) {
this.valueDisplayed -= x;
}
public void power(final int x) {
this.valueDisplayed = (int) Math.pow(this.valueDisplayed, x);
}
public int getResult() {
return this.valueDisplayed;
}
public void set(final int x) {
this.valueDisplayed = x;
}
public boolean setConditional(final int x, final boolean yesOrNo) {
if (yesOrNo) {
set(x);
return true;
}
else {
return false;
}
}
}
… a k nej asociovanú testovaciu triedu (CalculatorTest.java)
import org.junit.Assert;
import org.junit.Test;
import Calculator;
public class CalculatorTest {
@Test
public void testAddition() {
final Calculator calculator = new Calculator();
calculator.add(2);
Assert.assertEquals(calculator.getResult(), 2);
}
@Test
public void testPower() {
final Calculator calculator = new Calculator(2);
calculator.power(3);
Assert.assertEquals(calculator.getResult(), 8);
}
/*
@Test
public void testSubtraction() {
final Calculator calculator = new Calculator(5);
calculator.subtract(4);
Assert.assertEquals(calculator.getResult(), 1);
}
*/
@Test
public void testConditionalSetTrue() {
final Calculator calculator = new Calculator();
Assert.assertEquals(calculator.setConditional(2, true), true);
// Assert.assertEquals(calculator.getResult(), 2);
}
@Test
public void testConditionalSetFalse() {
final Calculator calculator = new Calculator();
Assert.assertEquals(calculator.setConditional(3, false), false);
// Assert.assertEquals(calculator.getResult(), 0);
}
Po dokončení testov sa zdá, že je všetko v poriadku. Všetky testy sú „zelené“, čiže v poriadku.

pri dôkladnejšom pohľade ale zistíme, že:
- „Subtraction method“ nie je zahrnutá do testov
- Metóda “setConditional” robí dve operácie súčasne. Nastavuje premennú “valueDisplayed” a jej návratová hodnota je boolean. Nastavenie premennej tiež nie je testom pokryté (weak test)
Ideálny príklad pre test Unit testov použitím mutačného testovania.
Detekcia nepokrytých a weak testov pomocou PIT frameworku
Použitím PIT – real world mutation testing, vývojári majú možnosť rýchlo a ľahko odhaliť „weak test“ a zároveň zobraziť riadky nepokryté unit testom. Pozrime si teda PIT report:


Ako na to? Ako použiť PIT framework v projekte pripravenom pre maven
pom.xml
<build>
<plugins>
<plugin>
<groupId>org.pitest</groupId>
<artifactId>pitest-maven</artifactId>
<version>1.1.4</version>
<configuration>
<targetClasses>
<param>package.root.containing.classes.to.mutate*</param>
</targetClasses>
<targetTests>
<param>package.root.containing.test.classes*</param>
</targetTests>
</configuration>
</plugin>
</plugins>
</build>
maven spustíme riadkovým príkazom:
- mvn org.pitest:pitest-maven:mutationCoverage
alebo vytvoríme „run configuration“ v Eclipse:

PIT report potom nájdeme v rámci projektu v adresári /target/pit-reports/<date>/index.html




