<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>mutation testing Archives - CodeJourney.net</title>
	<atom:link href="https://www.codejourney.net/tag/mutation-testing/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.codejourney.net/tag/mutation-testing/</link>
	<description>Pragmatic full stack software development</description>
	<lastBuildDate>Thu, 03 Oct 2024 13:41:05 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://i0.wp.com/www.codejourney.net/wp-content/uploads/2018/10/cropped-512px-na-512px-JPEG-BEZ-NAPISU-1.jpg?fit=32%2C32&#038;ssl=1</url>
	<title>mutation testing Archives - CodeJourney.net</title>
	<link>https://www.codejourney.net/tag/mutation-testing/</link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">123174533</site>	<item>
		<title>What is Mutation Testing and Why Should You Use It?</title>
		<link>https://www.codejourney.net/what-is-mutation-testing-and-why-you-should-use-it/</link>
					<comments>https://www.codejourney.net/what-is-mutation-testing-and-why-you-should-use-it/#respond</comments>
		
		<dc:creator><![CDATA[Dawid Sibiński]]></dc:creator>
		<pubDate>Tue, 01 Oct 2024 18:22:58 +0000</pubDate>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[mutation testing]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[typescript]]></category>
		<category><![CDATA[unit tests]]></category>
		<guid isPermaLink="false">https://www.codejourney.net/?p=4825</guid>

					<description><![CDATA[<p>Do you know what is a better testing metric than code coverage? Does 100% code coverage mean your code is well-tested? How to generate unit test cases for free, without using AI? The answer to all these questions is mutation testing. Interested? Read on 😉 Code Coverage &#8211; Our Old Friend You probably know what&#8230;</p>
<p>The post <a href="https://www.codejourney.net/what-is-mutation-testing-and-why-you-should-use-it/">What is Mutation Testing and Why Should You Use It?</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Do you know what is a better testing metric than code coverage? Does 100% code coverage mean your code is well-tested? How to generate unit test cases for free, without using AI?</p>



<p>The answer to all these questions is <strong>mutation testing</strong>. Interested? Read on <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<span id="more-4825"></span>



<h2 class="wp-block-heading">Code Coverage &#8211; Our Old Friend</h2>



<p>You probably know what <a href="https://en.wikipedia.org/wiki/Code_coverage">code coverage</a> is. Traditionally, many teams tend to measure how good their tests&#8217; suite is by percentage line / statements / functions coverage. Some even require this metric to be 100%. Let&#8217;s start with this well-known approach first.</p>



<p>We are working with <code>TicketsPriceCalculator</code> class today. It contains some simple business logic:</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler wp-block-embed-embed-handler"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist133062269" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-ticketspricecalculator-ts" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-typescript  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="ticketsPriceCalculator.ts content, created by dsibinski on 04:08PM on October 01, 2024."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="ticketsPriceCalculator.ts">
        <tr>
          <td id="file-ticketspricecalculator-ts-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-ticketspricecalculator-ts-LC1" class="blob-code blob-code-inner js-file-line">export class TicketsPriceCalculator {</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-ticketspricecalculator-ts-LC2" class="blob-code blob-code-inner js-file-line">  calculateTotalTicketsPrice(tickets: Ticket[]): number {</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-ticketspricecalculator-ts-LC3" class="blob-code blob-code-inner js-file-line">    if (tickets.length === 0) {</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-ticketspricecalculator-ts-LC4" class="blob-code blob-code-inner js-file-line">      return 0;</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-ticketspricecalculator-ts-LC5" class="blob-code blob-code-inner js-file-line">    }</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-ticketspricecalculator-ts-LC6" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-ticketspricecalculator-ts-LC7" class="blob-code blob-code-inner js-file-line">    let totalPrice = tickets.reduce((sum, ticket) =&gt; sum + ticket.price, 0);</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-ticketspricecalculator-ts-LC8" class="blob-code blob-code-inner js-file-line">    const businessClassTickets = tickets.filter(</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-ticketspricecalculator-ts-LC9" class="blob-code blob-code-inner js-file-line">      (ticket) =&gt; ticket.isBusinessClass</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L10" class="blob-num js-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-ticketspricecalculator-ts-LC10" class="blob-code blob-code-inner js-file-line">    ).length;</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L11" class="blob-num js-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-ticketspricecalculator-ts-LC11" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L12" class="blob-num js-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-ticketspricecalculator-ts-LC12" class="blob-code blob-code-inner js-file-line">    let totalDiscountToApply = 0;</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L13" class="blob-num js-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-ticketspricecalculator-ts-LC13" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L14" class="blob-num js-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-ticketspricecalculator-ts-LC14" class="blob-code blob-code-inner js-file-line">    // Apply discounts based on total price</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L15" class="blob-num js-line-number js-blob-rnum" data-line-number="15"></td>
          <td id="file-ticketspricecalculator-ts-LC15" class="blob-code blob-code-inner js-file-line">    if (totalPrice &gt; 2000) {</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L16" class="blob-num js-line-number js-blob-rnum" data-line-number="16"></td>
          <td id="file-ticketspricecalculator-ts-LC16" class="blob-code blob-code-inner js-file-line">      totalDiscountToApply += 0.25;</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L17" class="blob-num js-line-number js-blob-rnum" data-line-number="17"></td>
          <td id="file-ticketspricecalculator-ts-LC17" class="blob-code blob-code-inner js-file-line">    } else if (totalPrice &gt; 1000 &amp;&amp; totalPrice &lt;= 2000) {</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L18" class="blob-num js-line-number js-blob-rnum" data-line-number="18"></td>
          <td id="file-ticketspricecalculator-ts-LC18" class="blob-code blob-code-inner js-file-line">      totalDiscountToApply += 0.2;</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L19" class="blob-num js-line-number js-blob-rnum" data-line-number="19"></td>
          <td id="file-ticketspricecalculator-ts-LC19" class="blob-code blob-code-inner js-file-line">    } else if (totalPrice &gt; 500 &amp;&amp; totalPrice &lt;= 1000) {</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L20" class="blob-num js-line-number js-blob-rnum" data-line-number="20"></td>
          <td id="file-ticketspricecalculator-ts-LC20" class="blob-code blob-code-inner js-file-line">      totalDiscountToApply += 0.15;</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L21" class="blob-num js-line-number js-blob-rnum" data-line-number="21"></td>
          <td id="file-ticketspricecalculator-ts-LC21" class="blob-code blob-code-inner js-file-line">    } else if (totalPrice &gt;= 200 &amp;&amp; totalPrice &lt;= 500) {</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L22" class="blob-num js-line-number js-blob-rnum" data-line-number="22"></td>
          <td id="file-ticketspricecalculator-ts-LC22" class="blob-code blob-code-inner js-file-line">      totalDiscountToApply += 0.1;</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L23" class="blob-num js-line-number js-blob-rnum" data-line-number="23"></td>
          <td id="file-ticketspricecalculator-ts-LC23" class="blob-code blob-code-inner js-file-line">    }</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L24" class="blob-num js-line-number js-blob-rnum" data-line-number="24"></td>
          <td id="file-ticketspricecalculator-ts-LC24" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L25" class="blob-num js-line-number js-blob-rnum" data-line-number="25"></td>
          <td id="file-ticketspricecalculator-ts-LC25" class="blob-code blob-code-inner js-file-line">    // Apply additional discount based on number of tickets</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L26" class="blob-num js-line-number js-blob-rnum" data-line-number="26"></td>
          <td id="file-ticketspricecalculator-ts-LC26" class="blob-code blob-code-inner js-file-line">    if (tickets.length &gt;= 10) {</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L27" class="blob-num js-line-number js-blob-rnum" data-line-number="27"></td>
          <td id="file-ticketspricecalculator-ts-LC27" class="blob-code blob-code-inner js-file-line">      totalDiscountToApply += 0.05;</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L28" class="blob-num js-line-number js-blob-rnum" data-line-number="28"></td>
          <td id="file-ticketspricecalculator-ts-LC28" class="blob-code blob-code-inner js-file-line">    }</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L29" class="blob-num js-line-number js-blob-rnum" data-line-number="29"></td>
          <td id="file-ticketspricecalculator-ts-LC29" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L30" class="blob-num js-line-number js-blob-rnum" data-line-number="30"></td>
          <td id="file-ticketspricecalculator-ts-LC30" class="blob-code blob-code-inner js-file-line">    // Apply business class discounts</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L31" class="blob-num js-line-number js-blob-rnum" data-line-number="31"></td>
          <td id="file-ticketspricecalculator-ts-LC31" class="blob-code blob-code-inner js-file-line">    if (businessClassTickets &gt;= 10) {</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L32" class="blob-num js-line-number js-blob-rnum" data-line-number="32"></td>
          <td id="file-ticketspricecalculator-ts-LC32" class="blob-code blob-code-inner js-file-line">      totalDiscountToApply += 0.2;</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L33" class="blob-num js-line-number js-blob-rnum" data-line-number="33"></td>
          <td id="file-ticketspricecalculator-ts-LC33" class="blob-code blob-code-inner js-file-line">    } else if (businessClassTickets &gt;= 5) {</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L34" class="blob-num js-line-number js-blob-rnum" data-line-number="34"></td>
          <td id="file-ticketspricecalculator-ts-LC34" class="blob-code blob-code-inner js-file-line">      totalDiscountToApply += 0.1;</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L35" class="blob-num js-line-number js-blob-rnum" data-line-number="35"></td>
          <td id="file-ticketspricecalculator-ts-LC35" class="blob-code blob-code-inner js-file-line">    }</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L36" class="blob-num js-line-number js-blob-rnum" data-line-number="36"></td>
          <td id="file-ticketspricecalculator-ts-LC36" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L37" class="blob-num js-line-number js-blob-rnum" data-line-number="37"></td>
          <td id="file-ticketspricecalculator-ts-LC37" class="blob-code blob-code-inner js-file-line">    return totalPrice * (1 &#8211; totalDiscountToApply);</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L38" class="blob-num js-line-number js-blob-rnum" data-line-number="38"></td>
          <td id="file-ticketspricecalculator-ts-LC38" class="blob-code blob-code-inner js-file-line">  }</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator-ts-L39" class="blob-num js-line-number js-blob-rnum" data-line-number="39"></td>
          <td id="file-ticketspricecalculator-ts-LC39" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/28087f239e57c7dab06d3df2e7532e6d/raw/d388fec49bd951d520a8d0af93c07907c122ce27/ticketsPriceCalculator.ts" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/28087f239e57c7dab06d3df2e7532e6d#file-ticketspricecalculator-ts" class="Link--inTextBlock">
          ticketsPriceCalculator.ts
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p>As you can see, the class has one function whith returns the total price to be paid for a set of tickets. On the way, it applies various discounts based on some business rules. Fair enough.</p>



<p>It&#8217;s a critical piece of business logic for the app we&#8217;re working on, but it has never had any tests. We were asked to write unit tests for this class. Our manager strictly requires the code coverage to be 100%. Let&#8217;s do it then. We will go line by line, analyze the business logic and add the tests. Below, you can see the results of running those tests (you can find the tests code <a href="https://gist.github.com/dsibinski/cfc8d36cf7fe45bb9114b950fa898766">here</a>):</p>



<figure class="wp-block-image size-full"><img data-recalc-dims="1" fetchpriority="high" decoding="async" width="839" height="427" data-attachment-id="4840" data-permalink="https://www.codejourney.net/what-is-mutation-testing-and-why-you-should-use-it/1-unit-tests-initial/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/1-unit-tests-initial.jpg?fit=839%2C427&amp;ssl=1" data-orig-size="839,427" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="1-unit-tests-initial" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/1-unit-tests-initial.jpg?fit=839%2C427&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/1-unit-tests-initial.jpg?resize=839%2C427&#038;ssl=1" alt="Unit tests before using mutation testing. We have 8 unit tests, all passing. Our code coverage (line, functions, statements, branches) is 100%" class="wp-image-4840" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/1-unit-tests-initial.jpg?w=839&amp;ssl=1 839w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/1-unit-tests-initial.jpg?resize=768%2C391&amp;ssl=1 768w" sizes="(max-width: 839px) 100vw, 839px" /></figure>



<p></p>



<p>Wow, that&#8217;s awesome! We did a great job. We have <strong>8 unit tests which provide 100% statements, branch, functions and lines coverage</strong>!</p>



<p>So now we are really safe, aren&#8217;t we? <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f914.png" alt="🤔" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p>Yeah&#8230; until you know what mutation testing is <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f60e.png" alt="😎" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h2 class="wp-block-heading">What Is Mutation Testing?</h2>



<p>The idea of mutation testing is to <em>mutate</em> (change) our code. Mutation testing tools introduce changes into our production code. These changes can be really anything &#8211; from reverting a condition of an <code>if</code> statement, to changing some operators or changing a <code>string</code> value. For instance, here are some logical mutations <a href="https://stryker-mutator.io/">Stryker Mutator</a> is able to introduce (you can find the list of all mutations supported by Stryker <a href="https://stryker-mutator.io/docs/mutation-testing-elements/supported-mutators/">here</a>):</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" decoding="async" width="445" height="320" data-attachment-id="4845" data-permalink="https://www.codejourney.net/what-is-mutation-testing-and-why-you-should-use-it/2-stryker-logical-mutations/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/2-stryker-logical-mutations.jpg?fit=445%2C320&amp;ssl=1" data-orig-size="445,320" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="2-stryker-logical-mutations" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/2-stryker-logical-mutations.jpg?fit=445%2C320&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/2-stryker-logical-mutations.jpg?resize=445%2C320&#038;ssl=1" alt="Logical operator mutations supported by Stryker Mutator" class="wp-image-4845"/></figure>
</div>


<p></p>



<p>In effect, they generate modified versions of our code, which are called <em>mutants</em>. Makes sense <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p>Each mutant contains a single modification in our source code. What happens next is crucial. Mutation testing tool takes this mutant (it is used as the code under tests now) and executes all of our unit tests against it. The result may be twofold:</p>



<ul class="wp-block-list">
<li>all tests have passed. In other words, the <em>mutant has</em> <em>survived</em>. <strong>This is a bad situation</strong>. It implies that the modification of our source code was not detected by our tests</li>



<li>at least one test has failed. In other words, the <em>mutant has been killed</em>. <strong>This is a good scenario</strong>. It means that our tests detect changes in the production code and efficiently cover this particular scenario.</li>
</ul>



<p>The flow is more or less like this <a href="https://peterevans.dev/posts/mutation-testing/">schema from Peter Evans&#8217; blog</a> presents:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full is-resized"><img data-recalc-dims="1" decoding="async" width="353" height="580" data-attachment-id="4847" data-permalink="https://www.codejourney.net/what-is-mutation-testing-and-why-you-should-use-it/3-mutation-test-schema/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/3-mutation-test-schema.png?fit=353%2C580&amp;ssl=1" data-orig-size="353,580" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="3-mutation-test-schema" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/3-mutation-test-schema.png?fit=353%2C580&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/3-mutation-test-schema.png?resize=353%2C580&#038;ssl=1" alt="Schema of mutation testing" class="wp-image-4847" style="width:353px;height:auto"/></figure>
</div>


<p></p>



<p>But why would anyone change the production code on purpose by introducing some stupid changes? It may seem counterintuitive for now, but let&#8217;s see how we can use it to our leverage.</p>



<h2 class="wp-block-heading">Mutation Testing with Stryker Mutator</h2>



<p>Let&#8217;s clearly state what we are starting with:</p>



<p><strong>8 unit tests, 100% code coverage</strong></p>



<p>Let&#8217;s now run mutation testing on our code. We are using TypeScript here, so let&#8217;s go with <a href="https://stryker-mutator.io/">Stryker Mutator</a>.</p>



<p>Here&#8217;s the result of running Stryker with <code>npx stryker run</code> on our code:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="958" height="163" data-attachment-id="4854" data-permalink="https://www.codejourney.net/what-is-mutation-testing-and-why-you-should-use-it/4-stryker-mutator-1/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/4-stryker-mutator-1.jpg?fit=958%2C163&amp;ssl=1" data-orig-size="958,163" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="4-stryker-mutator-1" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/4-stryker-mutator-1.jpg?fit=958%2C163&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/4-stryker-mutator-1.jpg?resize=958%2C163&#038;ssl=1" alt="Mutation test result - first run. Mutation score 78%, survived mutants 15" class="wp-image-4854" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/4-stryker-mutator-1.jpg?w=958&amp;ssl=1 958w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/4-stryker-mutator-1.jpg?resize=768%2C131&amp;ssl=1 768w" sizes="auto, (max-width: 958px) 100vw, 958px" /></figure>
</div>


<p></p>



<p>As you can see, 53 mutants were killed, but 15 of them survived. This gives us a mutation score of 78%. Let&#8217;s call it <em>mutation coverage</em> from now on. So to make it clear, this is our starting situation:</p>



<p><strong>8 unit tests, 100% code coverage, 78% mutation coverage</strong></p>



<p>Let&#8217;s now see how to kill those remaining mutants.</p>



<h2 class="wp-block-heading">Killing First Mutants</h2>



<p>In order to kill the mutants and improve our mutation score, we need to write more unit tests. Sounds logical, doesn&#8217;t it?</p>



<p>If still not, let&#8217;s take a deeper look at mutation tests results in VS Code. Stryker lists details of every survived mutant, for example this one:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="864" height="198" data-attachment-id="4855" data-permalink="https://www.codejourney.net/what-is-mutation-testing-and-why-you-should-use-it/5-stryker-mutant-1/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/5-stryker-mutant-1.jpg?fit=864%2C198&amp;ssl=1" data-orig-size="864,198" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="5-stryker-mutant-1" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/5-stryker-mutant-1.jpg?fit=864%2C198&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/5-stryker-mutant-1.jpg?resize=864%2C198&#038;ssl=1" alt="First mutant generated by Stryker" class="wp-image-4855" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/5-stryker-mutant-1.jpg?w=864&amp;ssl=1 864w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/5-stryker-mutant-1.jpg?resize=768%2C176&amp;ssl=1 768w" sizes="auto, (max-width: 864px) 100vw, 864px" /></figure>
</div>


<p></p>



<p>Stryker changed the greater or equal (<code>>=</code>) operator to greater operator (<code>></code>). This is a very common and very useful mutation. It usually means that our tests don&#8217;t cover the edge case associated with this particular condition.</p>



<p>In this case, the edge case value seems to be <code>5</code>. More precisely, what happens if the number of business class tickets is <em>exactly 5</em>? We don&#8217;t know, because there is no test for this particular edge case!</p>



<p>Let&#8217;s add it:</p>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler wp-block-embed-embed-handler"><div class="wp-block-embed__wrapper">
<style>.gist table { margin-bottom: 0; }</style><div style="tab-size: 8" id="gist133063837" class="gist">
    <div class="gist-file" translate="no" data-color-mode="light" data-light-theme="light">
      <div class="gist-data">
        
<div class="js-gist-file-update-container js-task-list-container">
      <div id="file-ticketspricecalculator_edgecase-test-ts" class="file my-2">
    
    <div itemprop="text"
      class="Box-body p-0 blob-wrapper data type-typescript  "
      style="overflow: auto" tabindex="0" role="region"
      aria-label="ticketsPriceCalculator_edgeCase.test.ts content, created by dsibinski on 05:23PM on October 01, 2024."
    >

        
<div class="js-check-hidden-unicode js-blob-code-container blob-code-content">

  <template class="js-file-alert-template">
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
    <span>
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div></template>
<template class="js-line-alert-template">
  <span aria-label="This line has hidden Unicode characters" data-view-component="true" class="line-alert tooltipped tooltipped-e">
    <svg aria-hidden="true" data-component="Octicon" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true" class="octicon octicon-alert">
    <path d="M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z"></path>
</svg>
</span></template>

  <table data-hpc class="highlight tab-size js-file-line-container" data-tab-size="4" data-paste-markdown-skip data-tagsearch-path="ticketsPriceCalculator_edgeCase.test.ts">
        <tr>
          <td id="file-ticketspricecalculator_edgecase-test-ts-L1" class="blob-num js-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-ticketspricecalculator_edgecase-test-ts-LC1" class="blob-code blob-code-inner js-file-line">  test(&quot;should apply 10% discount if there are exactly 5 business class tickets&quot;, () =&gt; {</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator_edgecase-test-ts-L2" class="blob-num js-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-ticketspricecalculator_edgecase-test-ts-LC2" class="blob-code blob-code-inner js-file-line">    const tickets = Array.from({ length: 5 }, () =&gt; ({</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator_edgecase-test-ts-L3" class="blob-num js-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-ticketspricecalculator_edgecase-test-ts-LC3" class="blob-code blob-code-inner js-file-line">      price: 10,</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator_edgecase-test-ts-L4" class="blob-num js-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-ticketspricecalculator_edgecase-test-ts-LC4" class="blob-code blob-code-inner js-file-line">      isBusinessClass: true,</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator_edgecase-test-ts-L5" class="blob-num js-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-ticketspricecalculator_edgecase-test-ts-LC5" class="blob-code blob-code-inner js-file-line">    }));</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator_edgecase-test-ts-L6" class="blob-num js-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-ticketspricecalculator_edgecase-test-ts-LC6" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator_edgecase-test-ts-L7" class="blob-num js-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-ticketspricecalculator_edgecase-test-ts-LC7" class="blob-code blob-code-inner js-file-line">    const totalPrice = calculator.calculateTotalTicketsPrice(tickets);</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator_edgecase-test-ts-L8" class="blob-num js-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-ticketspricecalculator_edgecase-test-ts-LC8" class="blob-code blob-code-inner js-file-line">    expect(totalPrice).toBe(45); // 10% discount</td>
        </tr>
        <tr>
          <td id="file-ticketspricecalculator_edgecase-test-ts-L9" class="blob-num js-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-ticketspricecalculator_edgecase-test-ts-LC9" class="blob-code blob-code-inner js-file-line">  });</td>
        </tr>
  </table>
