В этой статье мы покажем вам, как использовать плагин для тестирования мутаций Maven PIT для создания отчета о покрытии тестов на мутации для проекта Java.
Протестировано с
- Мавен 3.5.3
- Юнит 5.3.1
- Питест 1.4.3
1. Быстрый – Плагин Maven PITest
1.1 Чтобы включить тестирование на мутацию PIT, выполните это pitest-maven в pom.xml
org.pitest pitest-maven 1.4.3 pit-report test mutationCoverage org.pitest pitest-junit5-plugin 0.8 com.mkyong.examples.* com.mkyong.examples.*
1.2 Запустите PITest вручную.
$ mvn clean org.pitest:pitest-maven:mutationCoverage
1.3 Выше pom.xml файл прикрепил цель “охват мутациями” к этапу тестирования Maven. Теперь, когда мы запустим тест Maven, он автоматически запустит самый неудачный тест.
$ mvn clean test
1.4 Отчет будет сгенерирован в target/pit-отчеты/ГГГГМДДХХМИ/*
2. Что такое Тестирование на мутации
2.1 Тестирование на мутации используется для измерения эффективности теста.
В тестировании на мутации будут использоваться мутаторы (переключение математических операторов, изменение типа возвращаемого значения, удаление вызова и т. Д.), Чтобы мутировать/изменять код в разные мутации (создавать новый код на основе мутаторов) и проверять, не завершится ли модульный тест для новых мутаций (мутация убита).
Эффективность тестов может быть мерой того, сколько мутаций уничтожено.
2.2 Например, этот код:
public boolean isPositive(int number) {
boolean result = false;
if (number >= 0) {
result = true;
}
return result;
}
По умолчанию PITest будет использовать разные мутаторы для преобразования вышеуказанного кода в разные мутации (новый код):
Мутация № 1 – Измененная условная граница (мутатор)
public boolean isPositive(int number) {
boolean result = false;
// mutator - changed conditional boundary
if (number > 0) {
result = true;
}
return result;
}
Мутация № 2 – Отрицаемый условный (мутатор)
public boolean isPositive(int number) {
boolean result = false;
// mutator - negated conditional
if (false) {
result = true;
}
return result;
}
#3 Мутация – Заменено возвращаемое значение целого размера на (x?1:0) (мутатор)
public boolean isPositive(int number) {
boolean result = false;
if (number > 0) {
result = true;
}
// mutator - (x == 0 ? 1 : 0)
return !result;
}
2.3 Хороший модульный тест должен провалиться (убить) все мутации # 1, #2, #3.
@Test
public void testPositive() {
CalculatorService obj = new CalculatorService();
assertEquals(true, obj.isPositive(10));
}
Приведенный выше модульный тест уничтожит мутации № 2 и № 3 (модульный тест не пройден), но мутация № 1 выживет (модульный тест пройден).
2.4 Еще раз просмотрите мутацию № 1. Чтобы провалить (убить) этот тест (мутацию), мы должны проверить условную границу, число ноль.
public boolean isPositive(int number) {
boolean result = false;
// mutator - changed conditional boundary
if (number > 0) {
result = true;
}
return result;
}
Улучшение модульного теста путем тестирования нулевого числа.
@Test
public void testPositive() {
CalculatorService obj = new CalculatorService();
assertEquals(true, obj.isPositive(10));
//kill mutation #1
assertEquals(true, obj.isPositive(0));
}
Готово, теперь 100 % покрытие мутаций.
3. Maven + самый жалкий пример
Еще один полный пример Maven + PITest, просто для справки.
3.1 A полный pom.xml
4.0.0 com.mkyong.examples maven-mutation-testing jar 1.0-SNAPSHOT UTF-8 1.8 1.8 5.3.1 1.4.3 org.junit.jupiter junit-jupiter-engine ${junit.version} test maven-mutation-testing org.apache.maven.plugins maven-surefire-plugin 3.0.0-M1 org.pitest pitest-maven ${pitest.version} pit-report test mutationCoverage org.pitest pitest-junit5-plugin 0.8 com.mkyong.examples.* com.mkyong.examples.*
3.2 Исходный код
package com.mkyong.examples;
public class StockService {
private int qtyOnHand;
public StockService(int qtyOnHand) {
this.qtyOnHand = qtyOnHand;
}
private void isValidQty(int qty) {
if (qty < 0) {
throw new IllegalArgumentException("Quality should be positive!");
}
}
public int add(int qty) {
isValidQty(qty);
qtyOnHand = qtyOnHand + qty;
return qtyOnHand;
}
public int deduct(int qty) {
isValidQty(qty);
int newQty = qtyOnHand - qty;
if (newQty < 0) {
throw new IllegalArgumentException("Out of Stock!");
} else {
qtyOnHand = newQty;
}
return qtyOnHand;
}
}
3.3 Ниже модульный тест уничтожит все мутации, которые генерируются PItest.
package com.mkyong.examples;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class TestStockService {
@DisplayName("Test deduct stock")
@Test
public void testDeduct() {
StockService obj = new StockService(100);
assertEquals(90, obj.deduct(10));
assertEquals(0, obj.deduct(90));
assertEquals(0, obj.deduct(0));
Assertions.assertThrows(IllegalArgumentException.class, () -> {
obj.deduct(-1);
});
Assertions.assertThrows(IllegalArgumentException.class, () -> {
obj.deduct(100);
});
}
@DisplayName("Test add stock")
@Test
public void testAdd() {
StockService obj = new StockService(100);
assertEquals(110, obj.add(10));
assertEquals(110, obj.add(0));
Assertions.assertThrows(IllegalArgumentException.class, () -> {
obj.add(-1);
});
}
}
3.4 Запустите его.
$ mvn clean org.pitest:pitest-maven:mutationCoverage #or $ mvn clean test
3.5 Просмотрите отчет по адресу target\pit-отчеты\${ГГГГММДДХХМИ}\index.html
4. Часто задаваемые вопросы
4.1 Изучите Самые опасные мутаторы , чтобы мы поняли, как генерируется мутация.
4.2 Это тестирование на мутацию является трудоемкой задачей, всегда объявляются классы, необходимые для теста на мутацию.
org.pitest pitest-maven ${pitest.version} com.mkyong.examples.*Calculator* com.mkyong.examples.*Stock* com.mkyong.examples.*
Скачать Исходный Код
$$mvn чистая организация.pitest: pitest-maven: охват мутациями #или $mvn чистый тест
# просмотреть отчет по адресу target/pit-reports/YYYYMMDDHHMI/index.html
Рекомендации
- Тестирование на мутацию PITest
- Википедия – Тестирование на мутации
- Пример покрытия кода Maven –JaCoCo
Оригинал: “https://mkyong.com/maven/maven-pitest-mutation-testing-example/”