Integration testing checks that several components work correctly together, exercising the real seams between them — a parser feeding a decoder, or code talking to a database.1
What it is
Where a unit test isolates one piece, an integration test deliberately wires several pieces together and checks that the combination behaves correctly. The bugs it catches live in the joins — mismatched assumptions about data formats, wrong ordering, broken contracts between an API and its caller, or a query that doesn’t match the schema. These tests often use real collaborators (a real database, a real file format) precisely because the seam is the thing under test, though they may still stub out slow or external systems via mocking.
Where it sits
Integration tests form the middle layer of the test pyramid: fewer than unit tests and slower, because they exercise real interactions rather than one isolated function.1 That trade-off is deliberate — they give more end-to-end-like confidence than a unit test while remaining faster and more targeted than a full end-to-end test. A healthy suite has a wide base of unit tests, a smaller band of integration tests, and only a thin tip of E2E.
In practice
Like all tests, integration tests only protect you if they run automatically. A CI/CD pipeline builds the code and runs the full suite on every push, so a broken seam is caught within minutes. They contribute to code coverage and complement the test-driven development habit of specifying behavior before building it.
Sources
-
Integration testing — Wikipedia, for the definition and its place between unit and end-to-end tests. ↩ ↩2