Knowledge-base
  • Home
  • Samman Technical Coaching
  • Software craftsmanship
    • Practices
      • Pair Programming
      • Code Review
      • Co-designs
      • Design sessions
      • Interview Domain Experts
      • Dev ethics
    • The Software Craftsman
    • Egoless Crafting
    • Technical debt workshop
    • Functional Programming made easy in C# with Language-ext
    • F# for OO programmers
    • Domain Modeling Made Functional
    • Testing
      • Clean Tests
      • Improve the design and testing of your micro-services through CDC Tests
        • CDC testing made simple with Pact
        • Pact broker : the missing piece of your Consumer-Driven Contract approach
      • Improve your test quality with Mutation testing
      • How to name our Unit Tests
      • How to write better assertions
    • Katas
      • TDD
        • Stack kata
        • Fizzbuzz
        • Outside-in TDD (London Style)
      • Improve your software quality with Property-Based Testing
        • A journey to Property-Based Testing
      • Clean Code
      • Clean Architecture
      • Write S.O.L.I.D code
      • Mocking
      • Gilded Rose (Approval Testing)
      • Mikado method
        • Mikado kata
      • Pure functions
      • Theatrical players refactoring Kata
        • Let's refactor (OOP style)
        • Let's refactor (FP style)
      • Functional Programming made easy in Java & C#
      • Refactoring journey
      • Refactoring du Bouchonnois
        • 1) Se faire une idée du code
        • 2) "Treat warnings as errors"
        • 3) Let's kill some mutants
        • 4) Améliorer la lisibilité des tests
        • 5) "Approve Everything"
        • 6) Définir des propriétés
        • 7) Tests d'architecture
        • 8) Use Cases
        • 9) Tell Don't Ask
        • 10) "Avoid Primitives" - Commands
        • 11) "Avoid Exceptions"
        • 12) "Event Sourcing"
    • Software Design X-Rays
      • Workshop
    • The Programmer's Brain
      • How to read code better
  • Software Architecture
    • Fundamentals of Software Architecture
    • Aligning Product & Software Design
    • DDD re-distilled
    • Test your architecture with Archunit
    • NoSQL
  • Agile coaching
    • How to run a Community of Practices (COP)
    • The developers — the forgotten of agility
      • The secrets to re-on-board the devs in agility
    • Coaching toolbox
      • Echelle
      • Learning expedition
    • How to improve Team Decision making ?
      • Decision Making Principles and Practices
    • Learning 3.0
    • Retrospectives
      • Back to the Future
      • Mission Impossible
      • Movie themes
      • Rétro dont vous êtes le héros
      • Sad/Mad/Glad
      • Speed boat
      • Star wars theme
      • Story cubes
    • Technical Agile Coaching with the Samman Method
    • Xanpan - a team centric agile method story
    • XTREM WATCH — Découvrez la puissance de la veille collective
    • Become a better speaker through peer feedback
    • Project-to-Product Principles
  • Leadership
    • Bref. J'ai pris une tarte dans la gueule (et ça fait extrêmement de bien)
    • Forward Summit 2020
    • Learn leadership from the Navy SEALs
    • Learn to lead and help your team(s) to be successful
    • Towards a learning organization and beyond
    • Leadership is language
  • Serious games
    • My serious games
    • Libérez vos entretiens d’embauche avec la gamification
    • How to create a game
    • How to debrief a game ?
    • Lego Serious Play (LSP)
      • LSP in your job interviews
  • Xtrem Reading
    • Cultivate Team Learning with Xtrem Reading
    • My Book Infographics
    • How to make book infographics
    • En route vers l’apprenance avec Xtrem Reading
    • Resources
      • Book notes
        • Agile People: A Radical Approach for HR & Managers
        • Agile testing : A Practical Guide for Testers and Agile Teams
        • Boite à outils de l'intelligence émotionnelle
        • Building a better business using Lego Serious Play method
        • Building evolutionary architectures
        • Code that fits in your head
        • Culture Agile
        • Culture is everything
        • Domain-Driven Design: The First 15 Years
        • Dynamic Reteaming - The Art and Wisdom of Changing Teams
        • How to avoid a Climate Disaster
        • La liberté du commandement
        • Réaliser ses rêves, ça s'apprend
        • Refactoring at Scale
        • Succeeding with OKRs in Agile
        • Team Topologies
        • The Good Life
        • Tu fais quoi dans la vie
        • Who Does What By How Much?
  • My Activity
    • Retour sur mon année 2020
Powered by GitBook
On this page
  • How can we measure test quality ?
  • Use our intuition ?
  • Use code coverage ?
  • Mutation testing to our rescue
  • What is it ?
  • What is a mutant ?
  • How to generate mutants ?
  • Start with pitest
  • Mutators
  • Available mutators
  • Mutation report
  • Real life feedback
  • Integrate Pitest in your Integration pipelines
  • Pros & cons

Was this helpful?

  1. Software craftsmanship
  2. Testing

Improve your test quality with Mutation testing

Mutation testing (or mutation analysis or program mutation) is used to design new software tests and evaluate the quality of existing software tests.

PreviousPact broker : the missing piece of your Consumer-Driven Contract approachNextHow to name our Unit Tests

Last updated 4 years ago

Was this helpful?

How can we measure test quality ?

Use our intuition ?

Not really a good indicator : too much subjective.

Use code coverage ?

Code coverage is a quantitative metric not a qualitative one.

Let's take a simple example :

Imagine I have written a Calculator.add method that simply add an integer x and an integer y. I have written some tests on it :

It could seem fine at the first look with a 100% lines covered according to my code coverage tool :

But when you take a closer look the tests the assertions are really shitty :

Mutation testing to our rescue

What is it ?

Mutation testing is based on two hypotheses :

The first is the competent programmer hypothesis. This hypothesis states that most software faults introduced by experienced programmers are due to small syntactic errors.

The second hypothesis is called the coupling effect. The coupling effect asserts that simple faults can cascade or couple to form other emergent faults.” - wikipedia

The concept behind :

Test our tests by introducing MUTANTS (fault) into our production code during the test execution :

  • To check that the test is failing

  • If the test pass, there is an issue

3 steps

  1. Generate mutants

  2. Launch tests

  3. Check result / Generate report

What is a mutant ?

A mutant is created by altering the production in various ways :

  • For conditions :

    • Change

    • Reverse conditions

    • Constant

  • For math operations :

    • Change increment with decrement (from x++ to x--)

    • Change binary operations

  • Remove function calls

  • Rename constants

  • ...

How to generate mutants ?

Start with pitest

Simply add a dependency in your pom to the pitest-maven plugin :

<plugin> 
	<groupId>org.pitest</groupId>
	<artifactId>pitest-maven</artifactId>
	<version>1.5.0</version>
</plugin>

You will then have access to the pitest functionality from your maven :

Mutators

PIT applies a set of mutation operators (mutators) to our byte code generated by compiling our code.

Available mutators

Mutation report

When you run the pitest report it will generate an html report (by default) :

How to read it ?

For each mutation PIT will report one of the following outcomes :

  • KILLED : exactly what we want our tests have failed so detected the mutant

  • SURVIVED : our tests have not detected the mutants so we have to improve our assertions

  • NO COVERAGE : same as SURVIVED except there were no tests that exercised the line of code where the mutation was created

  • TIMED OUT : a mutation may time out if it causes an infinite loop, such as removing the increment from a counter in a for loop

  • NON-VIABLE : mutation that could not be loaded by the JVM as the bytecode was in some way invalid

  • MEMORY ERROR : might occur as a result of a mutation that increases the amount of memory used by the system

  • RUN ERROR : means something went wrong when trying to test the mutation

Real life feedback

  • Configure pitest to skip pojos : exclude every auto generated code (lombok in my case), otherwise ti creates a lot of noise.

You can do it from you pom.xml :

<plugin>    
    <groupId>org.pitest</groupId>
    <artifactId>pitest-maven</artifactId>
    <version>1.5.0</version>
    <configuration>
        <targetClasses>
            <param>sample.controller*</param>
            <param>com.bil.commons.sample.service*</param>
        </targetClasses>
        <targetTests>
            <param>com.bil.commons.sample*</param>
        </targetTests>
    </configuration>
</plugin>
  • Avoid the run of integration tests otherwise it could be really slow on spring boot micro-services (more than 10 minutes)

Integrate Pitest in your Integration pipelines

  • Add an XML Output (still in your pom)

<configuration>
    <outputFormats>
        <outputFormat>XML</outputFormat>
    </outputFormats>
    ...
  • Add a stage in your pipeline

    • For jenkins for example : stage('Mutation Test') { mvn "org.pitest:pitest-maven:mutationCoverage" }

You will now have your pitest report integrated in your Sonar analysis report :

Pros & cons

Pros

Cons

Help identify missing important tests

Very expensive : Take a lot of time to run

It catches many small programming errors, as well as holes in unit tests that would otherwise go unnoticed

Do not run it on controllers

Quantify quality of our tests and so of our system

Requires brainpower to sort ‘junk’ mutations from useful ones.

Really useful for core domain model tests

From my Point of View Mutation Testing is really a great tool that can help you identify problems and drive your code reviews.

To use mutation testing we can use tools like (for java) but others are available like .

More info here :

By default it's offering a lot of mutators :

You can integrate it easily in your integration pipelines with SonarQube or

Install the "mutation analysis" plugin on Sonar :

pitest
stryker
https://pitest.org/quickstart/maven/
https://pitest.org/quickstart/mutators/
SonarCloud
https://www.sonarplugins.com/mutationanalysis
Example of pitest mutator
Report summary
Report details