</div>


    </div>

  </div>

</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/dsibinski/ee04a5c91df633a66935ed6a663f3ae1/raw/836811b2f5ba7f306346a9c11f4fe7de42ce2b89/ticketsPriceCalculator_edgeCase.test.ts" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/dsibinski/ee04a5c91df633a66935ed6a663f3ae1#file-ticketspricecalculator_edgecase-test-ts" class="Link--inTextBlock">
          ticketsPriceCalculator_edgeCase.test.ts
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>

</div></figure>



<p>The test passes. Let&#8217;s run mutation tests again:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="961" height="166" data-attachment-id="4856" data-permalink="https://www.codejourney.net/what-is-mutation-testing-and-why-you-should-use-it/6-stryker-mutator-2/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/6-stryker-mutator-2.jpg?fit=961%2C166&amp;ssl=1" data-orig-size="961,166" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="6-stryker-mutator-2" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/6-stryker-mutator-2.jpg?fit=961%2C166&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/6-stryker-mutator-2.jpg?resize=961%2C166&#038;ssl=1" alt="Struker Mutator second run - already 14 mutants survived and almost 80% mutation coverage" class="wp-image-4856" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/6-stryker-mutator-2.jpg?w=961&amp;ssl=1 961w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/6-stryker-mutator-2.jpg?resize=768%2C133&amp;ssl=1 768w" sizes="auto, (max-width: 961px) 100vw, 961px" /></figure>
</div>


