Мутационное тестирование - способ оценить надежность кода, проверить предупреждение об изменениях кода, увидеть значение примеров модульного тестирования и опустить отчет о тестовом покрытии (100% тестовое покрытие не означает хорошие модульные тесты).

Итак, что такое мутационное тестирование и какую выгоду от этого может получить мой проект?

Что ж, мутационное тестирование не ново, исходя из собранной мной информации, оно было впервые предложено в 1971 году, но не принято с 2008 года. Однако сейчас оно все еще ново для многих людей, которые никогда не слышали о нем, но я уверен, что это будет изменения в ближайшие годы, пока разработчики осознают, насколько мощным это может быть для оценки качества модульного тестирования и защиты от изменений.

Мутационное тестирование вносит небольшие изменения в код (мутации), чтобы заставить модульные тесты, которые оценивают эту часть кода, дать сбой (уничтожить мутацию).

Пошаговый процесс тестирования мутаций:

  • Внесено изменение в исходный код.
  • Связанные тесты запускаются с этим кодом, который был только что изменен.
  • Если тест не прошел, это означает, что есть тест, который его покрывает, и мутация была уничтожена.
  • Если тест не проваливается, значит, нет теста, охватывающего жизни мутации.

У нас есть такая функция сложения:

public addition(num_1, num_2) {
  return num_1 + num_2;
}

Гипотетический тест для функции сложения:

it('must return the result addtion between the two numbers') {
  assert(addition(2,2)).toBeEqual(4);
  //Assert in values assert(4).toBeEqual(4)=True Test passed
}

Применим мутационное тестирование для приведенного выше примера:

Мы берем добавление функции и вносим изменения в код, чтобы преобразовать код, мы собираемся изменить оператор «+» на «-».

public addition(num_1, num_2) {
  return num_1 - num_2;
}

Мы запускаем соответствующие тестовые примеры для этой функции, и тест должен завершиться неудачно:

it('must return the result addtion between the two numbers') {
  assert(addition(2,2)).toBeEqual(4);
  //Assert in values assert(0).toBeEqual(4)=True Test failed
}

Когда тест завершается неудачно из-за изменения кода, которое мы сделали в коде, мутация уничтожается, но если она все еще проходила, это означает, что мутация существует, и код недостаточно силен, чтобы предупредить разработчика об изменении поведения кода. текущие функции, это критическая часть, где я считаю, что мутационное тестирование лучше, чем тестовое покрытие, так как покрытие тестового кода и изменение кода.

Итак, мы увидели, что есть, но как это может принести пользу моему проекту, ответ прост: при тестировании мутаций разработчик может видеть, что модульный тест, который он / она сделал для кода, завершится ошибкой, если кто-то изменит его, и исправит его, если они не надо. Это очень удобно для больших проектов, где многие разработчики постоянно меняют код. Вы будете уверены, что все модульные тесты тестируют код, а не только покрывают его. Кроме того, на ранних этапах разработки поделитесь идеями с разработчиком, чтобы увидеть, что можно протестировать.

Мутационное тестирование работает, только если модульные тесты настолько изолированы, насколько они должны быть.

Если вы хотите использовать тестирование мутаций для проекта javascript, вот фреймворк, который я использовал для тестирования мутаций для javascript / Angular:
https://stryker-mutator.io/

Вот несколько файлов конфигурации stryker для разных участников тестирования:

stryker.conf.js для Angular Webpack Typescript Jest:

npm i -D @ stryker-mutator / core @ stryker-mutator / html-reporter @ stryker-mutator / api @ stryker-mutator / jest-runner @ stryker-mutator / typescript

module.exports = function (config) {
    config.set({
        mutate: ["src/**/*.ts"],
        testRunner: 'jest',
        testFramework: 'jest',
        mutator: 'typescript',
        reporter: ['html'],
        coverageAnalysis: 'off',
        jest: {
            config: require('./config/jest/config')
        },
        logLevel: "all",
        tsconfigFile: "tsconfig.json",
        packageManager: "npm",
        allowUnreachableCode: true,
        noUnusedLocals: false,
        noUnusedParameters: false,
        htmlReporter: {
            baseDir: 'reports/mutation/html' // this is the default
        }
    });
};

