В этой статье мы покажем вам, как использовать плагин для тестирования мутаций 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/”