<p></p>



<p>That&#8217;s it! We have a new unit test and 1 more mutant killed <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f389.png" alt="🎉" class="wp-smiley" style="height: 1em; max-height: 1em;" />  Current state:</p>



<p><strong>9 (+1) unit tests, 100% code coverage, 79% mutation coverage</strong></p>



<p>I think you&#8217;re now getting what this is all about. We should be adding unit tests to cover the edge cases detected by mutations until all (or most) mutants are killed.</p>



<h2 class="wp-block-heading">Mutation Testing &#8211; Free Unit Tests Generator</h2>



<p>After adding 1 more test, the results look as follows:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="960" height="164" data-attachment-id="4859" data-permalink="https://www.codejourney.net/what-is-mutation-testing-and-why-you-should-use-it/7-stryker-mutator-3/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/7-stryker-mutator-3.jpg?fit=960%2C164&amp;ssl=1" data-orig-size="960,164" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="7-stryker-mutator-3" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/7-stryker-mutator-3.jpg?fit=960%2C164&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/7-stryker-mutator-3.jpg?resize=960%2C164&#038;ssl=1" alt="Struker mutator with 10 tests - 86% mutation coverage" class="wp-image-4859" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/7-stryker-mutator-3.jpg?w=960&amp;ssl=1 960w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/7-stryker-mutator-3.jpg?resize=768%2C131&amp;ssl=1 768w" sizes="auto, (max-width: 960px) 100vw, 960px" /></figure>
</div>


