In the previous article, I gave an introduction of unit testing and test driven development (TDD). I also discussed why for a modern day software developer, TDD is mandatory! In this article I will go into a little bit of more detail about unit tests and tell you the various types of unit tests.
Types of Tests
Although if you search online, you will find that there are a lot of different types of tests and each one of them adds different value and benefit. In my personal opinion you need to be aware of 5 types of tests at most as most of the times you will never be using anything other than them.
As I discussed in the last article, a unit test simply tests a small distinct part of your application code. A unit test needs to be very fast and it should only be testing one thing and one thing only. If a unit test is testing more than one thing and it fails. You will not know the reason for its failure. Unit tests should only test the behavior of the class i.e. its methods.
Now I know a lot of people that will tend to disagree, but in my view the only thing that you do need to test in your application is its behavior and you do not need to worry about the state. I will be posting a lot of articles in BDD (Behavior Driven Development) in the near future so be sure to check them out if you need to know about this phenomena in greater detail.
Because unit tests should test behavior and because objects in our code interact with each other, it is extremely important that unit tests test the behavior of a class in isolation.
If for example you have a class that processes some information and then calls another method of some class to save that information in the database, it is extremely important that you isolate the piece of code that processes information from the code that saves it in the database. This isolation is necessary for unit test. If you are not isolating your code then you are not really writing unit tests but rather integration tests.
So in unit tests, software modules and objects are tested alone in isolation. This isolation is achieved using mocks and fakes which I will discuss in greater detail in another article.
In integration testing individual software modules and objects are combined and tested as a group. So in integration tests it is ok to test classes and objects together in a group. The purpose of integration tests is to make sure that the objects interact with each other correctly. Imagine a case where you would have a lot of beautiful Lego blocks that look really nice and have been carved to perfection but when you try to put them together they do not fit. I do not think anyone would buy a set of such Lego blocks. Integration tests allow us to be certain that the classes and modules that we have developed and tested via unit tests, work together seamlessly and accurately as expected.
Simply put acceptance tests are a special type of integration tests that normally test the application from end to end. In modern time a lot of tools exist that can simulate the role of a tester. They can fill forms, set controls state and simulate different events and then verify the application behavior.
For example a simple acceptance test can verify that when you enter a certain user name and password in the login form and then click login, the application should take you to home page.
Of all the various types of automated tests, acceptance tests are by far the slowest and therefore least in number.
A good rule of thumb is that you should have 100% code coverage of your code with unit tests. Then you should always test the interaction among your classes with integration tests where it is necessary and for the most important scenarios you can have some acceptance tests to verify that the critical part of the application is functioning correctly.
A good rule of thumb that is quite common is that you should have 75% of unit tests, 20% integration tests and about 3-5% of acceptance tests. This by no means is a rule to always follow but it does give you an idea about how much focus you should put into each type of test.
Black box testing
It is a technique of testing in which you simply test the public interface or methods of an object or class without knowing about their internal implementation.
White box testing
This simply means to test all parts of an interface or class with complete knowledge about their implementation.
There are a lot of other types of automated tests but I feel that the knowledge of these five is sufficient and mastering how to write each of these is a must. Whether you have a difference of opinion on what part of the application should be tested, you should by know accept that automated testing needs to be learned and there is no other way to have faith in the code that you right.