49
ТЕСТИРУЕМ ТЕСТЫ С PIT 15 сентября 2016

Тестируем тесты с PIT (мутационное тестирование)

Embed Size (px)

Citation preview

Page 1: Тестируем тесты с PIT (мутационное тестирование)

ТЕСТИРУЕМТЕСТЫС PIT

15 сентября 2016

Page 2: Тестируем тесты с PIT (мутационное тестирование)

Кто я?Евгений Барановский

Я здесь, потому что люблю Java, качественный код и спокойствие.

Связаться со мной меня можно через [email protected].

Page 3: Тестируем тесты с PIT (мутационное тестирование)

План выступления

▷Текущие ограничения тестов

▷Мутационное тестирование

▷Мутационное тестирование с PIT

▷Проблемы мутационного

тестирования

▷Будет много кода

Page 4: Тестируем тесты с PIT (мутационное тестирование)

РАССМОТРИМ ПРИМЕРНет ничего лучше примера

Page 5: Тестируем тесты с PIT (мутационное тестирование)

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......}

Page 6: Тестируем тесты с PIT (мутационное тестирование)

public class TimeLineTest {

private TimeLine timeLine;

@BeforeMethodprotected void setUp() {

timeLine = new TimeLine(10);}

@Testpublic void shouldUpdateFetchCount() {

int expected = 5;timeLine.setFetchCount(expected);

assertEquals(timeLine.getFetchCount(), expected);}

@Test(expectedExceptions = IllegalArgumentException.class)public void shouldNotAllowNegativeFetchCount() {

timeLine.setFetchCount(-10);}

}

Page 7: Тестируем тесты с PIT (мутационное тестирование)
Page 8: Тестируем тесты с PIT (мутационное тестирование)

Что же не так страдиционнымтестированием?

Page 9: Тестируем тесты с PIT (мутационное тестирование)

Уберем вызов

Page 10: Тестируем тесты с PIT (мутационное тестирование)

▷Успешно прошедшие тесты не

всегда правы.

▷Существует много критериев

покрытия кода.

▷И даже эти критерии могут быть

неточными.

Текущие ограничения

Page 11: Тестируем тесты с PIT (мутационное тестирование)

Это искусственный баг. Если набор тестов не в состоянии обнаружить мутацию, то он рассматривается как недостаточный.

Мутация

Page 12: Тестируем тесты с PIT (мутационное тестирование)

Мутант – это система с мутациями.

Мутант

Page 13: Тестируем тесты с PIT (мутационное тестирование)

в 1970х

Причины низкой популярности:– недостаток технологий и– недостаток вычислительных мощностей.

Мутационное тестированиебыло разработано еще

Page 14: Тестируем тесты с PIT (мутационное тестирование)

Итак, как работает мутационное тестирование?

1. Написать тест

2. Выбрать мутации

3. Получить мутантов

4. Прогнать тесты на мутантах

5. Пересмотреть тесты

6. Прогнать тесты снова

Page 15: Тестируем тесты с PIT (мутационное тестирование)

Итак, как работает мутационное тестирование?

2. Выбрать мутации

3. Получить мутантов

4. Прогнать тесты на мутантах

5. Пересмотреть тесты

6. Прогнать тесты снова

1. Написать тест

Page 16: Тестируем тесты с PIT (мутационное тестирование)

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}

Page 17: Тестируем тесты с PIT (мутационное тестирование)

... напишем такой тест@BeforeMethodprotected void setUp() {

timeLine = new TimeLine(10);}

@Testpublic void shouldUpdateFetchCount() {

int expected = 5;timeLine.setFetchCount(expected);

assertEquals(timeLine.getFetchCount(), expected);}

@Test(expectedExceptions = IllegalArgumentException.class)public void shouldNotAllowNegativeFetchCount() {

timeLine.setFetchCount(-10);}

Page 18: Тестируем тесты с PIT (мутационное тестирование)

Итак, как работает мутационное тестирование?

1. Написать тест

3. Получить мутантов

4. Прогнать тесты на мутантах

5. Пересмотреть тесты

6. Прогнать тесты снова

2. Выбрать мутации

Page 19: Тестируем тесты с PIT (мутационное тестирование)

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}

Можно удалить вызов

Можно инвертировать условие

Можно изменить границу условия

Page 20: Тестируем тесты с PIT (мутационное тестирование)

Итак, как работает мутационное тестирование?

1. Написать тест

2. Выбрать мутации

4. Прогнать тесты на мутантах

5. Пересмотреть тесты

6. Прогнать тесты снова

3. Получить мутантов

Page 21: Тестируем тесты с PIT (мутационное тестирование)

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) {}