<p></p>



<p><strong>10 (+2) unit tests, 100% code coverage, 86% mutation coverage</strong></p>



<p>Finally, this is what we managed to get after a few minutes of work:</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img data-recalc-dims="1" loading="lazy" decoding="async" width="959" height="165" data-attachment-id="4860" data-permalink="https://www.codejourney.net/what-is-mutation-testing-and-why-you-should-use-it/8-stryker-mutator-4/" data-orig-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/8-stryker-mutator-4.jpg?fit=959%2C165&amp;ssl=1" data-orig-size="959,165" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="8-stryker-mutator-4" data-image-description="" data-image-caption="" data-large-file="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/8-stryker-mutator-4.jpg?fit=959%2C165&amp;ssl=1" src="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/8-stryker-mutator-4.jpg?resize=959%2C165&#038;ssl=1" alt="" class="wp-image-4860" srcset="https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/8-stryker-mutator-4.jpg?w=959&amp;ssl=1 959w, https://i0.wp.com/www.codejourney.net/wp-content/uploads/2024/10/8-stryker-mutator-4.jpg?resize=768%2C132&amp;ssl=1 768w" sizes="auto, (max-width: 959px) 100vw, 959px" /></figure>
</div>


<p></p>



<p>And we now have 17 unit tests in our suite! The final score looks like that:</p>



