What? Your code failed but your unit-test passed? Weird
When auto engineers design a new car, they spend weeks and probably months studying the designs and thinking about the different conditions and values. They create computer generated models to test and validate their designs. The thing is that you can’t just stop there. You have to build the car with every step and component before you can validate the car can be built. It is only after that crowning achievement has been built that you could then test the outcome of your planning.
I feel that I have started to sound like a broken record at this point. I spend a lot of time pushing the concept of testing to my client’s development teams. As part of the effort, I have even given a boot camp on how to write better tests and recipes. I talk about the Test-then-fail method (It is how I describe the practice of Test Driven Development) for writing code. One thing that I do stress, sometimes to the point of insanity, is the difference between Unit and Integration testing.
In a previous article, I talked about the benefits of testing and validation when it comes to the development life-cycle. Recently, I have started to change the words that I use when I describe Unit and Integration testing. Instead, I describe it as ‘Testing the expectations of my code” and “Validating the output of my code”. These definitions are worlds apart.
What did you expect from me?
A unit test validates how a specific part of your code behaves under controlled conditions. In order to meet these results, we will often mock-up the conditions and output of commands. This allows us to account for all potential situations. Often, it is hard or difficult to trigger potential exceptions in the real world but we know that we should test those types of situations.
Hmm let’s check your report card, shall we?
After you deploy your code, we want to see what happens and verify that our expectations have been met in our output. This is the stage where integration testing will come into the equation. I want to confirm that the output of my execution actually returns the results that I expected to see. The integration tests make sure compliance of the solution later on. This is extremely important as unit tests only make sure that our code can handle different situations but never validates the outcome.
Clever developer but wait.. what?
A few weeks ago, I had an interesting tale told to me about a recent meeting with a development team. The team had written remediation cookbooks and embracing the Unit testing method. In fact, they had developed some very eloquent unit tests that covered an amazing amount use cases. In reviewing the code, the question came up about the integration tests. There was silence followed by a quick ‘we have unit testing, we don’t need integration testing’. This baffled a few people and then the question came, has this code been tested? It had been previously noted that a portion of the code would break Windows if it ran but surely this team had tested the code. The team insisted that they tested this code many times and was production ready. In fact it was not. Someone from the infrastructure team fired up a new server and ran the code on a default Virtual Machine template. After the recipe ran, the system rebooted and never came back.