Презентация подготовлена по материалам выступления Евгения Барановского на витебском Dev Day MiniQ (https://vk.com/devdayminiq), который был проведен 15 сентября 2016.
2. Кто я?
Евгений Барановский
Я здесь, потому что люблю Java,
качественный код и спокойствие.
Связаться со мной меня можно
через judzin.baranovsky@gmail.com.
3. План выступления
▷Текущие ограничения тестов
▷Мутационное тестирование
▷Мутационное тестирование с PIT
▷Проблемы мутационного
тестирования
▷Будет много кода
5. public class TimeLine {
private int fetchCount;
public TimeLine(int fetchCount) {
setFetchCount(fetchCount);
}
public void setFetchCount(int fetchCount) {
if (fetchCount <= 0) {
throw new IllegalArgumentException("Count must be > 0");
}
this.fetchCount = fetchCount;
}
public int getFetchCount() {
return fetchCount;
}
// Some service logic, omitted for simplicity......
}
6. public class TimeLineTest {
private TimeLine timeLine;
@BeforeMethod
protected void setUp() {
timeLine = new TimeLine(10);
}
@Test
public void shouldUpdateFetchCount() {
int expected = 5;
timeLine.setFetchCount(expected);
assertEquals(timeLine.getFetchCount(), expected);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void shouldNotAllowNegativeFetchCount() {
timeLine.setFetchCount(-10);
}
}
10. ▷Успешно прошедшие тесты не
всегда правы.
▷Существует много критериев
покрытия кода.
▷И даже эти критерии могут быть
неточными.
Текущие ограничения
11. Это искусственный баг. Если набор тестов не
в состоянии обнаружить мутацию, то он
рассматривается как недостаточный.
Мутация
13. в 1970х
Причины низкой популярности:
– недостаток технологий и
– недостаток вычислительных мощностей.
Мутационное тестирование
было разработано еще
14. Итак, как работает
мутационное тестирование?
1. Написать тест
2. Выбрать мутации
3. Получить мутантов
4. Прогнать тесты на мутантах
5. Пересмотреть тесты
6. Прогнать тесты снова
15. Итак, как работает
мутационное тестирование?
2. Выбрать мутации
3. Получить мутантов
4. Прогнать тесты на мутантах
5. Пересмотреть тесты
6. Прогнать тесты снова
1. Написать тест
16. 1. Для знакомого класса ...
public class TimeLine {
private int fetchCount;
public TimeLine(int fetchCount) {
setFetchCount(fetchCount);
}
public void setFetchCount(int fetchCount) {
if (fetchCount <= 0) {
throw new IllegalArgumentException("Count must be > 0");
}
this.fetchCount = fetchCount;
}
public int getFetchCount() {
return fetchCount;
}
// Some service logic
}
17. ... напишем такой тест
@BeforeMethod
protected void setUp() {
timeLine = new TimeLine(10);
}
@Test
public void shouldUpdateFetchCount() {
int expected = 5;
timeLine.setFetchCount(expected);
assertEquals(timeLine.getFetchCount(), expected);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void shouldNotAllowNegativeFetchCount() {
timeLine.setFetchCount(-10);
}
18. Итак, как работает
мутационное тестирование?
1. Написать тест
3. Получить мутантов
4. Прогнать тесты на мутантах
5. Пересмотреть тесты
6. Прогнать тесты снова
2. Выбрать мутации
19. 2. Выбрать мутации для кода
public class TimeLine {
private int fetchCount;
public TimeLine(int fetchCount) {
setFetchCount(fetchCount);
}
public void setFetchCount(int fetchCount) {
if (fetchCount <= 0) {
throw new IllegalArgumentException("Count must be > 0");
}
this.fetchCount = fetchCount;
}
public int getFetchCount() {
return fetchCount;
}
// Some service logic
}
Можно удалить вызов
Можно инвертировать
условие
Можно изменить границу
условия
20. Итак, как работает
мутационное тестирование?
1. Написать тест
2. Выбрать мутации
4. Прогнать тесты на мутантах
5. Пересмотреть тесты
6. Прогнать тесты снова
3. Получить мутантов
21. 3. Получить мутантов системы
public class TimeLine {
private int fetchCount;
public TimeLine(int fetchCount) {
setFetchCount(fetchCount);
}
public void setFetchCount(int fetchCount) {
if (fetchCount <= 0) {
throw new IllegalArgumentException("Count must be > 0");
}
this.fetchCount = fetchCount;
}
public int getFetchCount() {
return fetchCount;
}
// Some service logic
}
public TimeLine(int fetchCount) {
}
22. 3. Получить мутантов системы
public class TimeLine {
private int fetchCount;
public TimeLine(int fetchCount) {
setFetchCount(fetchCount);
}
public void setFetchCount(int fetchCount) {
if (fetchCount <= 0) {
throw new IllegalArgumentException("Count must be > 0");
}
this.fetchCount = fetchCount;
}
public int getFetchCount() {
return fetchCount;
}
// Some service logic
}
if (fetchCount < 0) {
if (fetchCount > 0) {
23. Итак, как работает
мутационное тестирование?
1. Написать тест
2. Выбрать мутации
3. Получить мутантов
5. Пересмотреть тесты
6. Прогнать тесты снова
4. Прогнать тесты на мутантах
25. Итак, как работает
мутационное тестирование?
1. Написать тест
2. Выбрать мутации
3. Получить мутантов
4. Прогнать тесты на мутантах
6. Прогнать тесты снова
5. Пересмотреть тесты
26. 5. Пересмотреть тесты
@BeforeMethod
protected void setUp() {
timeLine = new TimeLine(10);
}
@Test
public void shouldSetTheConstructorFetchValue() {
assertEquals(timeLine.getFetchCount(), 10);
}
@Test
public void shouldUpdateFetchCount() {
int expected = 5;
timeLine.setFetchCount(expected);
assertEquals(timeLine.getFetchCount(), expected);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void shouldNotAllowNegativeFetchCount() {
timeLine.setFetchCount(-10);
}
27. Итак, как работает
мутационное тестирование?
1. Написать тест
2. Выбрать мутации
3. Получить мутантов
4. Прогнать тесты на мутантах
5. Пересмотреть тесты
6. Прогнать тесты снова
29. Мутационное тестирование
1. Написать тест
Просто пишем обычные тесты
безо всяких предположений о
том, что будет дальше.
2. Выбрать мутации
Код автоматически
анализируется и к нему
подбираются мутации.
3. Получить мутантов
Звучит зловеще, но это тоже
происходит автоматически.
4. Прогнать тесты на
мутантах
Никаких дополнительных
действий от программиста тут
не требуется – не зря же мы
писали тесты на самом первом
шаге.
5. Пересмотреть тесты
Если мы получили ошибки,
либо имеющиеся тесты, либо
настройки мутаций надо
пересмотреть.
6. Прогнать тесты снова
Запустить мутационное
тестирование снова, но уже с
исправленными
тестами/конфигурацией.
45. ▷Удаление условий
▷Удаление вызова конструктора
PIT – Нестабильные мутации
public int foo() {
// Object o = null;
Object o = new Object();
return o;
}