Why NUnit test context is our best friend?

In the Creating custom attributes with internal NUnit features article, I mentioned the ITest interface that gives us access to test properties. In this post, I’d like to talk a little bit more about the TestContext class and the opportunities that it brings us. First of all, let’s define some kind of challenge that we want to solve at the end using the above-mentioned TestContext class and especially its static CurrentContext property.

Challenge: to provide infrastructure for saving logs for each failed NUnit test with splitting by sub-folders.

First of all, we need to understand where we’d like to save our logs. Working with the file system is painful sometimes because we need to be careful with absolute paths. In order to solve this problem we need to recall that NUnit tests are always run from a DLL file, doesn’t matter what way of running tests we use (Visual Studio, NUnit GUI, command line or continuous integration system).  This similarity allows us to utilize the first property of the CurrentContext – TestDirectory. Let’s see an example:

The private CurrentTestFolder string points us to the directory where the DLL file with NUnit tests is located. For example, if we run tests from Visual studio, it’s usually the [solution]\[project]\bin\Debug\ or [solution]\[project]\bin\Release\ folders. According to our initial goal, I added a structure of NUnit methods and a couple of private members of the class which corresponds to the common logs folder and sub-folders for each test: LogsFolder and SubTestFolder.

In the OneTimeSetUp() method (which is executed only once) we create the “Logs” folder inside the CurrentTestFolder. So, before any test is started, we have the place where we can save our logs. But what about splitting logs by sub-folders corresponding to the test names? It’s time to appeal to the CurrentContext again! Let’s see how we can modify the SetUp() method:

As we see from the method’s body above, CurrentContext allows us to get a current test name by accessing its Test.Name property. Then we just create an appropriate folder inside the “Logs” folder. Due to the purpose of the method followed after the [SetUp] attribute, it’s executed before each test, i.e. we create a new folder for each test according to its name.

Except for a test name, TestContext.CurrentContext.Test property gives us access to the following data:

  • ClassName
  • FullName
  • test ID
  • MethodName
  • Properties bag (see later)

The only one task remains – to provide saving logs for failed tests only. First of all, we need to understand what do we mean under the “failed tests” because a test in the NUnit world can have different states: passed, failed, failed with an error, skipped, inconclusive, etc. Let’s decide that we’d like to save our logs for those tests which are failed because of assertions and unexpected exceptions. All the rest we don’t care. Another question is where we should perform this check (if a test is failed or not)? The answer is in the method marked with the [TearDown] attribute because it’s executed after each test and this is the correct place where we know the test result already. Here is the final code of our infrastructure:

As you can see from the TearDown() method, we get the TestContext.CurrentContext.Result.Outcome property of the current test. Then we compare it with known values of the ResultState enum and make a decision: to save or not to save our logs for this specific test.

What else can the CurrentContext give us? For example, Random numbers generator:

The Random property of the Randomizer class provides lots of methods for obtaining random numbers of different types (bool, integer, float, long, decimal, etc.). This is very useful in some cases if we want to make our unit tests more robust and test more different combinations. Another interesting example of the CurrentContext usage is shown below:

I’ve mentioned that CurrentContext gives us a way how to get the Property bag of a test. The example above shows exactly that case when we can get access to different NUnit test properties. As you might know, an NUnit test can have a lot of different attributes: Description, Order, Repeat, Category, Bug, etc. If we know what we’re looking for (the name of the property), we’re able to get it, check its value and adjust some logic inside the test or SetUp/TearDown methods.

Summary: internal NUnit features have a lot of interesting methods and properties inside. As we’ve just seen, the TestContext contains many useful properties which can be and should be used by QA Automation engineers in order to make our tests more readable, flexible and maintainable. Explore it, try it and have fun!

 

Like this post?

Subscribe to updates from my blog, if you don't want to miss more interesting future posts and materials

Please check your email and confirm subscription

Pin It on Pinterest

Share This