# Supercharge Your Test Coverage with NUnit’s TestCase Attribute

## Save Time and Money Writing Exhaustive C# Tests

# Introduction

In this article, I explain the benefits of using NUnit’s *TestCaseAttribute*, which* *helps eliminate repetition and make C# tests more expressive.

# The Problem

To grasp the reason for using the *TestCaseAttibute*, it is necessary first to identify the problem it seeks to solve. Let’s write some edge case tests for Math.Pow(double, double), which takes in:

- a base,
*x* - an exponent,
*y*

and returns the base taken to the power of the exponent:

[TestFixture]

public class Tests

{

[Test]

public void

Pow_X_Zero_Y_More_Than_Zero_Returns_Zero()

{

Assert.AreEqual(0,

Math.Pow(0, 0.1));

}[Test]

public void

Pow_X_Zero_Y_Less_Than_Zero_Returns_PositiveInf()

{

Assert.AreEqual(double.PositiveInfinity,

Math.Pow(0, -0.1));

}[Test]

public void

Pow_X_PositiveInf_Y_More_Than_Zero_Returns_PositiveInf()

{

Assert.AreEqual(double.PositiveInfinity,

Math.Pow(double.PositiveInfinity, 0.1));

}[Test]

public void

Pow_X_PositiveInf_Y_Less_Than_Zero_Returns_Zero()

{

Assert.AreEqual(0,

Math.Pow(double.PositiveInfinity, -0.1));

} [...]}

You’re probably finding yourself doing a lot of copying and pasting, changing the input variables, the expected result, and the test names to reflect different combinations. And, we haven’t finished yet — there are still a lot more tests to write.

Not only does this take longer, but it increases the chances of human error creeping in, requiring more effort for both developers writing the test cases and PR reviewers reading and verifying their correctness.

# The Solution

The solution is to use the NUnit *TestCaseAttribute*, which:

- marks a method with parameters as a test method
- provides data used when calling this test method
- allows us to test a large number of combinations that might not be feasible to check for under time and budget constraints

Instead of writing a new test case for every condition, we instead decorate a **single** unit test method with the inputs and output, which performs the same test over four separate data sets.

First, write a single unit test method that takes in two parameters — *x* and *y* — and asserts against a third input called *expectedResult*.

` `

**[Test]**

public void Pow_X_Y_Returns_X_To_Power_Of_Y

(double **x**, double **y**, double **expectedResult**)

{

Assert.AreEqual(**expectedResult**, Math.Pow(**x**, **y**));

}

Second, stack *[TestCase] *attributes on the test, providing inline data with the following syntax that matches the signature of the unit test method:

** **

[TestCase(0, 0.1, 0)**]**

**[TestCase**(0, -0.1, double.PositiveInfinity)**]**

**[TestCase**(double.PositiveInfinity, 0.1,

double.PositiveInfinity)**]**

**[TestCase**(double.PositiveInfinity, -0.1, 0)]

public void Pow_X_Y_Returns_X_To_Power_Of_Y(

double x,

double y,

double expectedResult)

{

Assert.AreEqual(expectedResult, Math.Pow(x, y));

}

Although we’ve only defined one unit test method, our test results show that **four** test cases have been passed:

Another variety of the test case attribute approach is to specify a named parameter called *ExpectedResult*, which means **two** things for our unit test method. We need to:

- Change the output type from
*void*to*double*, returning the result instead of using*Assert*. - Remove the last parameter in the method signature

In the following example, *ExpectedResult* is set in each *TestCase* attribute, replacing the *expectedResult* parameter in the method signature. I’m also expecting a return value of the type of *double*:

[TestCase(0, 0.1,

**ExpectedResult = 0**)]

[TestCase(0, -0.1,

**ExpectedResult = double.PositiveInfinity**)]

[TestCase(double.PositiveInfinity, 0.1,

**ExpectedResult = double.PositiveInfinity**)]

[TestCase(double.PositiveInfinity, -0.1,

**ExpectedResult = 0**)]

public **double** Pow_X_Y_Returns_X_To_Power_Of_Y(

double x, double y)

{

return Math.Pow(x, y);

}

Again, four test cases pass:

Finally, use the *TestName* named parameter to provide PR reviewers and future developers with some context about what the test does:

` `

[TestCase(0, 0.1,

ExpectedResult = 0,

TestName = "0^0.1 = 0")]

[TestCase(0, -0.1,

ExpectedResult = double.PositiveInfinity,

**TestName = "0^-0.1 = Inf"**)]

[TestCase(double.PositiveInfinity, 0.1,

ExpectedResult = double.PositiveInfinity,

**TestName = "Inf^0.1 = Inf"**)]

[TestCase(double.PositiveInfinity, -0.1,

ExpectedResult = 0

**TestName = "Inf^-0.1 = Inf"**)]

public double Pow_X_Y_Returns_X_To_Power_Of_Y(

double x, double y)

{

return Math.Pow(x, y);

}

Once more, confirm the test cases pass:

Thanks for reading! Let me know what you think in the comments section below, and don’t forget to subscribe. 👍