PageSourceSearch

https://stryker-mutator.io/assets/js/c2a0512a.8391bfda.js

js stryker-mutator.io collected 2026-09-24 17:55:14 UTC 5,349 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunkstryker_mutator_github_io=self.webpackChunkstryker_mutator_github_io||[]).push([["7323"],{34064:function(e,n,t){t.r(n),t.d(n,{metadata:function(){return i},default:function(){return l},frontMatter:function(){return a},contentTitle:function(){return r},toc:function(){return u},assets:function(){return c}});var i=JSON.parse('{"id":"mutation-testing-elements/equivalent-mutants","title":"Equivalent mutants","description":"Suppose you are writing a big chunk of code. You have decided to run both unit and mutation tests.","source":"@site/docs/mutation-testing-elements/equivalent-mutants.md","sourceDirName":"mutation-testing-elements","slug":"/mutation-testing-elements/equivalent-mutants","permalink":"/docs/mutation-testing-elements/equivalent-mutants","draft":false,"unlisted":false,"editUrl":"https://github.com/stryker-mutator/mutation-testing-elements/edit/master/docs/equivalent-mutants.md","tags":[],"version":"current","frontMatter":{"title":"Equivalent mutants","custom_edit_url":"https://github.com/stryker-mutator/mutation-testing-elements/edit/master/docs/equivalent-mutants.md"},"sidebar":"docs","previous":{"title":"FAQ","permalink":"/docs/General/faq"},"next":{"title":"Implementing real-time reporting","permalink":"/docs/mutation-testing-elements/implementing-real-time-reporting"}}'),o=t(91987),s=t(67008);let a={title:"Equivalent mutants",custom_edit_url:"https://github.com/stryker-mutator/mutation-testing-elements/edit/master/docs/equivalent-mutants.md"},r,c={},u=[];function m(e){let n={code:"code",em:"em",p:"p",pre:"pre",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.p,{children:'Suppose you are writing a big chunk of code. You have decided to run both unit and mutation tests.\nYour score of unit tests is 100% and mutation 99%. You think "I\'ll make that 100%". After some work, you notice this part of your co
1de:'}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-js",children:"var max = Math.max(a.comma, b.comma);\nvar min = Math.min(a.comma, b.comma);\nif (a.comma >= b.comma) {\n  a.number *= 10 ** (max - min);\n} else {\n  b.number *= 10 ** (max - min);\n}\n"})}),"\n",(0,o.jsx)(n.p,{children:"Let's analyse this example."}),"\n",(0,o.jsxs)(n.p,{children:["Assume ",(0,o.jsx)(n.code,{children:"a.comma"})," is greater than ",(0,o.jsx)(n.code,{children:"b.comma"}),". For example 4 and 2"]}),"\n",(0,o.jsx)(n.p,{children:"We get that"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-js",children:"max = 4;\nmin = 2;\nif (4 >= 2) {\n  a.number *= 10 ** 2;\n} else {\n  b.number *= 10 ** 2;\n}\n"})}),"\n",(0,o.jsxs)(n.p,{children:["if we change ",(0,o.jsx)(n.code,{children:">="})," sign in our source code to ",(0,o.jsx)(n.code,{children:"<="})," it won't work, so our mutant is killed."]}),"\n",(0,o.jsx)(n.p,{children:"If we change 4 and 2 to 3 and 5, we will get the same output: mutant will be killed.\nBut what if we have both values the same? Let's say: 3, 3"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-js",children:"max = 3;\nmin = 3;\nif (3 >= 3) {\n  a.number *= 10 ** 0;\n} else {\n  b.number *= 10 ** 0;\n}\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Notice that 10 ** 0 = 1, so even if we change ",(0,o.jsx)(n.code,{children:">="})," to ",(0,o.jsx)(n.code,{children:"<="})," and even ",(0,o.jsx)(n.code,{children:"<"})," or ",(0,o.jsx)(n.code,{children:">"})," we will get the same output each time!"]}),"\n",(0,o.jsxs)(n.p,{children:["It is called ",(0,o.jsx)(n.em,{children:"equivalent mutant"}),". There is no definitive way for Stryker to find and ignore them. There is currently also no way yet to mark them to be ignored."]}),"\n",(0,o.jsx)(n.p,{children:"For now, the only solution is by finding these by hand, which is time consuming and try to rewrite the code so it won't occur, or accept that you won't make 100%."}),"\n",(0,o.jsx)(n.p,{children:"First one has been shown above. The easiest schema for this mutant is:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-js",children:"if(whatever condition) {\n  number1 += 0  // can be `-= 0` or `*= 1` `/= 1`\n} else {\n  number2 += 0  // can be `-= 0` or `*= 1` `/= 1`\n}\n"})}),"\n",(0,o.jsxs)(n.p,{children:["The second one we have found is about ",(0,o.jsx)(n.code,{children:"BigInt"}),"\nsince ",(0,o.jsx)(n.code,{children:"-0n"})," is transformed to ",(0,o.jsx)(n.code,{children:"0n"}),", doing"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-js",children:"a = 0n;\na = a <= 0n ? -a : a;\n"})}),"\n",(0,o.jsx)(n.p,{children:"will produce another equivalent mutant."}),"\n",(0,o.jsx)(n.p,{children:"So knowing that for now, help us find more of them and don't be scared of not 100% mutation score!"})]})}function l(e={}){let{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(m,{...e})}):m(e)}},67008:function(e,n,t){t.d(n,{R:function(){return a},x:function(){return r}});var i=t(71763);let o={},s=i.createContext(o);function a(e){let n=i.useContext(s);return i.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.