> For the complete documentation index, see [llms.txt](https://docs.leapwise.co/backend-handbook/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.leapwise.co/backend-handbook/development-practices/testing-guidelines/mutation-testing.md).

# Mutation Testing

## About <a href="#mutationtesting-about" id="mutationtesting-about"></a>

Mutation testing assesses software test quality by adding small code defects and checking if tests can find them. It measures how well tests identify errors, aiming for a high mutation detection rate for a strong test suite.

A *mutation* is nothing but a single syntactic change made in the code. Each *mutant* code should differ from the original code by one mutation.

### Glossary <a href="#mutationtesting-glossary" id="mutationtesting-glossary"></a>

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th></tr></thead><tbody><tr><td><strong>mutant</strong></td><td>a unit modification of the code (e.g: <code>!=</code> replaced by <code>==</code>)</td></tr><tr><td><strong>killed/captured</strong></td><td>a mutant was killed if the unit test fails (positive outcome)</td></tr><tr><td><strong>lived/escaped</strong></td><td>a mutant escapes if the unit test doesn’t fail (negative outcome)</td></tr><tr><td><strong>uncovered</strong></td><td>a mutant is uncovered if no test covers the mutated code</td></tr></tbody></table>

## Code coverage <a href="#mutationtesting-codecoverage" id="mutationtesting-codecoverage"></a>

Code coverage is a false indicator of protection. Good coverage does not imply good tests. It is important to distinguish line and branch test coverage:

* **Line Coverage** - the percent of lines executed by this test run
* **Branch Coverage** - the percent of branches executed by this test run

Example:

```
public int getNameLength(boolean isAdminUser) {
    User user = null;
    if (isAdminUser) {
        user = new John();
    }
    return user.getName().length();
}
```

* if we call the getNameLength method with isAdminUser set to true, we will get 100% line coverage
* branch coverage is 50% - we can see there is something missing in our testing
* NullPointerException in case isAdminUser flag is false

### **Coverage runner in IntelliJ** <a href="#mutationtesting-coveragerunnerinintellij" id="mutationtesting-coveragerunnerinintellij"></a>

IntelliJ's Coverage runner allows you to switch from default **Line Coverage** to **JaCoCo** for collecting **Branch Coverage**.<br>

## Types of Mutation Testing <a href="#mutationtesting-typesofmutationtesting" id="mutationtesting-typesofmutationtesting"></a>

Mutation testing is categorised into 3 types:

* **statement mutation** – developer cut and pastes a part of a code of which the outcome may be a removal of some lines
* **value mutation** – values of primary parameters are modified
* **decision mutation** – control statements are to be changed

\
What should be changed in **Mutant Program**?

* *operand replacement*
  * replace the operand with another operand or with the constant value
  * *if(x>y)* replace ***x*** and ***y*** values
* *expression Modification*
  * replace an operator or insert a new operator in a statement
  * *if(x==y)* replace ***==*** with ***>=***
* *statement modification*
  * statements are modified to create mutant programs
  * delete the *else* part in an *if-else* statement
  * delete the entire *if-else* statement to check how a program behaves<br>

## PIT <a href="#mutationtesting-pit" id="mutationtesting-pit"></a>

PIT mutation testing runs unit tests against automatically modified code, providing a Mutation Coverage metric. It is fast, easy to use (e.g., Maven, Gradle), actively developed, and supported. The reports from PIT combine line and mutation coverage information.\ <br>
