Developer Working is not Tester Working

26 06 2011

There is a single tester on our team. The depth of her knowledge and her attention to detail astounds us most days. She knows the edge cases, the strange behaviours and the places where our code and the real world don’t quite agree with each other. There is definite truth to the saying that if you want to know how a system works, ask the testers! Something that she has taught me is that there is a vast difference between what I consider to be working code and what she considers to be working code.

Developer working is a rosy view of the world. Usually it means that the code works under some nice conditions. We assume the user has behaved sanely, the OS is in good shape, the machine is up and responsive etc. Tester working is a much tougher place to be. In tester working the end is nigh and all hell has broken loose. The user has decided to put all spaces in every field and delete our config files. The OS is a custom version that we’ve never seen before and the machine only responds twice a day.

Devs are optimists and testers are realists. I’m glad to have a tester who is so thorough in her understanding of the real world. It means I don’t have to be!





What did Unit Tests ever do for us Anyway?

25 06 2011

Six months ago my fellow dev and I were handed a new project to work on. We had just started to work together, our domain knowledge was zero, and 50% of us (me, that is) had zero experience of C#. The significant risk that this formula involved was obvious, especially on the faces of our project manager and the division head.

Something special was required. Luckily this guy would not shut up about this. Dependency inject he said, unit test he said. Having both experienced projects where the thought of changing code struck fear into our very hearts, we were up for giving it a go.

It started slow, that much is true. Writing one to two lines of test harness code for every line of “real” code is hard to accept. It’s counterintuitive given the business pressures you are under. Test code can be so simple that it feels worthless. Of course thing.Increment() returns thing+1, what else would it do?!

I felt that too, and often, but sticking with it (thanks to the support of the team as a whole) brought with it a significant reward. It is between doubt and boredom that magic happens.

Communication

Unit tests allowed a clear and concise communication of intent. For us this meant that we could compensate for some of our lacking in domain knowledge by increasing our ability to converse about the state of the code. I could easily point to a test to explain a problem I was having, instead of being stuck for words.

Code Quality

Code rot starts instantly. Having tests from the beginning allowed us to make sure that once the code was correct, it stayed correct. For a project where there were no gurus to save us this was incredibly valuable. Without unit tests to help us, plugging one hole would spring a leak elsewhere and we would almost certainly have ended up racing to the bottom as deadlines approached.

Knowing when we hit the Target

One pivotal component had to store and sort data on disk. We didn’t know how we would do that at first so we came up with the interface for the component and an in memory implementation. The tests for this interface acted as a target for us to hit when it came to implementing the on disk component. Once our on disk implementation passed the same tests we knew that our work was done and it satisfied the same criteria!

Testability gave us Flexibility

Making something testable through dependency injection means that it is also flexible. Having gone through this process we were able to port our application to multiple new DB platforms, each one taking roughly two days to complete. Each solution depends on the very same engine, we just had to write the custom pieces to be injected. Testability means being able to mock out parts of the system easily, those mockable parts make your system ultra-flexible.

We are on to another project now. One full of legacy code and no unit tests. Our eyes have been opened to what quality code can be and it is already influencing how we work on this new challenge. Try it and stick with it. Aiming for 100% test coverage but settling for 60% is enough to raise the quality of your code and your job satisfaction immeasurably.