<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f38a.png" alt="🎊" class="wp-smiley" style="height: 1em; max-height: 1em;" /><strong>17 (+9) unit tests, 100% code coverage, 96% mutation coverage</strong> <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f38a.png" alt="🎊" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p>Notice what happened here. <strong>We started with 8 unit tests and finished with 17! This is awesome! That&#8217;s how mutation testing is a free unit tests generator</strong>. And you don&#8217;t even need AI for that <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p>What&#8217;s more, the generated mutations even forced me to make a little tweak to the production code. It exposed some things that didn&#8217;t make sense. I could make this change to the production code, because my tests&#8217; suite was already quite substantial.</p>



<p>Note that I didn&#8217;t push to gain 100% mutation coverage. The 3 mutants that survived don&#8217;t make much sense in our case. I encourage you to <a href="https://github.com/dsibinski/codejourney/tree/main/mutation-testing">get the code</a> and execute <code>npx stryker run</code> in the application folder to see for yourself <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p>The percentage value doesn&#8217;t matter in that case. What matters is that we got 9 new unit tests and our tests&#8217; suite is more robust. Now we can go and tell our manager that the business-critical code is well tested <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f60a.png" alt="😊" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h2 class="wp-block-heading">So What Now?</h2>



<p>I hope you see how valuable mutation testing is. It&#8217;s not a perfect tool that suits all cases. For example, it&#8217;s not easy to use mutation testing for complex legacy code. However, if your logic is nicely isolated, it could be a great tool. Especially if your production code heavily depends on calculations and many conditions. You may be surprised how many edge cases mutation testing can find.</p>