stryker.conf.js для Typescript Jasmine:

npm i -D @stryker -mutator / core @stryker -mutator / html-reporter @stryker -mutator / api @stryker -mutator / typescript @stryker -mutator / jasmine-runner

module.exports = function(config) {
  config.set({
    mutator: "typescript",
    packageManager: "npm",
    reporters: ["html", "clear-text", "progress"],
    testRunner: "command",
    testFramework: "jasmine",
    coverageAnalysis: "off",
    jasmineConfigFile: "jasmine.json",
    tsconfigFile: "tsconfig.json",
    mutate: ["src/**/*.ts"]
  });
};

stryker.conf.js для Typescript Mocha:

npm i -D @stryker -mutator / core @stryker -mutator / html-reporter @stryker -mutator / api @stryker -mutator / typescript @stryker -mutator / mocha-runner

module.exports = function(config) {
  config.set({
    mutator: "typescript",
    packageManager: "npm",
    reporters: ["html", "clear-text", "progress"],
    testRunner: "mocha",
    testFramework: "mocha",
    coverageAnalysis: "off",
    tsconfigFile: "tsconfig.json",
    mutate: ["src/**/*.ts"],
    mochaOptions: {
            // Optional mocha options
            files: [ 'test/**/*.ts' ]
            opts: 'mocha/conf.js',
            ui: 'bdd',
            timeout: 3000,
            require: [ /*'babel-register' */],
            asyncOnly: false,
            grep: /.*/
        }
  });
};

Список инструментов тестирования мутаций для других языков (спасибо Википедии):

  • Список инструментов и публикаций Мутационное тестирование от Jeff Offutt
  • MuJava Инструмент мутации для Java, включающий операторы уровня класса.
  • Mutate.py Python-скрипт для изменения C-программ.
  • Bacterio Инструмент тестирования мутаций для мультиклассовых систем Java.
  • Javalanche Инструмент тестирования мутаций на основе байт-кода для Java
  • Major интегрированный в компилятор фреймворк для тестирования мутаций для Java
  • Jumble Инструмент тестирования мутаций на основе байт-кода для Java
  • PIT Инструмент тестирования мутаций на основе байт-кода для Java
  • Descartes Плагин движка мутаций для PIT на основе тестирования экстремальных мутаций [21], разработанный в рамках Исследовательского проекта STAMP
  • Stryker Инструмент тестирования мутаций для JavaScript
  • Мутантный инструмент тестирования мутаций на основе AST для Ruby
  • Jester Инструмент для тестирования мутаций на основе исходного кода для Java
  • Judy Инструмент тестирования мутаций для Java
  • Heckle Инструмент тестирования мутаций для Ruby
  • Инструмент тестирования мутаций на основе IL NinjaTurtles для .NET и Mono
  • Nester Инструмент тестирования мутаций для C #
  • VisualMutator Инструмент тестирования мутаций для C #
  • Humbug Инструмент тестирования мутаций для PHP
  • Infection PHP Фреймворк для тестирования мутаций на основе AST для PHP
  • Библиотека анализа мутаций MuCheck для Haskell
  • Mutmut Система тестирования мутаций для Python
  • Mull Мутационное тестирование на основе LLVM
  • Dextool Mutate Мутационное тестирование C / C ++
  • Mutate ++ Инструмент тестирования мутаций для C ++

Пожертвования

BTC - bc1qx2alfy4ks8p6gg5y4eantcuwxaefg4wfk42krm

ETH - 0xf21134B4b09F3C1ebF0C8eb386C2EA8D517783fc или hetdev.eth

BCH - qqcxu636r93dne2unp7gdvzdpkwtnx6vlyp3klw48y

LTC - LPQeUXYJ1pThNSLXPJYYHobKEh92sWQyUT

ZEC - t1fkrzNFqwSb2PHtQsKU6i2SVnxmsQMbXKr