Testing 1o1 - what is the difference between integration tests and unit tests?

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 Calculatorclass 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 clickevents 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 Calculatormethods.

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.