Send As SMS

Sunday, December 04, 2005

Unit testing in dotnet [Articles]

In addition to many good strategies for unit testing could be easily found in internet, I described few more things to care about:

Application configuration


Use virtual class which defines configuration.
By default, this class can read data from .config file.
For unit testing, this class will have hardcoded values, and help to solve issue with .config file and NUnit.
Additional advantage that for different tests you can use different configurations, just create another instance of configuration.
Example of configuration strategy described in this article:
http://dotnet.osypchuk.com/2005/06/configuration-files-mapping-to-code.html


Dates


If function is working with date, for example – calculate a balance of user for today, never use DateTime.Now property.
If you want to check something which depends on time intervals, you will be forced to change system time during unit test, or ad some system sleeps which increase time necessary for unit testing.
Also this could cause incorrect results in distributed environments, when servers has different time zone


Separate logic and implementation


In ideal world, you should have a one function at business layer for each user operation.
However, often this is not true in real life. Very often we need to create complex input parameters for these methods, or call few business layer methods to perform single logical operation.
Define some helper in unit tests which hides entire functionality related to implementation. This greatly helps you in case some re-factoring and makes easier to observer logical part of unit test.


Reuse strategy


For common scenarios, define strategy is virtual class and reuse it.
You will have one test to create user, another one to create customer, and last one to create admin.
Does not use copy/paste. Please. This is really simple even for juniors.


Automatically create test environment


From very beginning of your project, implement code which make it live from very beginning.
Check and create all internal objects in database, such as administrator, types of payments, packages.
In unit tests, you need function responsible to create a necessary state of system, and check if this state is applied in each StartUp method.
If system can work in different situations it could be quite expensive to change system states automated. Some time ago I worked with budget system, and some operations was ok only when year is in state planning, some other when year is in state approved, and completely other in state Active. Each UT checked state of year and change it if necessary. Each execution of unit tests created about dozens of years :)
It was not simple but only in this way we can be sure that our method which we edit now do not broke data when system is in another state


Strings and numbers


Do not use hardcoded string and numbers.
If you test 2+2 = 4 it do not shows that your + operation is working. Maybe it is always return 4.
If you pass random number to function, you will at least knew that it works with other parameters. (And sometimes it may crash because of overflow).


Clean up your data after test


Add some attribute to objects created by unit tests. For example, all user names start from “UT_”.
If this is possible and system supports delete operation on objects, delete all what you created in UT.
Create script which drop al objects created by unit tests. Even if you have cleanup section in unit test, sometimes if it is completed unsuccessful you will get a test data in database.




Applies to all dotnet languages: C#, VB.NET, C++.NET, J#

0 Comments:

Post a Comment

<< Home