<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Andreas Schnapp</title>
    <description>The latest articles on DEV Community by Andreas Schnapp (@5n4p_).</description>
    <link>https://dev.to/5n4p_</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F33591%2F84169134-db49-4067-af83-8f9294371e7c.jpg</url>
      <title>DEV Community: Andreas Schnapp</title>
      <link>https://dev.to/5n4p_</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/5n4p_"/>
    <language>en</language>
    <item>
      <title>I built a single compile Mutation testing lib for Kotlin which runs inside your normal test suite</title>
      <dc:creator>Andreas Schnapp</dc:creator>
      <pubDate>Tue, 03 Mar 2026 07:44:00 +0000</pubDate>
      <link>https://dev.to/5n4p_/i-built-a-single-compile-mutation-testing-lib-for-kotlin-which-runs-inside-your-normal-test-suite-4253</link>
      <guid>https://dev.to/5n4p_/i-built-a-single-compile-mutation-testing-lib-for-kotlin-which-runs-inside-your-normal-test-suite-4253</guid>
      <description>&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Introduction to mutflow&lt;/li&gt;
&lt;li&gt;Testing existing code&lt;/li&gt;
&lt;li&gt;Correct it to pass mutation tests&lt;/li&gt;
&lt;li&gt;Final Conclusions&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Introduction to mutflow
&lt;/h2&gt;

&lt;p&gt;Hey together,&lt;/p&gt;

&lt;p&gt;I built a K2 Compiler Plugin based mutation testing library for kotlin. It is quite different from most of the other mutation libraries or frameworks.&lt;/p&gt;

&lt;p&gt;It does only include mutations for the class which is under test and also only the code you have reached within your test class. It works best if you have a good test coverage already but you want to be sure that the behavior is fully tested.&lt;/p&gt;

&lt;p&gt;It's really easy and fast to include to your project and to integrate with your current tooling.&lt;/p&gt;

&lt;p&gt;In fact it just use a JUnit extension feature which runs your tests for one test class several times (one time per tested mutation).&lt;/p&gt;

&lt;p&gt;To enable mutflow you just have to put it in your gradle plugins:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight gradle"&gt;&lt;code&gt;&lt;span class="n"&gt;plugins&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;kotlin&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"jvm"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="s2"&gt;"2.3.0"&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"io.github.anschnapp.mutflow"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="s2"&gt;"0.8.0"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Maybe it's easiest to see by a little example.
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Testing existing code
&lt;/h3&gt;

&lt;p&gt;Let's say i have this little calculator class:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="c1"&gt;// this annotation mark this class to get configurable mutation points&lt;/span&gt;
&lt;span class="c1"&gt;// inside the test build (dual compile approach production keeps clean)&lt;/span&gt;
&lt;span class="nd"&gt;@MutationTarget&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RangeValidator&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;isInRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;min&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;Boolean&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;min&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;max&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;And this straight forward test:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@MutFlowTest&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RangeValidatorTest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;validator&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;RangeValidator&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;`isInRange&lt;/span&gt; &lt;span class="n"&gt;returns&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range`&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MutFlow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;underTest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;validator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isInRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;min&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;max&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nf"&gt;assertTrue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;`isInRange&lt;/span&gt; &lt;span class="n"&gt;returns&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="n"&gt;below&lt;/span&gt; &lt;span class="nf"&gt;range`&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MutFlow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;underTest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;validator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isInRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nf"&gt;assertFalse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This test looks fine in general, it has full code coverage.&lt;br&gt;
And testing 2 different cases with meaningful assumptions.&lt;/p&gt;

&lt;p&gt;But do we test all relevant behavior here?&lt;/p&gt;

&lt;p&gt;Let's see what happens when we now run our tests.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fid7mc4tbcjazlhn2p66k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fid7mc4tbcjazlhn2p66k.png" alt="JUnit test summary, all tests run multiple times. One time for baseline/normal case. Then for each mutation. Several mutation tests are failing."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here we see the results of the test run in my current IDE (this works without any IDE plugin)&lt;/p&gt;

&lt;p&gt;It shows that all tests are run multiple times in a row.&lt;/p&gt;

&lt;p&gt;First there is the baseline test. This tests run against the normal implementation as is. Because tests had pass before introduction to mutflow the baseline is also green (nothing changed here)&lt;/p&gt;

&lt;p&gt;Then there is one run of all tests per mutation which is tried by the library.&lt;/p&gt;

&lt;p&gt;The first mutation has changed the &amp;lt;= to a &amp;lt; expression.&lt;/p&gt;

&lt;p&gt;Now we need a little mind twist here. The test series which are run per mutation are green if at least one test don't pass.&lt;br&gt;
The idea is that if someone would do a significant change to a correct program. Then the program should not be longer correct and the tests should fail. If they don't fail, then most properly the test does miss to test the behavior fully.&lt;/p&gt;

&lt;p&gt;The &amp;lt;= to &amp;lt; mutation fail means that we don't have tested the border cases close enough. For the is in range we should test the exact border cases (which is also quite intuitive for experienced developers). In the log output of the tests you will be pointed on the line where this mutation appears.&lt;/p&gt;
&lt;h3&gt;
  
  
  Correcting the code for passing mutation tests
&lt;/h3&gt;

