Слайд 1Мутационное тестирование
STRYKER.JS
Варпахович Кирилл Николаевич
Ведущий FrontEnd Разработчик
Tinkoff.ru
Слайд 2О чём поговорим?
Уровни тестирования
Взросление продукта
Взросление бизнеса
Что такое мутационное тестирование
Как начать
работать с Stryker
Подводные камни, которые мы поймали
Слайд 3Типы тестирования
* по уровню
Слайд 4Типы тестирования (по уровню)
Как вы тестируете ваше приложение?
Мы пишем юнит
тесты.
Какие?
Я же сказал - юнит!
Слайд 5Типы тестирования (по уровню)
Как вы тестируете ваше приложение?
Мы пишем юнит
тесты.
Какие?
Я же сказал - юнит!
Слайд 6Типы тестирования (по уровню)
Слайд 7Типы тестирования (по уровню)
Системное тестирование
(сценарии использования и т.д.)
Системное тестирование
проверяют выполнение
бизнес-функций (требований) системы.
проверяет сценарии работы пользователя в системе
есть много видов
Слайд 8Типы тестирования (по уровню)
Системное тестирование
(сценарии использования и т.д.)
Тестирование интеграционное
(проверяем результат
внешних эффектов)
Тестирование интеграционное
проверяем изменения после взаимодейсвтия компонент
проверяем технические сценарии взаимодейсвтия
компонент
Слайд 9Типы тестирования (по уровню)
Тестирование компоненты
(проверяем наличие внешних эффектов, проверяем результат
внешних изменений)
Системное тестирование
(сценарии использования и т.д.)
Тестирование интеграционное
(проверяем результат внешних эффектов)
Тестирование
компоненты
Проверяем что вызываются внешние функции/сущности
Проверяем обработку запросов на изменение извне
Дёргаем внешнее API компоненты
Слайд 10Типы тестирования (по уровню)
Тестирование компоненты
(проверяем наличие внешних эффектов, проверяем результат
внешних изменений)
Тетирование функций
(не важны любые эффекты, только результат функции)
Тестирование модулей
(проверяем
внутренние эффекты)
Системное тестирование
(сценарии использования и т.д.)
Тестирование интеграционное
(проверяем результат внешних эффектов)
Тестирование модулей
Проверяем нечистые функции
Проверяем функции, которые должны менять состояние модуля
Проверяем, что чистые функции не меняют состояние модуля
Слайд 11Типы тестирования (по уровню)
Тестирование компоненты
(проверяем наличие внешних эффектов, проверяем результат
внешних изменений)
Тестирование функций
(не важны любые эффекты, только результат функции)
Тестирование модулей
(проверяем
внутренние эффекты)
Системное тестирование
(сценарии использования и т.д.)
Тестирование интеграционное
(проверяем результат внешних эффектов)
Тестирование функций
Проверяем результат чистых функций
Проверяем результат не чистых функций на разных входных парамтерах
Не проверяем изменение состояния сущности
Слайд 12Типы тестирования (по уровню)
Тестирование компоненты
(проверяем наличие внешних эффектов, проверяем результат
внешних изменений)
Тестирование функций
(не важны любые эффекты, только результат функции)
Тестирование модулей
(проверяем
внутренние эффекты)
Системное тестирование
(сценарии использования и т.д.)
Тестирование интеграционное
(проверяем результат внешних эффектов)
Это всё
Unit-тестирование
Слайд 13Когда тесты нужны бизнесу?
Этапы взросления
Слайд 14Взросление бизнеса
Команда
Идея
Средства
Этап 1
Собственные
Прототип
Рынок
Слайд 15Взросление бизнеса
Фирма
Прототип
Капитал
Этап 2
Деньги
Инвесторы
Рынок
Продукт
Прибыль
Слайд 16Взросление бизнеса
Этап 3
Кампания
Продукт
Капитал
Деньги
Инвесторы
Рынок
Нишевые
предложения
Прибыль
Слайд 17Взросление продукта
Идея
Concept
Прототип
Proof of concept
Опытный образец
Minimal viable product
Работоспособный продукт
Market Product
Специальный продукт
Проверка
востребованности
Проверка осуществимости
Демонстрация возможностей
Демонстрация жизнеспособности
Максимизация прибыли
Укоренение в рынке
Обеспечение стабильности
Слайд 18Взросление продукта
Идея
Concept
Прототип
Proof of concept
Опытный образец
Minimal viable product
Работоспособный продукт
Market Product
Специальный продукт
Проверка
востребованности
Проверка осуществимости
Демонстрация возможностей
Демонстрация жизнеспособности
Максимизация прибыли
Укоренение в рынке
Обеспечение стабильности
Слайд 19Взросление продукта
Идея
Concept
Прототип
Proof of concept
Опытный образец
Minimal viable product
Работоспособный продукт
Market Product
Специальный продукт
Проверка
востребованности
Проверка осуществимости
Демонстрация возможностей
Демонстрация жизнеспособности
Максимизация прибыли
Укоренение в рынке
Обеспечение стабильности
Слайд 20Взросление продукта
Идея
Concept
Прототип
Proof of concept
Опытный образец
Minimal viable product
Работоспособный продукт
Market Product
Специальный продукт
Проверка
востребованности
Проверка осуществимости
Демонстрация возможностей
Демонстрация жизнеспособности
Максимизация прибыли
Укоренение в рынке
Обеспечение стабильности
Слайд 21Взросление продукта
Идея
Concept
Прототип
Proof of concept
Опытный образец
Minimal viable product
Работоспособный продукт
Market Product
Специальный продукт
Проверка
востребованности
Проверка осуществимости
Демонстрация возможностей
Демонстрация жизнеспособности
Максимизация прибыли
Укоренение в рынке
Обеспечение стабильности
Слайд 22Взросление продукта
Растёт потребность в стабильности
Растёт потребность в качестве тестов
Идея
Concept
Прототип
Proof of
concept
Опытный образец
Minimal viable product
Работоспособный продукт
Market Product
Специальный продукт
Проверка востребованности
Проверка осуществимости
Демонстрация возможностей
Демонстрация
жизнеспособности
Максимизация прибыли
Укоренение в рынке
Обеспечение стабильности
Слайд 23Бизнес готов
Тесты пишутся
Что дальше?
Слайд 24Качество тестирования
Идея
Concept
Прототип
Proof of concept
Опытный образец
Minimal viable product
Работоспособный продукт
Market Product
Специальный продукт
Проверка
востребованности
Проверка осуществимости
Демонстрация возможностей
Демонстрация жизнеспособности
Максимизация прибыли
Укоренение в рынке
Обеспечение стабильности
Растёт потребность в
стабильности
Растёт потребность в качестве тестов
Слайд 26Качество тестирования
Цели:
Повышаем качество тестов
Удаляем бесполезные тесты
Повышаем качество кода
Попутно улучшаем архитектуру,
отказоустойчивость и т.д.
Слайд 27Качество тестирования
Stryker:
C#
Scala
Javascript/Typescript
React
Angular
Native
Слайд 28Качество тестирования
Stryker:
C#
Scala
Javascript/Typescript
React
Angular
Native
Слайд 30Getting started…
(немного чёрных экранов)
Слайд 31Stryker.js
npm install -g stryker-cli
npm install -D stryker-cli
Слайд 32Stryker.js
npm install -g stryker-cli
npm install --save-dev @stryker-mutator/core
npm install -g stryker-cli
npm
install --save-dev @stryker-mutator/html-reporter
npm install --save-dev @stryker-mutator/typescript
npm install --save-dev @stryker-mutator/jest-runner
Слайд 33Stryker.js
npm install -g stryker-cli
npm install --save-dev @stryker-mutator/core
stryker init
npm install -g
stryker-cli
npm install --save-dev @stryker-mutator/html-reporter
npm install --save-dev @stryker-mutator/typescript
npm install --save-dev @stryker-mutator/jest-runner
Слайд 34Stryker.js
npm install -g stryker-cli
npm install --save-dev @stryker-mutator/core
stryker init
npm install -g
stryker-cli
npm install --save-dev @stryker-mutator/html-reporter
npm install --save-dev @stryker-mutator/typescript
npm install --save-dev @stryker-mutator/jest-runner
stryker
run
Слайд 36Stryker.js
module.exports = function(config) {
config.set({
...
});
};
stryker.conf.js
Слайд 37Stryker.js
module.exports = function(config) {
config.set({
...
mutator: "typescript",
testRunner: "jest",
jest: {
configFile: "jest.conf.js",
projectType: "angular-cli",
},
});
};
stryker.conf.js
Слайд 38Stryker.js
module.exports = function(config) {
config.set({
...
reporters: [
"progress",
"clear-text",
"html"
],
htmlReporter: {
baseDir: 'reports/mutation/html'
},
});
};
stryker.conf.js
Слайд 39Stryker.js
module.exports = function(config) {
config.set({
...
maxConcurrentTestRunners: 4,
// Recommended
to use about half of your available cores when running stryker with angular.
});
};
stryker.conf.js
Слайд 40Stryker.js
module.exports = function(config) {
config.set({
...
maxConcurrentTestRunners: 4,
// Recommended
to use about half of your available cores when running stryker with angular.
});
};
stryker.conf.js
Слайд 41Stryker.js
module.exports = function(config) {
config.set({
mutate:
[
"src/**/*.ts",
"!src/**/*.spec.ts",
"!src/**/*.module.ts",
"!src/app/test/**/*.ts",
"!src/**/*.routing.ts"
],
});
};
stryker.conf.js
Слайд 42Stryker.js
> stryker run
> INFO ConfigReader Using stryker.conf.js in the current
working directory.
> INFO InputFileResolver Found 992 of 2002 file(s) to
be mutated.
> INFO InitialTestExecutor Starting initial test run. This may take a while.
> INFO InitialTestExecutor Initial test run succeeded. Ran 1170 tests in 2 minutes 45 seconds (net 54338 ms, overhead 65737 ms).
> INFO MutatorFacade 12094 Mutant(s) generated
> INFO SandboxPool Creating 4 test runners (based on maxConcurrentTestRunners config)
Слайд 43Stryker.js
> stryker run
> INFO ConfigReader Using stryker.conf.js in the current
working directory.
> INFO InputFileResolver Found 992 of 2002 file(s) to
be mutated.
> INFO InitialTestExecutor Starting initial test run. This may take a while.
> INFO InitialTestExecutor Initial test run succeeded. Ran 1170 tests in 2 minutes 45 seconds (net 54338 ms, overhead 65737 ms).
> INFO MutatorFacade 12094 Mutant(s) generated
> INFO SandboxPool Creating 4 test runners (based on maxConcurrentTestRunners config)
Слайд 44Stryker.js
> stryker run
> INFO ConfigReader Using stryker.conf.js in the current
working directory.
> INFO InputFileResolver Found 992 of 2002 file(s) to
be mutated.
> INFO InitialTestExecutor Starting initial test run. This may take a while.
Слайд 45Stryker.js
> stryker run
> INFO ConfigReader Using stryker.conf.js in the current
working directory.
> INFO InputFileResolver Found 992 of 2002 file(s) to
be mutated.
> INFO InitialTestExecutor Starting initial test run. This may take a while.
> INFO InitialTestExecutor Initial test run succeeded. Ran 1170 tests in 2 minutes 45 seconds (net 54338 ms, overhead 65737 ms).
> INFO MutatorFacade 12094 Mutant(s) generated
> INFO SandboxPool Creating 4 test runners (based on maxConcurrentTestRunners config)
-----------------------------|---------|----------|-----------|------------|----------|---------|
File | % score | # killed | # timeout | # survived | # no cov | # error |
-----------------------------|---------|----------|-----------|------------|----------|---------|
All files | 0.00 | 0 | 0 | 12094 | 0 | 0 |
call-step-form.component.ts | 0.00 | 0 | 0 | 11 | 0 | 0 |
... | 0.00 | 0 | 0 | ... | 0 | 0 |
-----------------------------|---------|----------|-----------|------------|----------|---------|
> INFO HtmlReporter Your report can be found at: file:///.../reports/mutation/html/index.html
> INFO Stryker Done in 6 hours 11 minutes.
Слайд 46Stryker.js
Done in 6 hours 11 minutes
Слайд 47Stryker.js
-----------------------------|---------|----------|-----------|------------|----------|---------|
File
| % score | # killed |
# timeout | # survived | # no cov | # error |
-----------------------------|---------|----------|-----------|------------|----------|---------|
All files | 0.00 | 0 | 0 | 12094 | 0 | 0 |
call-step-form.component.ts | 0.00 | 0 | 0 | 11 | 0 | 0 |
... | 0.00 | 0 | 0 | ... | 0 | 0 |
-----------------------------|---------|----------|-----------|------------|----------|---------|
https://github.com/stryker-mutator/stryker-handbook/blob/master/mutant-states-and-metrics.md
перцентиль
циферъ
умерло от безысходности
этих даже не искали
живее всех живых
эти поломали нам систему
Слайд 48Stryker.js
htmlReporter: { baseDir: 'reports/mutation/html' },
Слайд 49Stryker.js
htmlReporter: { baseDir: 'reports/mutation/html' },
Слайд 51Особенности
Очень много времени на анализ результатов
Можно настроить запуск на конкретные
файлы вручную
Слайд 52Особенности
Очень много времени на анализ результатов
Можно настроить запуск на конкретные
файлы вручную
1 мутация !== 1 прогон
:(
Слайд 53Особенности
Очень много времени на анализ результатов
Можно настроить запуск на конкретные
файлы вручную
1 мутация !== 1 прогон
:(
Слайд 54Особенности
Очень много времени на анализ результатов
Можно настроить запуск на конкретные
файлы вручную
1 мутация !== 1 прогон
:(
1 точка в коде почти
всегда 1 мутация
Для условий и математики количество мутаций больше
Можно создавать кастомные мутации + количество инстансов должно решить проблему
Слайд 55Особенности
Очень много времени на анализ результатов
Можно настроить запуск на конкретные
файлы вручную
1 мутация !== 1 прогон
:(
1 точка в коде почти
всегда 1 мутация
Для условий и математики количество мутаций больше
Можно создавать кастомные мутации + количество инстансов должно решить проблему
Нет teamcity-reporter для интеграции
Можно пользоваться репортером jest/karma
Слайд 57Первые результаты
Стали думать что тестируем и как тестируем
Появились тесты убивающие
мутантов
Избавляемся от тяжёлых тестов
Выстраиваем пирамиду тестирования здорового программиста
Слайд 59Литература по теме
medium.com/@ClrMobile - A Beginner’s Guide: POC vs. MVP
vs. Prototype
geteasyqa.com - Типы тестирования программного обеспечения
habr.com - Тестирование. Фундаментальная
теория
Инженерное предпринимательство курс Хачин В. Н.
https://ru.wikipedia.org/wiki/Системное_тестирование
habr.com - Мутационное тестирование
https://ru.wikipedia.org/wiki/Мутационное_тестирование
https://stryker-mutator.io
stryker-mutator - Mutant states and metrics
stryker-mutator - Supported mutators