<?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>Forem: Guilherme Guitte</title>
    <description>The latest articles on Forem by Guilherme Guitte (@guilhermeguitte).</description>
    <link>https://forem.com/guilhermeguitte</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%2F432521%2Fd66e0ed8-acb4-484f-b23c-19fc9b8f41f3.jpeg</url>
      <title>Forem: Guilherme Guitte</title>
      <link>https://forem.com/guilhermeguitte</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/guilhermeguitte"/>
    <language>en</language>
    <item>
      <title>👾 Mutation testing on Go</title>
      <dc:creator>Guilherme Guitte</dc:creator>
      <pubDate>Mon, 02 Aug 2021 15:29:44 +0000</pubDate>
      <link>https://forem.com/guilhermeguitte/mutation-testing-on-go-1lbf</link>
      <guid>https://forem.com/guilhermeguitte/mutation-testing-on-go-1lbf</guid>
      <description>&lt;p&gt;One of the Developer's goals is to improve the healthiness of codebases. Fortunately, automated testing is a widely known practice to decrease production cycles and receive accelerated feedback. But, how we can check if our test suite are healthy? One of the techniques on automated testing to identify weak spots of dead/untested code is &lt;strong&gt;Mutation Testing&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is Mutation Testing? 👾
&lt;/h2&gt;

&lt;p&gt;Mutation testing or known as Mutation Analysis, involves to modifies an application in small ways programmatically and running against your test suite looking for weak spots of your code that has not test for a specific mutation. &lt;/p&gt;

&lt;p&gt;Fundamental concepts involved over Mutation Testing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Mutants&lt;/strong&gt;: a modified version that will test against a testing suite.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mutation Score&lt;/strong&gt;: percentage of &lt;strong&gt;passed mutation/total mutation created total&lt;/strong&gt;. 
0 means all mutations created are &lt;em&gt;alive&lt;/em&gt; 👾, so the tests are probably has not good coverage.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Mutation operators/mutators&lt;/strong&gt;: A mutator is an operation applied to the original code. Many types of mutators can be applied. It is important to check which mutators are available for your mutation tool.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Equivalent Mutations&lt;/strong&gt;: Are false-positives mutants. Sometimes, it will found a mutated version that has no practical changes. Often, they can mean a dead/useless code in the application.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  When to use Mutation Testing?
&lt;/h2&gt;

&lt;p&gt;It is an exciting alternative to the code coverage we see over different open source projects. One caveat about mutation testing that, for larger codebases, mutation testing can consume a significant amount of resources. So it can be decide to run it periodically through the codebase, not each push to your git remote repository.&lt;/p&gt;




&lt;h2&gt;
  
  
  Mutation Testing in Go
&lt;/h2&gt;

&lt;p&gt;In practice, how mutation testing works? Let's see the follow code sample that will be the production code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;GreetingsByLocale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;localestring&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

   &lt;span class="n"&gt;greetings&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;resolveGreetings&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;locale&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;greetings&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Sorry, we didn't identified you"&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;greetings&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;resolveGreetings&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;localestring&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;locale&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"en"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Hello"&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;

   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;locale&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"pt"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Olá"&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;

   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The example above, implements a very straightforward &lt;code&gt;GreetingByLocale&lt;/code&gt; function, that returns the appropriated greetings by locale. Example: &lt;code&gt;en&lt;/code&gt; , &lt;code&gt;pt&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To running a mutation testing in Go, we have to install a mutation testing tool. For this article I've choose &lt;a href="https://github.com/zimmski/go-mutesting"&gt;go-mutesting&lt;/a&gt; based what I was looking for at &lt;a href="https://github.com/avelino/awesome-go"&gt;awesome-go&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to install
&lt;/h2&gt;

