03 May 2014

best practice of writing unit tests in c#

Unit test issue

Recently one of my friends had called me regarding an issue. He was facing an issue, where few unit tests pass when the code is checked in and they fail when run as part of the nightly build. This was intriguing him, how can unit test pass on local machine and fail on build machine when running at night time.

Started looking into the issue and found few unit tests had failed with the below error:

System.ArgumentOutOfRangeException: Hour, Minute, and Second parameters describe an un-representable DateTime.

Unit test issues analysis

After googling and browsing the MSDN docs found out that all unit tests are failing while initializing the DateTime using the below constructor:

public DateTime(int year,int month,int day,
int hour,int minute,int second)

And he had used the below line of C# code to initialize the DateTime fields

DateTime currentTime= DateTime.Now;
DateTime field1 = new DateTime(currentTime.Year, 
currentTime.Month, currentTime.Day, 
currentTime.Hour+2, 0, 0);

OK, we thought the only difference on local machine unit test run and the night build unit test run is the time at which unit tests are running. When around 5 PM all pass, but the same test fail when ran at around 11 PM in the night. Then what's wrong with the code above. Looking at the Exceptions details for the DateTime class constructor, gave a clue.

hour is less than 0 or greater than 23.

When unit test ran around night, the time was around 23 hour, adding 2 to it, becomes 25, which is greater than allowed value of 23 and hence he was getting the error and resulting unit tests failure.

23 < 23+2

Unit test issues fix

Later corrected the issue by using the below code and nightly build started passing successfully.

DateTime currentTime= DateTime.Now;
DateTime field1 = currentTime.AddHours(2);

Moral of the story: Best practice of writing unit test case

  • Unit tests should be written such a way that they pass whenever you run them. Don't make your unit test time sensitive.
  • Before using an API we should be looking at the related docs to see what kind of values are expected as part the argument values and what not and also look the exceptions an API thrown when input values are incorrect.This is very important not just while unit testing but also when writing the actual code.

No comments:

Post a Comment