{"id":914,"date":"2010-06-17T00:00:00","date_gmt":"2010-06-17T00:00:00","guid":{"rendered":"https:\/\/test.simple-talk.com\/uncategorized\/mutation-testing\/"},"modified":"2021-05-11T15:56:32","modified_gmt":"2021-05-11T15:56:32","slug":"mutation-testing","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/development\/dotnet-development\/mutation-testing\/","title":{"rendered":"Mutation Testing"},"content":{"rendered":"<h2>What is Mutation Testing?<\/h2>\n<p>How do you know that you can trust your unit tests?\u00a0 How do you know that they&#8217;re really telling you the truth?\u00a0 If they don&#8217;t find a bug, does that really mean that there aren&#8217;t any?\u00a0 What if you could test your tests?<\/p>\n<p>Mutation testing \u00a0is one way that you can test those tests.\u00a0 Mutation testing involves deliberately altering a program&#8217;s code, then re-running a suite of valid unit tests against the mutated program.\u00a0 A good unit test will detect the change in the program and fail accordingly.<\/p>\n<p>There has recently been a resurgence of interest in Mutation testing, which was actually first conceived of by Richard Lipton in 1971, resulting in mutation testers appearing on many different platforms.\u00a0 Some notable examples are Java&#8217;s <a href=\"https:\/\/cs.gmu.edu\/~offutt\/mujava\/\">\u03bcJava<\/a>, Ruby&#8217;s <a href=\"https:\/\/github.com\/seattlerb\/heckle\">Heckle<\/a>, C++&#8217;s <a href=\"http:\/\/www.parasoft.com\/products\/insure\">Insure++<\/a>, and of course, C#&#8217;s <a href=\"http:\/\/nester.sourceforge.net\/\">Nester<\/a>.<\/p>\n<h2>How Does Mutation Testing Work?<\/h2>\n<p>In a nutshell, mutation testing works in the following way.\u00a0 First you start with a piece of production code that&#8217;s well covered by unit tests.\u00a0 Once you&#8217;ve verified that all tests pass for a given piece of code it&#8217;s time to apply your mutation to your target assembly.\u00a0<\/p>\n<p>The extent of the mutation that you apply to your code can span many levels; some of the more common mutations simply involve replacing a logical operator with its inverse.\u00a0 For example, <b><code>==<\/code><\/b> can become <b><code>!=<\/code><\/b> while <b><code>&lt;<\/code><\/b> can become <b><code>&gt;=<\/code><\/b>.\u00a0 In more complex mutations you may go so far as to rework the order of execution of code or even remove some lines of code completely.\u00a0 However, as mutations of this level can often cause compiler errors, it&#8217;s often easier to initially stick with the simpler mutations that I&#8217;ve mentioned.<\/p>\n<p>After your code has been mutated, it&#8217;s time to re-run your original suite of unit tests against it.\u00a0 If your tests are well written, any test that covers the mutated program code should fail.\u00a0 However, if your tests succeed in spite of the mutated program code then your tests are creating false positives and need to be revisited.<\/p>\n<h2>Building Your Own Mutation Tester<\/h2>\n<p>Although there are a few mutation testers available for .NET, the best way to learn any technique is by writing your own.\u00a0 Over the next few paragraphs, we&#8217;ll walk through building our own simple mutation tester to test the test suite of a simple program.<\/p>\n<h2>Something to Mutate<\/h2>\n<p>But before we can build our mutation tester, we need a program to test.\u00a0FirstBank, <a href=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/plugins\/download-attachments\/includes\/download.php?id=57911\">available here<\/a>, is a simple banking library we can use as our guinea pig.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"float-right\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1061-MT1.JPG\" alt=\"1061-MT1.JPG\" width=\"277\" height=\"307\" \/><\/p>\n<p>Let&#8217;s take a moment to familiarize ourselves with <b>FirstBank<\/b>.\u00a0 First, we&#8217;ll note that there are two projects in the solution.\u00a0 The first project, <b><code>FirstBank.Model<\/code><\/b> contains the production code for a simple <b><code>Account<\/code><\/b>, <b><code>AccountManager<\/code><\/b>, and an exception to represent when an account has insufficient funds to perform an action.\u00a0 There&#8217;s also an interface defined for an interest rate service.\u00a0 The second project, <b><code>FirstBank.Model.Tests<\/code><\/b>, simply contains the unit tests which target the first project.<\/p>\n<p>Let&#8217;s take a closer look at the <b><code>Account<\/code><\/b> class.<\/p>\n<p>The <b><code>Account<\/code><\/b> class has two methods-<b><code>Withdraw()<\/code><\/b> and <b><code>Deposit()<\/code>,<\/b> as well as a single property-<b><code>Balance<\/code><\/b>.\u00a0 The <b><code>Deposit()<\/code><\/b> method simply accepts an amount from the caller and adds it to the account&#8217;s current balance.\u00a0 The <b><code>Withdraw()<\/code><\/b> method accepts an amount from the caller and deducts it from the account&#8217;s current balance.\u00a0 However, the <b><code>Withdraw()<\/code><\/b> method also has a check to ensure that the caller isn&#8217;t attempting to withdraw more than the account&#8217;s current balance.\u00a0 In the event that the caller asks for more than the current balance an exception of type <b><code>InsufficientFundsException<\/code><\/b> is thrown.<\/p>\n<pre class=\"lang:c# theme:vs2012\">public void Withdraw(decimal amount)\r\n{\r\n\u00a0\u00a0\u00a0 if (amount &gt; Balance)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 throw new InsufficientFundsException(amount, Balance);\r\n\u00a0\r\n\u00a0\u00a0\u00a0\u00a0Balance -= amount;\r\n}\r\n<\/pre>\n<p>Now that we&#8217;re familiar with the key parts of the FirstBank solution, let&#8217;s move onto our mutation tester.<\/p>\n<h2>MutantPower<\/h2>\n<p>MutantPower is a <i>very<\/i> simple mutation tester that simply inverts any Boolean conditionals that it finds in the code.\u00a0 I&#8217;ve intentionally kept MutantPower simple for two reasons.\u00a0 First, MutantPower is only really intended to be run against the FirstBank solution therefore it only needs to handle the few branching operations it encounters within that solution.\u00a0 Secondly, the simpler we keep the MutantPower codebase the easier it&#8217;ll be for us to talk about.\u00a0 MutantPower relies heavily on the <a href=\"http:\/\/www.mono-project.com\">Mono Project&#8217;s<\/a> <a href=\"http:\/\/www.mono-project.com\/Cecil\">Cecil<\/a> library to handle both traversing the object graph and the IL manipulation of .NET assemblies.\u00a0 You can download <a href=\"http:\/\/www.simple-talk.com\/content\/file.ashx?file=3746\">the source code for MutantPower here<\/a>.<\/p>\n<div class=\"note\">\n<p class=\"note\">Why Cecil?<\/p>\n<p> Cecil was created as part of the Mono Project, which is an open source implementation of the .NET framework. Cecil is used heavily in many of Mono&#8217;s own development tools such as the Mono debugger and Gendarme, which is an FxCop-like static analysis tool. Although Cecil is actually an open source implementation of .NET&#8217;s Reflection.Emit library and has very similar capabilities, I tend to prefer Cecil over Reflection.Emit since it offers some more advanced functionality. In addition, since it&#8217;s not necessary for Cecil to actually load the target assembly into memory, Cecil tends to perform noticeably faster than Reflection.Emit.<\/p>\n<\/div>\n<p>MutantPower begins by loading the target assembly, passed as a command line parameter, into a <b><code>ModuleDefinition<\/code><\/b> object.\u00a0 It then iterates through all of the types it finds in the module.\u00a0 In our example, these are types such as <b><code>Account<\/code><\/b>,<b> <code>AccountManager<\/code><\/b>, and <b><code>InsufficientFundsException<\/code><\/b>.\u00a0 Note that we ignore any type which is actually an interface, such as <b><code>IInterestRateService<\/code><\/b>.\u00a0 The reason for this is that although interfaces do have members, those members do not have bodies so they have no IL to manipulate.\u00a0 Therefore interfaces are of little interest to a mutation tester.<\/p>\n<pre class=\"lang:c# theme:vs2012\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 var module = ModuleDefinition.ReadModule(inputAssembly);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 foreach (var typeDefinition in module.Types)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 if (typeDefinition.IsInterface)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 continue;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 foreach (var methodDefinition in typeDefinition.Methods)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 foreach (var instruction in methodDefinition.Body.Instructions)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 . . .\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0}\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"float-left\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1061-MT2.JPG\" alt=\"1061-MT2.JPG\" width=\"330\" height=\"327\" \/><\/p>\n<p>Within each type we also iterate though that type&#8217;s methods.\u00a0 This allows us to examine all methods of a class, regardless of visibility.\u00a0 What about properties?\u00a0 In C# properties are actually just syntactic sugar around specially named methods.\u00a0 So, in the IL world in which we&#8217;re working now, properties simply show up as just another method.\u00a0 For example, when we reflect over the <b><code>Account<\/code><\/b> class&#8217;s <b><code>Balance<\/code><\/b> property we see that the property actually exists in IL as two separate methods named <b><code>get<\/code><\/b><code>_Balance()<\/code> and <b><code>set<\/code><\/b><code>_Balance(Decimal)<\/code>.\u00a0<\/p>\n<p>Finally, within each method we iterate though the IL statements that comprise its body.\u00a0 You may have noticed that the FirstBank solution contained no abstract classes.\u00a0 However, if we were dealing with a solution that did we would want to take special care here to ignore any abstract methods.\u00a0 Just as interfaces contain no method bodies and thus are of little interest to a mutation tester, abstract methods are also missing method bodies and would be of just as little interest.<\/p>\n<p>Note the code&#8230;<\/p>\n<pre class=\"lang:c# theme:vs2012\">if (instruction.OpCode == OpCodes.Brtrue_S)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 instruction.OpCode = OpCodes.Brfalse_S;\r\n\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0else if (instruction.OpCode == OpCodes.Brfalse_S)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0instruction.OpCode = OpCodes.Brtrue_S;\r\n<\/pre>\n<p>This is the heart of our mutator.\u00a0 This section of code replaces any instance of <b><code>if (true)<\/code><\/b> with <b><code>if (false)<\/code><\/b> and vice versa.\u00a0 Obviously this is a very simple mutator, but if we wanted to extend this to handle some of the other mutations mentioned in the beginning of the article, such as inverting logical comparisons, this is where we could do it.<\/p>\n<p>Finally, after all of the Boolean operators found have been inverted we save the newly mutated assembly back out to disk.\u00a0<\/p>\n<h2>Running Your New Mutation Tester<\/h2>\n<p>Before we begin mutating our assembly, we must first make sure our code is in a good state to begin with.\u00a0 To do this, we need to run our unit tests against our original, un-mutated assembly.<\/p>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1061-MT3.JPG\" alt=\"1061-MT3.JPG\" \/><\/p>\n<p>As you can see, all of our tests pass without incident.\u00a0 Now that we know we&#8217;re starting from a clean slate, it&#8217;s time to mutate.<\/p>\n<p>Our mutator accepts the assembly to be mutated as a command line argument which means that we can call the mutator like so.<\/p>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1061-MT4.JPG\" alt=\"1061-MT4.JPG\" \/><\/p>\n<p>Once the mutator has completed you should have two assemblies in your output folder, <i>FirstBank.Model.dll<\/i> and <i>FirstBank.Model_backup.dll<\/i>.\u00a0 <i>FirstBank.Model_backup.dll<\/i> is actually your original unharmed assembly whereas <i>FirstBank.Model.dll<\/i> is your assembly after the mutations have been applied.\u00a0 It&#8217;s important that the mutated version of the assembly retain the same name as the original assembly.\u00a0 This is so that unit tests that were compiled against it can find the mutated assembly to retest.<\/p>\n<p>If we examine both assemblies using <a href=\"http:\/\/www.red-gate.com\/products\/reflector\/\">Red Gate&#8217;s .NET Reflector\u00c2\u00ae<\/a>, it becomes easy to spot the differences between the mutated version and the original version of the assembly.\u00a0 Looking in the <b><code>Account.Withdraw()<\/code><\/b> method of the original assembly (<i>FirstBank.Model_backup.dll<\/i>) we can see the code is still checking for insufficient funds and throwing the <b><code>InsufficientFundsException<\/code><\/b> as expected.\u00a0 However, if we examine the same method in our newly mutated assembly (FirstBank.Model.dll) we see that the code is actually doing the opposite of what we would expect.\u00a0 In fact, the <b><code>InsufficientFundsException<\/code><\/b> is only thrown if the amount that the account holder has requested is less than or equal to their current balance!<\/p>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1061-MT5.JPG\" alt=\"1061-MT5.JPG\" \/><\/p>\n<p>You may be wondering why inverting the Boolean operators <b><code>true<\/code><\/b> and <b><code>false<\/code><\/b> resulted in the operator <b><code>&gt;<\/code> <\/b>becoming <b><code>&lt;=<\/code><\/b>.\u00a0 To answer this question we&#8217;ll have to examine the underlying IL that results from the C# code above.<\/p>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1061-MT6.JPG\" alt=\"1061-MT6.JPG\" \/><\/p>\n<p>Take a look at line L_0012 in both sections of IL.\u00a0 This is really the only line of code between the two versions of the <b><code>Account.Withdraw()<\/code><\/b> method that exhibited any significant change.\u00a0 That change, as expected, was an inversion of the <b><code>brtrue<\/code><\/b><code>.s<\/code> command to the <b><code>brfalse.s<\/code><\/b> command (the <code>.s<\/code> suffix simply denotes the value we&#8217;re evaluating is stored as an 8-bit short).<\/p>\n<p>A full explanation of IL is well beyond the scope of this article, but in a nutshell the <b><code>brtrue.s<\/code><\/b> and <b><code>brfalse.s<\/code><\/b> commands on line L_0012 simply evaluate the result of the <b><code>op_GreaterThan()<\/code><\/b> command executed on line L_0008, which is stored in location 0.\u00a0 Then, based on whether this value is true or false, line L_0012 instructs the runtime to continue to line L_001b, which throws the <b><code>InsufficientFundsException<\/code><\/b>, or to skip the exception completely and go directly to line L_0021, which continues with the execution of the balance deduction.<\/p>\n<p>The only difference between the two methods is that the original <b><code>Withdraw<\/code><\/b><code>()<\/code> method skips throwing the exception if the results of the <b><code>op_GreaterThan<\/code><\/b><code>()<\/code> operation are true (the balance is greater than the amount requested) whereas the mutated <b><code>Withdraw<\/code><\/b><code>()<\/code> method skips throwing the exception if the results are false (the balance is less than or equal to the amount requested).<\/p>\n<p>The interesting part is that our mutation didn&#8217;t actually change the logical operator we used, but instead it changed the control flow resulting from the execution of that operator.<\/p>\n<p>Let&#8217;s see how this new mutation affects our previously 100% green test suite.<\/p>\n<p>After running our test suite against our mutated assembly we see that we now have a mixture of both passing and failing tests.\u00a0 Unlike traditional unit testing, we actually strive for 100% of our tests failing when doing mutation testing.\u00a0 Why?\u00a0 Because if our tests failed after the code was mutated then we know they&#8217;re serving us well as regression tests by detecting changes in logic.<\/p>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1061-MT7.JPG\" alt=\"1061-MT7.JPG\" \/><\/p>\n<p>Let&#8217;s start by looking at which tests failed.<\/p>\n<p><code>AccountTest.Can_withdraw_money_from_an_account<\/code><\/p>\n<p class=\"indented\">This test failed because the Withdraw() method threw an InsufficientFundsException even though the caller was trying to withdraw less than their current account balance.\u00a0 However, this is exactly the behavior our mutated code now prescribes so this test successfully caught the mutation.<\/p>\n<p><code>AccountTest.Will_throw_InsufficientFundsException_when_trying_to_ withdraw_more_than_account_balance<\/code><\/p>\n<p class=\"indented\">This test also failed but for the opposite reason than the test above.\u00a0 In this test the caller was able to withdraw more than their account balance without triggering an exception.\u00a0 Although this likely made the caller quite happy, their bank was likely less than thrilled with this new &#8216;feature&#8217;.\u00a0 This test also appears to be behaving exactly how we would expect it to..<\/p>\n<p><code>AccountManagerTest.Can_transfer_money_from_one_account_to_another<\/code><\/p>\n<p class=\"indented\">Finally, a test in the<b> <code>AccountManagerTest<\/code><\/b> suite failed as well.\u00a0 This may seem a bit unexpected at first since we only mutated code in the <b><code>Account.Withdraw()<\/code><\/b> method.\u00a0 However, once we examine the <b><code>AccountManager.TransferFunds()<\/code><\/b> method the reason becomes obvious.\u00a0 The <b><code>TransferFunds()<\/code><\/b> method actually calls the <b><code>Account.Withdraw()<\/code><\/b> method.\u00a0 This means that this test failed for the same reason as the <code>AccountTest.Can_withdraw_money_from_an_account<\/code> method above.<\/p>\n<p>In the vernacular of mutation testing, we would say that the mutant we introduced in the Account.Withdraw() method was &#8216;killed&#8217; by these three tests.<\/p>\n<p>Now let&#8217;s take a look at the tests that passed.<\/p>\n<ul>\n<li>\n<p><code>AccountManagerTest.Can_apply_annual_interest_rate_to_an_account_balance<\/code>,<\/p>\n<\/li>\n<li>\n<p>\u00a0<code>AccountTest.Can_deposit_money_into_an_account<\/code>,<\/p>\n<\/li>\n<li>\n<p><code>AccountTest.Can_deposit_additional_money_into_an_account<\/code><\/p>\n<\/li>\n<\/ul>\n<p>These three tests all still passed&#8230;er, failed.\u00a0 Does that mean they failed our mutation test?\u00a0 At first glance, yes.\u00a0 However, upon closer inspection it looks as if all of these tests actually focus on the Account.Deposit() method which wasn&#8217;t actually mutated.\u00a0 That means that there were no changes in the code targeted by these unit tests for these tests to detect so they can be ignored for this mutation.\u00a0 In a way, you could think of this as the concept of mutation coverage.\u00a0 Mutation coverage, similar to code coverage, is a metric that tells you how much of your program code was actually affected by the mutator.<\/p>\n<p>However, let&#8217;s look at the last two tests which still passed-<\/p>\n<ul>\n<li>\n<p><code>AccountTest.InsufficientFundsException_should_contain_the_actual_account_balance<\/code><\/p>\n<\/li>\n<li>\n<p><code>AccountTest.InsufficientFundsException_should_contain_the_amount_request<\/code>.<\/p>\n<\/li>\n<\/ul>\n<p>The false positives reported by these tests actually point to a more insidious problem.\u00a0 These tests cover code that was mutated by our mutator, the <b><code>Account.Withdraw()<\/code><\/b><code> <\/code>method.\u00a0 The fact these tests continue to pass even after the code they target has changed tells us that these aren&#8217;t effective tests.\u00a0 When we execute one of these tests under the debugger the reason for the false positive becomes obvious.\u00a0 This test catches the <b><code>InsufficientFundsException<\/code><\/b> thrown by the <b><code>Withdraw()<\/code><\/b> method and examines the values it carries.\u00a0 If the contained values don&#8217;t match the expected outcome then the test fails.\u00a0 But what if the <b><code>InsufficientFundsException<\/code><\/b> is never thrown?\u00a0 In this case, such as when the guard clause at the beginning of the <b><code>Account.Withdraw()<\/code><\/b> method has been inverted by our mutator, the exception is never caught and its contained values are never examined for validity.\u00a0 Since the only assert in the test exists in the unexecuted catch clause the test simply passes without incident.<\/p>\n<p>To make this a stronger test, we need to fail the test if the <b><code>InsufficientFundsException<\/code><\/b> is never thrown.\u00a0 The classic testing pattern for this is to simply place an <b><code>Assert.Fail()<\/code><\/b> immediately after the method that should throw the exception. \u00a0\u00a0If the exception is thrown then the execution will immediately be transferred to the catch clause and the <b><code>Assert.Fail()<\/code><\/b> won&#8217;t be executed.\u00a0 However, if the exception is <i>not<\/i> thrown then the <b><code>Assert.Fail()<\/code><\/b> will execute immediately after the method and fail the test.\u00a0 The example below demonstrates this pattern applied to the<b> <code><br \/>\nAccountTest<\/code><\/b><code>.InsufficientFundsException_should_contain_the_actual_account_balance<\/code>.<\/p>\n<pre class=\"lang:c# theme:vs2012\">[Test]\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 public void InsufficientFundsException_should_contain_the_actual_account_balance()\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0var account = new Account();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 account.Deposit(50.0m);\r\n\u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 try\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 account.Withdraw(75.0m);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Assert.Fail();\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 catch (InsufficientFundsException e)\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 {\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Assert.AreEqual(50.0m, e.AccountBalance);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 }\r\n<\/pre>\n<p>After applying this fix to both tests demonstrating false positives, we can repeat the mutation process and test run.\u00a0 Now we can see that these tests no longer demonstrate false positives, meaning that these mutants have been &#8216;killed&#8217;.<\/p>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1061-MT8.JPG\" alt=\"1061-MT8.JPG\" \/><\/p>\n<h2>Future Work<\/h2>\n<p>As an additional exercise, you can try to extend the MutantPower mutator we used in our example to handle more complex mutations such as inverting logical operators, reordering statement execution, or completely deleting certain statements from your code.\u00a0 Perhaps you&#8217;ll discover a mutation that affects the <b><code>Account.Deposit()<\/code><\/b> or <b><code>AccountManager.ApplyInterest()<\/code><\/b> methods.\u00a0 If so, then you can determine just how strong the tests covering these methods are and what you can do to improve them.<\/p>\n<p>You may also want to consider additional uses for program mutators, such as a creating a fuzz tester for penetration testing your software.<\/p>\n<p>Hopefully this article has piqued your interest in mutation testing and given you the tools to begin to think about how you can apply mutation testing in your day-to-day work.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>You may have a twinge of doubt when your code passes all its unit tests. They might say that the code is OK, but if the code is definitely incorrect, will the unit tests fail? Mutation Testing is a relatively simple, but ingenious, way of checking that your tests will spot the fact that your code is malfunctioning. It is definitely something that every developer should be aware of. &hellip;<\/p>\n","protected":false},"author":97401,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[143538],"tags":[4143,4204,5219,5220],"coauthors":[11295],"class_list":["post-914","post","type-post","status-publish","format-standard","hentry","category-dotnet-development","tag-net","tag-net-tools","tag-jeremy-jarrell","tag-mutant-testing"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/914","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/97401"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=914"}],"version-history":[{"count":9,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/914\/revisions"}],"predecessor-version":[{"id":77827,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/914\/revisions\/77827"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=914"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=914"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=914"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=914"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}