&lt;p&gt;So let's change the test for testing as close to the borders as possible.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@MutFlowTest&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RangeValidatorTest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;validator&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;RangeValidator&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;`isInRange&lt;/span&gt; &lt;span class="n"&gt;returns&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;range&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="nf"&gt;border`&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MutFlow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;underTest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;validator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isInRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;min&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;max&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nf"&gt;assertTrue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;`isInRange&lt;/span&gt; &lt;span class="n"&gt;returns&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;range&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="nf"&gt;border`&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MutFlow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;underTest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;validator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isInRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;min&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;max&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nf"&gt;assertTrue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;`isInRange&lt;/span&gt; &lt;span class="n"&gt;returns&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="n"&gt;below&lt;/span&gt; &lt;span class="n"&gt;range&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="nf"&gt;border`&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MutFlow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;underTest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;validator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isInRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nf"&gt;assertFalse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;`isInRange&lt;/span&gt; &lt;span class="n"&gt;returns&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="n"&gt;below&lt;/span&gt; &lt;span class="n"&gt;range&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="nf"&gt;border`&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MutFlow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;underTest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;validator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isInRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nf"&gt;assertFalse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now we run again the test and see if it worked:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2am5s3yuihs4mf9jovh2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2am5s3yuihs4mf9jovh2.png" alt="Screenshot of JUnit results showing all normal/baseline tests are passing and mutation tests also"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yes as expected our clean border testing works. Now we don't have only tests which covers each code line but which seems also be robust enough for our mutations.&lt;/p&gt;
&lt;h2&gt;
  
  
  Final Conclusions
&lt;/h2&gt;

&lt;p&gt;Of course this was a trivial example and the real world is a lot of more complex and nuance.&lt;/p&gt;

&lt;p&gt;There are already quite some little features and helpers in the library to cope with reality:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;easy ways of marking lines or function be ignored regarding mutations (only useful inside mutation target class)&lt;/li&gt;
&lt;li&gt;global way to deactivate mutation testing even if project and tests are configured for it&lt;/li&gt;
&lt;li&gt;limit amount of mutations per test. which has a stable enough mechanism where mutation are stable as long as implementation does not change. so it's fine to use this in a pipeline.&lt;/li&gt;
&lt;li&gt;timing out if mutation lead to infinite loops (then you get a hint to mark this line for ignoring)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also this project is young, for now i have very carefully selected the mutations which i have seen as most valuable.&lt;/p&gt;

&lt;p&gt;In general i think the set of mutation should be kept small. So that it's a good trade off regarding finding useful things, having good performance and don't have many false positives.&lt;/p&gt;

&lt;p&gt;Built with the help of an AI assistant — all design decisions carefully choose.&lt;/p&gt;
&lt;h3&gt;
  
  
  Feedback most welcome
&lt;/h3&gt;

&lt;p&gt;But of course feedback and real world usage would be required for making this tool as useful as it could be. Therefore early birds and feedback is most welcome.&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/anschnapp" rel="noopener noreferrer"&gt;
        anschnapp
      &lt;/a&gt; / &lt;a href="https://github.com/anschnapp/mutflow" rel="noopener noreferrer"&gt;
        mutflow
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Mutation testing inside your Kotlin tests. Compile once, catch gaps.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;
  &lt;a rel="noopener noreferrer" href="https://github.com/anschnapp/mutflow/blob/master/logo.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fanschnapp%2Fmutflow%2Fraw%2Fmaster%2Flogo.png" alt="mutflow"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
  Mutation testing inside your Kotlin tests. Compile once, catch gaps
&lt;/p&gt;
&lt;p&gt;
  &lt;a href="https://central.sonatype.com/artifact/io.github.anschnapp.mutflow/mutflow-gradle-plugin" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/2e126ac18fa54c24305aa859123b1bb42eaf0d0dfb551b94a5608fa48a694bb6/68747470733a2f2f696d672e736869656c64732e696f2f6d6176656e2d63656e7472616c2f762f696f2e6769746875622e616e7363686e6170702e6d7574666c6f772f6d7574666c6f772d677261646c652d706c7567696e" alt="Maven Central"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Early Stage:&lt;/strong&gt; mutflow is young and still evolving. Its dual-compilation approach is built to keep production builds clean — mutations only exist in test compilation. The project hasn't seen broad adoption yet, so bug reports and feedback are very welcome!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Contents&lt;/h2&gt;
&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/anschnapp/mutflow#what-is-this" rel="noopener noreferrer"&gt;What is this?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/anschnapp/mutflow#why" rel="noopener noreferrer"&gt;Why?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/anschnapp/mutflow#what-mutflow-tests-and-what-it-doesnt" rel="noopener noreferrer"&gt;What mutflow tests (and what it doesn't)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/anschnapp/mutflow#setup" rel="noopener noreferrer"&gt;Setup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/anschnapp/mutflow#quick-start" rel="noopener noreferrer"&gt;Quick Start&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/anschnapp/mutflow#configuration" rel="noopener noreferrer"&gt;Configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/anschnapp/mutflow#mutation-operators" rel="noopener noreferrer"&gt;Mutation Operators&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/anschnapp/mutflow#features" rel="noopener noreferrer"&gt;Features&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/anschnapp/mutflow#how-mutations-work" rel="noopener noreferrer"&gt;How Mutations Work&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/anschnapp/mutflow#design-decisions" rel="noopener noreferrer"&gt;Design Decisions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/anschnapp/mutflow#troubleshooting" rel="noopener noreferrer"&gt;Troubleshooting&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;What is this?&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;mutflow brings mutation testing to Kotlin with minimal overhead. Instead of the traditional approach (compile and run each mutant separately), mutflow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Compiles once&lt;/strong&gt; — All mutation variants are injected at compile time as conditional branches&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Discovers dynamically&lt;/strong&gt; — Mutation points are found during baseline test execution&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Runs all mutations&lt;/strong&gt; — Every discovered mutation is tested by default, no configuration needed&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why?&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;Traditional mutation testing is powerful but expensive. Most teams skip it…&lt;/p&gt;
&lt;/div&gt;


&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/anschnapp/mutflow" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;





</description>
      <category>kotlin</category>
      <category>mutationtesting</category>
      <category>kotlincompilerplugin</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
