Testing 1o1 - what is the difference between integration tests and unit tests?
Unit tests and e2e tests are quite easy to differentiate, but how would you describe the difference between integration and unit tests?
With that I wish you a happy new year and have fun with todays topic.
Blackbox and Whitebox testing
Blackbox tests don't know about the internal structure of the code and don't need to know it. They will just call a really high level entry point of the system under test and operate on it.
Representatives of black box testing include:
System tests and
e2e tests.
Whitebox testing
On the other side: Whitebox tests. They know the internal structure of the code quite well. That's why you as a developer need to understand the structure, too. Think of unit tests. You are likely to write a unit test for a class or a method. For example:
class Calculator {
calculateSum(items: number[]): number {
return items.reduce((prev, curr) => prev + curr), 0);
}
}
// Classic unit test in Typescript
describe("Calculator Tests", () => {
it("Works with 3 items", () => {
const sum = new Calculator().calculateSum([-1, 20, 1]);
expect(sum).toEqual(20);
})
})
You need to know that there is a Calculator
class and how to instantiate it, before you are able to create a test for it.
If the program was now much more complex and had a simple UI, you could just call the entry point of the program and emulate the click
events to get to implicitly call these functions. Also known as e2e testing.
So what's integration testing now?
Integration testing is quite similar to unit testing. It is also a white box testing method. To be honest, it's just like unit testing. The major difference is that integration testing puts several units under test.
In other words:
Integration tests test the integration of a compound of units.
Example of integration test
The integration test scenario might consist of a UI adapter that triggers certain Calculator
methods.
class CalculatorUIController {
private _numbersToSum: number[] = [];
private _sum: number;
constructor(private _calculator: Calculator) {
this._sum = 0;
}
addNumberToSum(num: number) {
this._numbersToSum = num;
}
calculate() {
this._sum = this._calculator.calculateSum();
this._numbersToSum = []; // reset state
}
}
You see that this class consist of multiple units, the actual UI and the Calculator
module.
The CalculatorUIController
implictly tests the Calculator
class, because there are calls it in the UIController.