Sunday, January 30, 2011

Developers should be lazy

One of my daily goals is to be a lazier developer. By this I mean - if what I'm implementing today also need to be implemented tomorrow or the day after, I should be able to deliver it with at least the same quality but with less effort. In order to achieve this, code duplication must be avoided and reusable components must be created whenever possible.

The difference between unit tests and integration tests

Developers usually write two types of tests for their code, unit tests and integration tests.

Unit tests are written for testing the correctness of the smallest unit of code in an application. In object oriented programming such a unit is usually a method. The unit must be tested in isolation when unit testing. This means that any dependency the unit has, such as a database, service or file system, must be abstracted away and replaced by a fake object. A fake object can be created manually or by using a mocking framework.

Integration tests on the other hand are for testing the correctness of the unit under test together with all of its dependencies. In such a test it's allowed to call a database, service, file system or any other type of dependency the code might have.

Monday, January 24, 2011

A true unit test does not...

A true unit test does not:
  • Depend on any code outside its own unit.
  • Talk to a database.
  • Invoke a service.
  • Call the file system.
  • Send an e-mail.
  • Communicate across the network.
  • Affect other unit tests.
  • Depend on environment specific configuration settings.

Monday, January 10, 2011

Unit tests should be in the same project as the code under test

Most of the .NET projects that I have seen with decent test coverage have the unit tests located in a separate test project. The structure of this unit test project usually reflects the structure of the project under test. Any folder and class in the project under test would also exist in the test project, but where the class has a *Tests suffix in the name.

On a project that I'm working on we also did it the same way. In the beginning it worked pretty well, keeping the two projects in sync wasn't too much hassle. But as the structure and the code was growing in size the two projects got more and more out of sync. The project under test would get new code added and it would get refactored, while the unit test project would not. Also more and more classes were lacking unit tests or the tests weren't up to date. Before this got totally out of hand I decided to find a better way to structure things. After playing around with a few different approaches I ended up with a simple solution to this problem. By simply moving the unit tests in to the same project as the code under test the problem was solved. The project under test would then have both a class A and a class ATests.

This approach has some nice benefits:
1) Easy to see if a class has any tests, just look for the ClassNameTests class.
2) Don’t have to maintain multiple structures.
3) Makes navigation between the class under test and the test class easier.
4) Signals the importance of unit tests.

But it also has some drawbacks:
1) The project needs to reference all the libraries that are required by the test code, such as mocking frameworks.
2) Changing the projects into a test project gives some overhead when compiling.
3) The compiled code/assemblies will be bigger in size. A way to solve this is to remove all the *Tests classes before compiling.

For unit tests I would recommend using this approach. When it comes to integration tests I suggest having them in a separate project as these tests are not to be run as frequent as the unit tests.

Saturday, January 1, 2011

Goals for 2011

It's the first day of the year and it's time to set my goals for 2011:
  • Write 52 blog posts.
  • Write 3 articles to be published on any larger technology site.
  • Maintain the 3 open source projects that I released in 2010, and release 2 new projects.
  • Create and release a simple Windows Phone 7 application.
  • Move this blog to my own to-be-created blog engine running on ASP.NET MVC and a NOSQL database.
  • Learn more about business intelligence by learning Microsoft SQL Server Integration Services and Microsoft SQL Server Reporting Services.
  • Become fluent on the ADO.NET Entity Framework.
  • Learn about event-driven architecture and NServiceBus.