Many people ask me about this comparison and even about the proportion of each type of tests.
I faced several situations when I needed to evaluation the best approach and of course is not like black and white situation, but I personally defend that should always favor the Unit Tests.
I compiled a comparison table about the two types of tests to help us to brainstorming about it.
Integration Tests VS Unit Tests
|Integration Test||Unit Test|
|Difficult to maintain||Easy to maintain|
|Usually don´t test every possible path||Usually test every method parameters combinations and paths|
|Difficult troubleshooting (many objects, many layers, many external resources are involved)||Straightforward to identity the problem and to fix (test of single unit of code)|
|Can take long time to execute||Is fast to execute|
|Parallel execution could causes problems||Are executed in parallel with no problems (if well done)|
|Can be executed against any kind of implementation||Force us to improve the code to make it testable.|
|Complex to setup||Easy to setup|
|Can give false-positive result (since it’s a black box test we can get correct result without knowing exactly how this result was generated – could be fixed or manipulated data i.e)||We are testing a small piece of code and we can perform multiple types of validation not only against the result but how it’s generated|
So why/when we need Integration Tests
Have more and good unit tests will ensure more product quality
So why we need and why we have Integration Tests
The integration test provide us a test of integration parts like:
- connections (databases, caching system, message queue…)
- application bootstrap
- infrastructure aspects (protocols, access control, authentication…)
How many integration tests we need to test this “integrations”?
Just a few tests. Not for all functionalities or use cases.
That’s why we should have much more unit tests (good tests with high code coverage)
What is, why is bad and how to prevent
The Code Smells, a symptom of our weakness. Seems to be faster than do the good option, but as always, the bad code slow down the team and makes we going slower.
How to know if you are creating a Primitive Obsession Code Smell?
- A primitive should never travel “naked” around the code.
When I say “naked” I mean: alone, opened, outside a class
Even for the most simple code or method we may think that would not be a problem to have this “data” traveling. But “the problem we don’t see today probably we will face tomorrow”
On this code, for instance, I decide to receive a Phone Number through a primitive variable as a parameter:
void AddPhone(string phoneNumber)
We can predict a many of problems from this code as:
- How we can insure that the phone number is valid?
- What if our system works with multiple countries with different phone numbers formats?
- What if we need to add more related information like zone code, country code and so on?
- What if our system need to validate that phone number is mandatory?
- What if we need to control phone types?
Primitive constants to control information is another case:
const int PHONE_TYPE_CELLPHONE = 1;
const int PHONE_TYPE_HOME = 1;
void AddPhone(string phoneNumber, int phoneType)
//validating by phone type
What is the problem?
The most important issues are about Consistency and Scalability. Why?
- If we use primitives and need consistency, we’ll need to add validations all over the place to guarantee that the data is correct all the time
- If we have more than one related data (like phoneNumber and phoneType) the consistency will be much more difficult to achieve (see Data Clumps code smell)
- Using primitives we can’t scale, won’t be easy to add new features, validations or data.
- Probably use primitives will drive us to add more and more
There is no problem at all by creating a small class, even with just one attribute, property or field. This will allow you to scale, reuse and keep your software good inside.
If we model the system using objects from beginning the cost will be minimal and we’ll have a scalable, consistent and healthy software.