<p>I also love using mutation testing with TDD. These two techniques nicely complement each other.</p>



<p>I encourage you to go and try mutation testing. There are different mutation tools for various programming languages:</p>



<ul class="wp-block-list">
<li>C#, JavaScript, TypeScript, Scala: <a href="https://stryker-mutator.io/">Stryker Mutator</a></li>



<li>Ruby: <a href="https://github.com/mbj/mutant">mutant</a></li>



<li>Java: <a href="https://pitest.org/">pitest</a></li>



<li>PHP: <a href="https://infection.github.io/">Infection</a></li>



<li>C++: <a href="https://github.com/nlohmann/mutate_cpp">Mutate++</a></li>
</ul>



<p>&#8230;and probably many more. Just do some research for the language you work with and give it a try <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Because <a href="https://www.codejourney.net/improve-your-tests-with-assert-object-pattern/">testing</a> is cool, isn&#8217;t it? <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p>You can find the full source code used in this article <a href="https://github.com/dsibinski/codejourney/tree/main/mutation-testing">here</a>.</p>
<p>The post <a href="https://www.codejourney.net/what-is-mutation-testing-and-why-you-should-use-it/">What is Mutation Testing and Why Should You Use It?</a> appeared first on <a href="https://www.codejourney.net">CodeJourney.net</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.codejourney.net/what-is-mutation-testing-and-why-you-should-use-it/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">4825</post-id>	</item>
	</channel>
</rss>
