Last active
August 29, 2015 13:56
-
-
Save ToJans/9228503 to your computer and use it in GitHub Desktop.
100 Percent test coverage means nothing
This file contains 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.
Learn more about bidirectional Unicode characters
using System; | |
using Microsoft.VisualStudio.TestTools.UnitTesting; | |
namespace TDDCoverage | |
{ | |
public enum Gender { Unknown, Male, Female } | |
public class Customer | |
{ | |
public Gender Gender = Gender.Unknown; | |
public bool IsVIP = false; | |
public bool IsPreferred = false; | |
} | |
public class Discounter | |
{ | |
// A customer can get a discount based on it's profile. | |
// Vips: | |
// - A male gets a 44% discount | |
// - A female gets a 33% discount | |
// - If we don't know the gender we get a 22% discount | |
// Preferred customers: | |
// - A preferred customer gets a discount of 10% | |
public static decimal DiscountPercentage(Customer c) | |
{ | |
decimal discount = 0; | |
if (c.IsVIP) | |
{ | |
if (c.Gender == Gender.Male) discount = 44; | |
else if (c.Gender == Gender.Female) discount = 33; | |
else discount = 22; | |
} | |
if (c.IsPreferred) | |
{ | |
discount = 10; | |
} | |
return discount; | |
} | |
} | |
// This testcase covers all the code, but the code still has a bug | |
[TestClass] | |
public class FullCoverage | |
{ | |
[TestMethod] | |
public void Discount_regular() | |
{ | |
Assert.AreEqual(0, Discounter.DiscountPercentage(new Customer { })); | |
} | |
[TestMethod] | |
public void Discount_vip() | |
{ | |
Assert.AreEqual(44, Discounter.DiscountPercentage(new Customer { Gender = Gender.Male, IsVIP = true })); | |
Assert.AreEqual(33, Discounter.DiscountPercentage(new Customer { Gender = Gender.Female, IsVIP = true })); | |
Assert.AreEqual(22, Discounter.DiscountPercentage(new Customer { Gender = Gender.Unknown, IsVIP = true })); | |
} | |
[TestMethod] | |
public void Discount_Preferred() | |
{ | |
Assert.AreEqual(10, Discounter.DiscountPercentage(new Customer { IsPreferred = true })); | |
} | |
// The problem with the code is that we actually overrule the vip | |
// behaviour with the preferred behaviour, which is obviously a bug. | |
// | |
// While it might be obvious here, it might not be as obvious | |
// in the big codebases one usually works with, as the cyclomatic | |
// complexity of these is WAAAY higher then this case. | |
// | |
// The point I want to make is that 100% test coverage proves nothing, | |
// because you only test specific scenarios, and not all the possible | |
// combinations. Most bugs in software appear because the software was | |
// used in an unexpected way. | |
// | |
// If you would like to test all behaviour, one has to fall back to | |
// property based testing. | |
// | |
// This is the missing test case: | |
// | |
//[TestMethod] | |
//public void Discount_preferred_and_vip() | |
//{ | |
// Assert.AreEqual(44, Discounter.DiscountPercentage(new Customer { Gender = Gender.Male, IsVIP = true, IsPreferred = true })); | |
// Assert.AreEqual(33, Discounter.DiscountPercentage(new Customer { Gender = Gender.Female, IsVIP = true, IsPreferred = true })); | |
// Assert.AreEqual(22, Discounter.DiscountPercentage(new Customer { Gender = Gender.Unknown, IsVIP = true, IsPreferred = true })); | |
//} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment