Skip to content

Instantly share code, notes, and snippets.

@nthdeveloper
Last active May 22, 2024 08:57
Show Gist options
  • Save nthdeveloper/b1814157c1647d2d47e99971f6d80763 to your computer and use it in GitHub Desktop.
Save nthdeveloper/b1814157c1647d2d47e99971f6d80763 to your computer and use it in GitHub Desktop.
NUnit Cheat Sheet for the most common test scenarios.

Installation

Install-Package NUnit

Install-Package NUnit.TestAdapter

Install-Package Microsoft.NET.Test.Sdk

Test Execution Workflow

using NUnit.Framework;
namespace NUnitUnitTests
{
    // A class that contains NUnit unit tests. (Required)
    [TestFixture]
    public class NonBellatrixTests
    {
        [OneTimeSetUp]
        public void ClassInit()
        {
            // Executes once for the test class. (Optional)
        }
        [SetUp]
        public void TestInit()
        {
            // Runs before each test. (Optional)
        }
        [Test]
        public void TestMethod()
        {
        }
        [TearDown]
        public void TestCleanup()
        {
            // Runs after each test. (Optional)
        }
        [OneTimeTearDown]
        public void ClassCleanup()
        {
            // Runs once after all tests in this class are executed. (Optional)
            // Not guaranteed that it executes instantly after all tests from the class.
        }
    }
}
// A SetUpFixture inside or outside of a namespace
[SetUpFixture]
public class MySetUpClass
{
    [OneTimeSetUp]
    public void RunBeforeAnyTests()
    {
        // Executes once before the test run. (Optional)
    }
    [OneTimeTearDown]
    public void RunAfterAnyTests()
    {
        // Executes once after the test run. (Optional)
    }
}

Misc Attributes

[Author("Joro Doev", "joro.doev@bellatrix.solutions")]
[Category("Category Name")]//Applied to test class or test method
[Ignore("Reason for ignore")]
[MaxTime(milisec)]//Max time for a test method to succeed. Test is not cancelled if the time is exceeded but reported as failure.
[Timeout(milisec)]//Max time for a test to complete. Test is cancelled if the time is exceeded and reported as failure.
[Repeat(N)]//Repeats the test N times (for testing intermittent bugs)
[Retry(N)]//Retries a test if it fails up to N times
[Range(start, end)]//Generates values between start and end
[Random(min, max, count)]//Generates "count" number of values between min and max

String/Null Check

string result = "Test string";
Assert.That(result, Is.EqualTo("Test string"), "Error occured...");
Assert.That(result, Is.Empty);//or Is.Not.Empty
Assert.That(result, Is.Null);//or Is.Not.Null

Numerical Equality

double result = 15.1;
//Equality
Assert.That(result, Is.EqualTo(15), "Error occured...");
//Range (-85) - (115)
Assert.That(result, Is.EqualTo(15).Within(100));
//Range by percentage  (13.5) - (16.5)
Assert.That(result, Is.EqualTo(15).Within(10).Percent);
//Sign check
Assert.That(result, Is.Positive);//Is.Negative
//Double NaN check
Assert.That(result, Is.NaN);

DateTime Equality

DateTime result = new DateTime(2000, 1, 1);
//Equality
Assert.That(result, Is.EqualTo(new DateTime(2000, 1, 1)));
//Range 1
Assert.That(result, Is.EqualTo(new DateTime(2000, 1, 1)).Within(TimeSpan.FromSeconds(100)));
//Range 2
Assert.That(result, Is.EqualTo(new DateTime(2000, 1, 1)).Within(100).Seconds);

General Range Check

int result = 220;
Assert.That(result, Is.GreaterThan(200));
Assert.That(result, Is.LessThan(300));
Assert.That(result, Is.GreaterThanOrEqualTo(220));
Assert.That(result, Is.LessThanOrEqualTo(220));
Assert.That(result, Is.InRange(200, 230));// (bounds are inclusive)

Boolean

Assert.That(result, Is.True);//or Is.False

Collections

List<string> stringCollection = new List<string>(){ "John","Dave","Susan" };

Assert.That(stringCollection, Is.All.Not.Empty);//None of them empty
Assert.That(stringCollection, Has.None.EqualTo("Bruce"));//None of them matches
Assert.That(stringCollection, Contains.Item("John"));//Contains the item
Assert.That(stringCollection, Has.Some.Contains("ave"));//Some of them Contains (only for strings, use item for others)
Assert.That(stringCollection, Has.Exactly(1).EndWith("ave"));//Exact number of matches
Assert.That(stringCollection, Is.Unique);//All members unique
Assert.That(stringCollection, Is.SubsetOf(new List<string>() { "John","Dave","Susan","Anna" }));//Subset of a collection
Assert.That(stringCollection, Is.SupersetOf(new List<string>() { "John", "Dave" })); //Superset of a collection
Assert.That(stringCollection, Is.EquivalentTo(new List<string>() { "John", "Susan", "Dave" }));//Has the same items
Assert.That(stringCollection, Is.Ordered);//Check if ordered collection

Reference Equality

var person1 = new Person();
var person2 = new Person();

Assert.That(person1, Is.SameAs(person2));//or Is.Not.SameAs(..)

Type Check

var car = new Volvo();
Assert.That(car, Is.TypeOf<Volvo>());//Check concrete type
Assert.That(car, Is.InstanceOf<Car>());//Check base type

Property Check

Assert.That(car, Has.Property("Model"));//Check object has the specified property

Exceptions

var sut = new Calculator();

Assert.That(()=> sut.Divide(150, 5), Throws.Exception);//Throws any exception
Assert.That(() => sut.Divide(50, 0), Throws.TypeOf<DivideByZeroException>());//Check a specific exception type
Assert.That(() => sut.Divide(50, 0), Throws.InstanceOf<ArithmeticException>());//Check a base exception type
Assert.That(() => sut.Divide(150, 0),
                Throws.TypeOf<ArgumentOutOfRangeException>()
                .With.Matches<ArgumentOutOfRangeException>(x=> x.ParamName=="a")); //Check exception parameters

Specifying Different Test Cases

[TestCase(-1,-2,-3)]
[TestCase(-2, -2, -4)]
public void should_sum_negative_numbers(int num1, int num2, int expectedResult)
{
  //...
}

Feeding With a Test Case Source

public class SampleTestCaseSource : IEnumerable
{
    public IEnumerator GetEnumerator()
    {
        yield return new int[] { 5, 6, 11 };
        yield return new int[] { 3, 4, 7 };
        yield return new int[] { 1, 2, 3 };
    }
}

[TestCaseSource(typeof(SampleTestCaseSource))]
public void should_add_positive_numbers(int num1, int num2, int expectedResult)
{
  //...   
}

Test With Combinatorial Values

[Test]
[Combinatorial]//This is default behavior, so this attribute is optional
public void should_add_numbers_without_exceptions([Values(2,3,4)] int num1, [Values(10, 20, 30)] int num2)
{
  //Runs 9 times (2, 10) (2, 20) (2, 30), (3, 10) (3, 30)....
}

Generate Test Values in a Range (Combinatorial Approach)

[Test]
public void should_add_numbers_without_exceptions([Values(2,3,4)] int num1, [Range(0.1, 0.3)] double num2)
{
  //Runs 9 times (2, 0.1) (2, 0.2) (2, 0.3), (3, 0.1) (3,0.2) (3, 0.3)....
}

Generate Random Test Values in a Range

[Test]
public void should_add_numbers_without_exceptions([Values(2,3,4)] int num1, [Random(1.0, 2.0, 5)] double num2)
{
  //Runs 15 times (3 x 5)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment