One day, browsing through software development communities I came across the following image:
I confess that the first time I didn't understand what the image was about, but I was sure that a cheap rabbit was better than an expensive turtle.
Time passed, I finally learned what unit tests are, what this cheap rabbit represents and I would like to help you understand too.
But what are unit tests?
A unit test is basically testing the smallest testable part of a program.
Okay, but what does that mean?
If you pr the grass in a language that supports functional paradigm for example, the smallest testable part of your code should be a function. So a unit test would be the test of any function. In the case of object orientation it would be the testing of a method of your object.
Well… as everything is easier to understand in practice, let's go to the code!
In the example below, we have a function that adds two numbers and returns the sum value.
function sum(a, b){
return a + b;
}
To test this code, all we need to do is run the function and check if its output value is what we expect.
var result = sum(1, 2);
expect(result).to.equal(3);
Ready! We already have our first unit test. Pretty easy isn't it?
Well.. Now that you understand what unit tests are and how unit tests are done, you might be asking yourself:
What are unit tests for?
Asking what unit tests or any other automated tests are for is a great question, after all there are several ways that apparently are faster to test if my function is doing what it should. I could just run the code to make sure it's working.
So why am I going to write other code to test my code? What makes sure the second code works? Who tests the test?
Unit tests, as well as any automated tests, are not primarily for verifying that a specific function is working, but rather to ensure that your application continues to work after any changes to your code base.
Why write unit tests?
It may seem tempting at first not to write tests for a function you have just developed, after all, it is customary to write more code to test a function than the function code itself. But you must remember that you will spend most of your development time on a system working on its maintenance.
Your application will soon have a few hundred functions running, and in many times running each other, your code base gets huge and soon becomes humanly impossible to manually test after any change. Unit tests most often take just a few seconds to test your entire application.
Where to start?
There are several unit testing tools for each programming language. You can get started by reading the documentation for these tools from their examples.
Okay, but I still don't understand the cheap Rabbit and Expensive Turtle thing
I won't close this post without first explaining what the test pyramid means.
It's a concept developed by Mike Cohn that says you should have a lot more unit tests (unit tests) than GUI tests which are more user-level tests. Like clicking on a link for example.
The Pyramid Concept explains how costly GUI tests are compared to unit tests, as they take much longer to run and are also difficult to maintain, while unit tests are much simpler, faster and cheaper.
If you liked this blog post, consider following me for more such stuff. Also, feel free to add your thoughts!
Top comments (2)
Automated UI (like selenium) smoke tests give you a lot of bang for your buck. As long as you write them to only spider the application they can give you a lot of regression testing without requiring a lot of work. They actually exercise a lot of code because they are exercising the whole stack. Detailed UI functional tests, on the other hand, are a lot of work and very brittle. So if you are determined to get the most bang for you buck this is what I recommend.
1) UI functional smoke tests that spider all your UI
2) Unit tests that only test either very important functionality like things that involve money, or things that are very complicated. Complicated code development benefits from unit tests to begin with and also might need protection against accidental breakage.
All of the other simple and less important code. Let it ride. Unit testing isn't worth it. This of course means you need to throw away the "unit test percentage" metric goal like the ol' 70% or 80%. Those kind of blanket metrics are just used to impress management in my opinion because a one size fits all blanket metric like this is too simplistic.
I completely agree with you on the Selenium part and it not being as robust as some managers assert it to be. There exist excellent alternatives like automated testing and end-to-end blackbox testing, however, I still think it's worth pursuing in some particular situations, like in the case of legacy code.