Subscribe Now: Feed Icon

Saturday, April 9, 2011

Unit Tests: Introduction

On my previous job we had a large team working on an existing framework above the ESRI framework, we worked with coded Unit Tests with continuous integration.

I guess it was a kind of cultural shock to reach a place that had ZERO coded Unit Tests, that the only framework above the ESRI framework was the usage of a Dictionary class and the copy paste of file named SdeUtilities.cs from project to project.

Not to say that everything was perfect in my old project. Most of our framework was without Unit Tests, we used the excuse of “It’s too difficult to test COM objects/code that accesses the database”. But we also suffered from it.

I remember this one time where I changed a private method with a piece of code that looked like:

  1. public void UpdateFeature(IFeature feature, IEnumerable<KeyValuePair<string, object>> fields, IGeometry geometry)
  2. {
  3.     foreach (var field in fields)
  4.     {
  5.         feature.SetValue(field);
  6.         feature.Store();
  7.  
  8.         if (geometry != null)
  9.         {
  10.             feature.Shape = geometry;
  11.             feature.Store();
  12.         }
  13.     }
  14. }

I changed it to:

  1. public void UpdateFeature(IFeature feature, IEnumerable<KeyValuePair<string, object>> fields, IGeometry geometry)
  2. {
  3.     foreach (var field in fields)
  4.     {
  5.         feature.SetValue(field);
  6.  
  7.         if (geometry != null)
  8.         {
  9.             feature.Shape = geometry;
  10.         }
  11.         feature.Store();
  12.     }
  13. }

Seems close, no? Well I tested it in both my services and my WinForm application and everything worked so I checked it in. My friend sitting next to me did a get latest and for the next two days debugged why his application stopped working. At the end he asked me and I told him what I changed. It didn’t seem like a large change and I am not really sure why the ArcObjects code needed those two “Store”s. But what I do know is that Unit Tests for that code would have found that bug in at most minutes and at best seconds and would have prevented me from making that mistake.

 

When I rewrote the framework this time I wrote both Unit Tests and coded integration tests (tests that effect the DB). This time when I upgraded from ArcGIS version 9.3.1 to version 10 and the build passed without any problem, I ran the Unit Tests and they failed. I got the error:

System.Runtime.InteropServices.COMException: Retrieving the COM class factory for component with CLSID {D9B4FA40-D6D9-11D1-AA81-00C04FA33A15} failed due to the following error: 80040111…

Googling the problem I found the solution. The problem was that in version 10 ESRI added another level of license control that needed to be initialized. I of course found out only when the tests failed.

When my team leader and manager asked me how much time I thought it will take me to upgrade the framework. My answer was two days. The unit tests I had were a big reason for that low estimate. I knew that all I needed to do was:

a. Make sure the tests pass in version 9.3.1

b. Replace the Dlls with those of version 10

c. Get the tests to work in version 10

I didn’t have to go over every pips in the application – my unit tests covered all of them.

 

Managers will forever tell you “there is no time for writing Unit Tests”. They do this for the sole reason of not understanding the importance of Unit Tests. They don’t understand that even the basic Unit Tests give a developer the confidence of changing his/her code (and prevent us from making the mistake of rewriting the code from scratch, since with Unit Tests it can be easily refactored). They don’t see Unit Tests as real tests – a developer’s job is to write code, a QA’s job is to do the tests. For them writing Unit Test just mean doubling the work with next to no gain – the developer might write better code but the QA will test it all the same.

So how do you start writing Unit Tests?

1. Try explaining it. I rarely succeeded in doing that (I scored very low on my bulshiting skill) so I can’t really help you there…

2. Going behind the back of the manager and just writing the damn tests.

3. Combine the two first methods. Begin with method 2 and start writing the tests, add CI (Continuous Integrations) to the mix with some instructions such as “Do not check in if the test or build failed” and show the manager concrete proof that Unit Tests work. Use graphs if you have to and show how Unit Tests saved you time in figuring the bugs in the system. Make sure to use the words like “experiment” and “low maintenance” managers seem to like them. And last but not least ask for the managers “advice” whether  to continue with this “experiment” or not – managers really want to manage us to death by giving the manager both the way (i.e. Unit Tests) and the problem “productivity”, “time” and “maintenance”, the manager will go to the least resistance route – the one you offer him… Let him in turn show it as his own success to his managers (for more such great advice read “The joy of work” by Scott Adams).

 

If you haven’t guessed I am going with method 3, it has both a return in results (i.e. written Unit Tests) and less manager bulshiting that managers must have in order to take things on faith alone…

 

Well tell me of your experience in convincing your boss? have you used one of these methods? Another way? How did it go? Do you have any advice for others?

 

Keywords: Unit Test, Test, IFeature

IceRocket Tags: ,,