NUnit 3.7 new features overview

0
109

Fresh baked NUnit 3.7 version has been released less than one month ago and it’s a good time to see what’s inside our favorite test framework that we can utilize in our tests.

First of all, let’s emphasize the main changes and improvements from the around 70 bugfixes and new features that NUnit authors have made:

  • multiple asserts;
  • parallel test methods execution within a fixture;
  • multiple “Author” attribute usage;
  • attaching files to test results;
  • some changes to test actions;
  • over 60 another fixes and improvements.

As you can see, there are several very interesting items in the list above. So, I installed the latest NUnit build and tried to play with these new features. Let’s have a look together in my findings! In order to have interesting examples, I prepared some kind of the sample project with the Employee class where we can create employees in different roles and then promote them. Each promotion will assign a new level of bonus for an employee, so we will be able to apply NUnit 3.7 new features there.

Multiple Asserts

This feature was always so obvious and useful for me that I was surprised why NUnit didn’t have it before. As some of you may know, the upcoming JUnit Jupiter release will also have multiple asserts (actually, you can use it already with milestone releases). So, I was sad a little bit that NUnit was falling behind but now it’s fixed.

What is inside in the box? The entry point is the Assert.Multiple() expression which surrounds another asserts (and also any arbitrary code). By design, the Assert.Multiple() takes a TestDelegate object as a parameter, so we are allowed to pass as many asserts as we’d like using lambda expressions. For example,

[Test]
public void CheckJohnPromotionToConsultant()
{
 Employee John = new Employee("John", Role.TRAINEE);
 John.Promote();

 Assert.Multiple(() =>
 {
 Assert.AreEqual(1.1, John.GetBonus(), "Employee's bonus is not valid");
 Assert.AreEqual(Role.CONSUTANT, John.Role, "Employee wasn't promoted correctly");
 });
}

How does it work? The Assert.Multiple() method is a wrapper for all assertion methods inside. If any assertion inside is failed, a test run won’t be stopped but the fail will be remembered and reported with another results on the exit of the block. If several assertions in the block are failed, all of them will be reported on the exit of he block. A test is passed only when all asserts inside the Assert.Multiple() block are successful. But when an unexpected and unhandled exception occurs in side the block, a test will be terminated immediately.

In my example above, I created the new employee John who is a trainee. Then I promoted him and checked that his new role is correct as well as he got a proper bonus for his position. This is exactly where multiple asserts help very much.

Parallel test methods execution

Before the version 3.7, we were able to utilize parallelism on the test fixtures level only. It was definitely unfair, that’s why Charlie Pool, the main NUnit contributor committed to delivering parallelism on the test methods level.

Let’s add several more tests to our example and see how we can speed their execution up by using parallelism:

[TestFixture, Parallelizable(ParallelScope.Children)]
public class NewFeaturesExamples
{
 [Test]
 public void CheckJohnPromotionToConsultant()
 {
 
 }

 [Test]
 public void CheckStevePromotionToManager()
 {
 
 }

 [Test, Author("John Doe"), Author("Jessica Doe")]
 public void CheckBrianPromotionToCEO()
 {
 
 }
}

As you can see, there are 3 similar test methods which check different levels of promotion. The most interesting part is specified on top of our test class inside the Parallelizable attribute. Whether a test is allowed to be run in parallel or not, it’s defined by the ParallelScope enum. The main values are:

  1. None (the test may not be run in parallel with other tests).
  2. Self (the test itself may be run in parallel with other tests).
  3. Children (child tests may be run in parallel with one another).
  4. Fixtures (fixtures may be run in parallel with one another).

There are several other values there but you can check them out by yourself, if interested (source).

According to the list above, we can have to 2 options to run test methods in parallel:

  1. Either specify the Parallelizable(ParallelScope.Children) attribute on the class level once or
  2. Specify the Parallelizable(ParallelScope.Self) for each test methods inside the class that we’d like to run in parallel.

I chose the first option to specify parallelism once on the class level (less code). Let’s compare the output! Here is the picture of results when we have parallelism (total run time = 3 sec):

NUnit 3.7 parallel tests execution

If we remove the Parallelizable attribute and run those 3 tests again, the total run time is equal around 8 seconds:NUnit 3.7 usual test execution

Multiple “Author” attribute usage

As you may notice, the last test in the last example had 2 authors:

[Test, Author("John Doe"), Author("Jessica Doe")]

The improvement itself is minor but useful for big teams where each test can be developed or modified by several people. Now all of them can be happy and acknowledged!

Attaching files to test results

This is the last feature that I was going to cover in this post. Attaching a file to test results is available through our good friend – TestContext. All you need is to call the static AddTestAttachment() method:

[Test]
public void CheckBrianPromotionToCEO()
{
 

 
 TestContext.AddTestAttachment(@"D:\myFile.txt");
}

Please note that you cannot obtain the TestResult.xml file if you run NUnit tests from Visual Studio. In order to overcome this limitation, you should build your test code and then run your DLL with tests via nunit3-console test runner. When you do that, the TestResult.xml file will appear in the folder with your DLL and contain something like this:

<test-case id="0-1003" name="CheckBrianPromotionToCEO" fullname="NUnitLastExamples.NewFeaturesExamples.CheckBrianPromotionToCEO" methodname="CheckBrianPromotionToCEO" classname="NUnitLastExamples.NewFeaturesExamples" runstate="Runnable" seed="1109087597" result="Passed" start-time="2017-06-20 22:34:36Z" end-time="2017-06-20 22:34:38Z" duration="2.052342" asserts="2">
 <attachments>
 <attachment>
 <filePath>D:\myFile.txt</filePath>
 </attachment>
 </attachments>
</test-case>

That’s it for now! Please share your thoughts, explore NUnit and… happy testing!

The post NUnit 3.7 new features overview appeared first on YOUR TEST AUTOMATION HUB.

LEAVE A REPLY