My preferred frameworks for automated testing in .NET.
See here for a list of included packages and their versions.
This package also includes the
TestHarnessBase
class, which aids my preferred technique for setup/teardown code. Generally, I
eschew traditional SetUp
and TearDown
methods. Instead, in each test, I
create an instance of a disposable context class. Construction is setup, and
disposal is teardown. Because TestContext
means something else already in
NUnit, I call this pattern Test Harness instead.
[Test]
public void TestSomething()
{
using var h = new TestHarness();
// rest of test
}
private class TestHarness : TestHarnessBase
{
// properties for mocks and things
public TestHarness()
{
// setup code
}
protected override CleanUp()
{
// teardown code
}
}
This pattern enables some cool things:
-
I can enable the C# 8 nullability checker and not have to sprinkle
?
and!
all over the test code. -
Tests can run in parallel, regardless of test fixture lifetime, since there is no longer any shared state within a test class.
-
Test-support code can be isolated away from the tests themselves.
If the
test fixture lifetime
is instance-per-test-case, the test fixture itself can be a subclass of
TestHarnessBase
. This results in a test fixture more closely resembling a
traditional one and removes the need for a using
statement in each test,
while retaining the improved nullability ergonomics. However, directly
subclassing TestHarnessBase
forfeits the isolation afforded by having a
separate test harness class.
[TestFixture]
[FixtureLifeCycle(LifeCycle.InstancePerTestCase)]
public class SomeTests : TestHarnessBase
{
// properties for mocks and things
public TestHarness()
{
// setup code
}
protected override CleanUp()
{
// teardown code
}
[Test]
public void TestSomething()
{
// test
}
}