1

I am working on a test library using NUnit, and am generating a custom report while the tests run.

In the TearDown of my tests I call a method that will report the result of the test. It works just fine if the test passes, but is never reached if the test fails, is ignored, or inconclusive.

To make things more difficult, the "//do stuff" in the TearDown can also cause the test to fail in which case it would still need to be logged. BUT Assert throws an exception which means it leaves the block and never reaches the reporting code.

[SetUp]
public void ExampleSetup()
{
    //whatever
}

[Test]
public void ExampleTest()
{
    //whatever
}

[TearDown]
public void ExampleTearDown()
{
    //do stuff
    someObject.ReportTestResult();
}

More Info - Using NUnit 3.2.0

jacobvoller.com
  • 476
  • 7
  • 28

2 Answers2

1

By looking up the NUnit documentation's Framework Extensibility chapter we can see that you need to use the Action Attribute.

The Action Attribute extension point is:

designed to better enable composability of test logic by creating attributes that encapsulate specific actions to be taken before or after a test is run.

Summary of a basic implementation of this extension point

You need to implement the ITestAction interface in your given say FooBarActionAttribute() class.

Given this you implement BeforeTest(), AfterTest() and Targets property.

For a basic scenario you need to perform your custom operations in the above two methods.

The final thing you need to do is to use this attribute, for example as:

[Test][FooBarActionAttribute()]
public void Should_Baz_a_FooBar() { 
    ...
}

This will get executed right before and after the test method run.

For more advanced techniques please consult the linked documentation, it's pretty straightforward.

kayess
  • 3,384
  • 9
  • 28
  • 45
1

Frankly, this is just a bad idea. TearDown is part of your test. That's why it can fail. (But note that NUnit treats an assert failure in teardown as an error rather than a failure)

Since a test can do anything - good or bad, right or wrong - putting your logging into the test code is unreliable. You should be logging in the code that runs tests, not in the tests themselves. As stated above, the TearDown is a part of your test. So is any ActionAttribute you may define, as suggested in another answer. Don't do logging there.

Unfortunately, there is a history of doing logging within the tests because NUnit either didn't supply an alternative - at least not one that was easy to use. For NUnit V2, you could create a test event listener addin for exactly this purpose. You still can if that's the version of NUnit you are using.

For NUnit 3.0 and higher, you should create a listener extension that works with the TestEngine. The TestEngine and its extensions are completely separate from your tests. Once you have a well-tested extension, you will be able to use it with all your tests and the tests won't be cluttered with logging code.

Charlie
  • 12,928
  • 1
  • 27
  • 31