&lt;p&gt;Running the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go get &lt;span class="nt"&gt;-t&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; github.com/zimmski/go-mutesting/...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will be ready to run the follow command without problem normally. If you have any problems, check it out &lt;a href="https://github.com/zimmski/go-mutesting"&gt;documentation&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go-mutesting main.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The command above, will produce:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nt"&gt;--------&lt;/span&gt; main.go   2021-06-06 14:33:00.000000000 +0200
+++ /var/folders/y0/z16t6n116rxgq599drwq_z31r3w4v8/T/go-mutesting-406451808/basics-ut/main.go.0 2021-06-06 14:41:17.000000000 +0200
@@ &lt;span class="nt"&gt;-5&lt;/span&gt;,7 +5,7 @@
        greetings :&lt;span class="o"&gt;=&lt;/span&gt; resolveGreetings&lt;span class="o"&gt;(&lt;/span&gt;locale&lt;span class="o"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;if &lt;/span&gt;greetings &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
-               &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;"Sorry, we didn't identified you"&lt;/span&gt;
+
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;return &lt;/span&gt;greetings
@@ &lt;span class="nt"&gt;-21&lt;/span&gt;,4 +21,4 @@
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
-&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="se"&gt;\ &lt;/span&gt;No newline at end of file
+&lt;span class="o"&gt;}&lt;/span&gt;

...

FAIL &lt;span class="s2"&gt;"/var/folders/y0/z16t6n116rxgq599drwq_z31r3w4v8/T/go-mutesting-406451808/basics-ut/main.go.2"&lt;/span&gt; with checksum 7543b5d5e97c3a66dec555fb1c908957
The mutation score is 0.000000 &lt;span class="o"&gt;(&lt;/span&gt;0 passed, 3 failed, 0 duplicated, 0 skipped, total is 3&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  What information you should take care of?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Mutation Score&lt;/strong&gt;: Percentage over &lt;strong&gt;passed mutation / mutation created total.&lt;/strong&gt;  0 means all mutation created are &lt;strong&gt;alive,&lt;/strong&gt; so the tests are probably not covering the whole usage of this package.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mutation&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;greetings&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt;               &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Sorry, we didn't identified you"&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output of mutation testing explains which it was modified that make the &lt;strong&gt;testing suite failed&lt;/strong&gt;. &lt;/p&gt;




&lt;h2&gt;
  
  
  Fixing Mutations
&lt;/h2&gt;

&lt;p&gt;You need to created the appropriated tests that covers the mutation. For it, you can implement something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;TestGreetingsByLocaleByDefault&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;testing&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;greetings&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;GreetingsByLocale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;greetings&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s"&gt;"Sorry, we didn't identified you"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"greeting() = %v; want 'Sorry, we didn't identified you'"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;greetings&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;Running again &lt;code&gt;go-mutesting&lt;/code&gt;, you should see this output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;go-mutesting main.go

PASS &lt;span class="s2"&gt;"/var/folders/y0/z16t6n116rxgq599drwq_z31r3w4v8/T/go-mutesting-610805264/basics-ut/main.go.0"&lt;/span&gt; with checksum 73ab3954dddfcf60d062bf280b49e996
PASS &lt;span class="s2"&gt;"/var/folders/y0/z16t6n116rxgq599drwq_z31r3w4v8/T/go-mutesting-610805264/basics-ut/main.go.1"&lt;/span&gt; with checksum 0a29bb0da18ff5c339c726f678c8f4b9
PASS &lt;span class="s2"&gt;"/var/folders/y0/z16t6n116rxgq599drwq_z31r3w4v8/T/go-mutesting-610805264/basics-ut/main.go.2"&lt;/span&gt; with checksum 7543b5d5e97c3a66dec555fb1c908957
The mutation score is 1.000000 &lt;span class="o"&gt;(&lt;/span&gt;3 passed, 0 failed, 0 duplicated, 0 skipped, total is 3&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Perfect! We fix all mutations found.&lt;/p&gt;




&lt;h2&gt;
  
  
  Going further
&lt;/h2&gt;

&lt;p&gt;Mutation testing is very powerful technique to spot weak coverage points of your test suite. Some links you can found useful:&lt;/p&gt;

&lt;p&gt;Explanation about mutation testing: &lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Mutation_testing"&gt;https://en.wikipedia.org/wiki/Mutation_testing&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Mutation testing tools by language:&lt;br&gt;
&lt;a href="https://github.com/theofidry/awesome-mutation-testing"&gt;https://github.com/theofidry/awesome-mutation-testing&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Mutation testing tool for Go:&lt;br&gt;
&lt;a href="https://github.com/zimmski/go-mutesting"&gt;https://github.com/zimmski/go-mutesting&lt;/a&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>testdev</category>
      <category>testing</category>
    </item>
  </channel>
</rss>