Page 22: Тестируем тесты с PIT (мутационное тестирование)

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) {

Page 23: Тестируем тесты с PIT (мутационное тестирование)

Итак, как работает мутационное тестирование?

1. Написать тест

2. Выбрать мутации

3. Получить мутантов

5. Пересмотреть тесты

6. Прогнать тесты снова

4. Прогнать тесты на мутантах

Page 24: Тестируем тесты с PIT (мутационное тестирование)

4. Прогнать тесты на мутантах

Не покрыто... Как так-то?

Page 25: Тестируем тесты с PIT (мутационное тестирование)

Итак, как работает мутационное тестирование?

1. Написать тест

2. Выбрать мутации

3. Получить мутантов

4. Прогнать тесты на мутантах

6. Прогнать тесты снова

5. Пересмотреть тесты

Page 26: Тестируем тесты с PIT (мутационное тестирование)

5. Пересмотреть тесты@BeforeMethodprotected void setUp() {

timeLine = new TimeLine(10);}

@Testpublic void shouldSetTheConstructorFetchValue() {

assertEquals(timeLine.getFetchCount(), 10);}

@Testpublic void shouldUpdateFetchCount() {

int expected = 5;timeLine.setFetchCount(expected);

assertEquals(timeLine.getFetchCount(), expected);}

@Test(expectedExceptions = IllegalArgumentException.class)public void shouldNotAllowNegativeFetchCount() {

timeLine.setFetchCount(-10);}

Page 27: Тестируем тесты с PIT (мутационное тестирование)

Итак, как работает мутационное тестирование?

1. Написать тест

2. Выбрать мутации

3. Получить мутантов

4. Прогнать тесты на мутантах

5. Пересмотреть тесты

6. Прогнать тесты снова

Page 28: Тестируем тесты с PIT (мутационное тестирование)

6. Прогнать тесты снова

Page 29: Тестируем тесты с PIT (мутационное тестирование)

Мутационное тестирование

1. Написать тестПросто пишем обычные тесты безо всяких предположений о том, что будет дальше.

2. Выбрать мутацииКод автоматически анализируется и к нему подбираются мутации.

3. Получить мутантовЗвучит зловеще, но это тоже происходит автоматически.

4. Прогнать тесты на мутантахНикаких дополнительных действий от программиста тут не требуется – не зря же мы писали тесты на самом первом шаге.

5. Пересмотреть тесты

Если мы получили ошибки, либо имеющиеся тесты, либо настройки мутаций надо пересмотреть.

6. Прогнать тесты снова

Запустить мутационное тестирование снова, но уже с исправленными тестами/конфигурацией.

Page 30: Тестируем тесты с PIT (мутационное тестирование)

ИНСТРУМЕНТЫПочему PIT?

Page 31: Тестируем тесты с PIT (мутационное тестирование)

Jester

Nester

Pester

PIT

Page 32: Тестируем тесты с PIT (мутационное тестирование)

БАЙТ-КОД– Работает напрямую с байт-кодом.

ДОКУМЕНТАЦИЯ– Хорошая документация + открытый код.– http://www.pitest.org + GitHub

ПРОСТОТА– Подсчитывает обычное покрытие строк.– Поддерживает различные оптимизации.

PIT

Page 33: Тестируем тесты с PIT (мутационное тестирование)
Page 34: Тестируем тесты с PIT (мутационное тестирование)
Page 35: Тестируем тесты с PIT (мутационное тестирование)

PIT – Пример отчета

Page 36: Тестируем тесты с PIT (мутационное тестирование)

PIT – Пример отчета

Page 37: Тестируем тесты с PIT (мутационное тестирование)

PIT – Пример отчета

Page 38: Тестируем тесты с PIT (мутационное тестирование)

PIT – Пример отчета

Page 39: Тестируем тесты с PIT (мутационное тестирование)

PIT – Пример отчета

Page 40: Тестируем тесты с PIT (мутационное тестирование)

▷Стабильные:

– простые,

– но эффективные.

▷Нестабильные:

– мощные,

– но чреваты ошибками.

PIT – Виды мутаций

Page 41: Тестируем тесты с PIT (мутационное тестирование)

▷Изменение граничных условий

PIT – Стабильные мутации

if (a < b) {// if (a <= b)// do something

}

Page 42: Тестируем тесты с PIT (мутационное тестирование)

▷Изменение граничных условий

▷Инверсия условий

PIT – Стабильные мутации

if (a == b) {// if (a != b)// do something

}

Page 43: Тестируем тесты с PIT (мутационное тестирование)

▷Изменение граничных условий

▷Инверсия условий

▷Инверсия операторов

PIT – Стабильные мутации

if (a >>> b) {// if (a << b)// do something

}

Page 44: Тестируем тесты с PIT (мутационное тестирование)

▷Удаление условий

PIT – Нестабильные мутации

if (a == b) {// if (true)// do something

}

Page 45: Тестируем тесты с PIT (мутационное тестирование)

▷Удаление условий

▷Удаление вызова конструктора

PIT – Нестабильные мутации

public int foo() {// Object o = null;Object o = new Object();return o;

}

Page 46: Тестируем тесты с PIT (мутационное тестирование)

▷Maven

▷Gradle

▷SonarQube

PIT – Интеграция со сборкой

Page 47: Тестируем тесты с PIT (мутационное тестирование)

▷Правильно настраивать плагины

сборки.

▷Избегать сгенерированных

классов (например, JAXB).

▷Избегать конфликтов со

смежными инструментами

(например, Clover, Cobertura).

С PIT нужно:

Page 48: Тестируем тесты с PIT (мутационное тестирование)

▷Может занимать много времени

▷Сложней реализовать

▷Трудно применить к тестам

уровнем выше интеграционных

Проблемы мутационного тестирования

Page 49: Тестируем тесты с PIT (мутационное тестирование)

Спасибо за внимание!Вопросы?