The Modern Testing Pyramid: Unit, Contract, Integration, E2E
The testing pyramid has four layers in 2026, not three. Where contract tests fit, why E2E should be small, and how to budget the test suite without slowing delivery.

The classic pyramid, updated
The original testing pyramid had three layers: a wide base of fast unit tests, a thinner band of integration tests, and a small peak of end-to-end tests. That model holds, but modern microservice architectures need a fourth layer between unit and integration: contract tests.
The pyramid is a budget, not a target. The goal is fast feedback with high confidence — not maximum coverage at every layer.
Unit tests: fast, deterministic, plentiful
Unit tests exercise a single function or class in isolation. They run in milliseconds, depend on nothing external, and fail deterministically. Aim for 70–80 percent of total test count and under five minutes total runtime.
Mocking is acceptable for collaborators that are not the unit under test. Over-mocking — mocking everything until the test only verifies the mock setup — is a smell.
Contract tests: the missing layer
Contract tests verify that the API a service exposes matches what its consumers expect. Tools like Pact run consumer-side tests that generate a contract, then verify the producer against that contract in its CI. This catches breaking changes at the producer's pipeline, before deployment.
Contract tests replace most of what teams used to do with shared integration test environments. They are faster, more deterministic, and they scale to many consumers without coordination meetings.
Integration tests: the boundary with the outside world
Integration tests exercise your code against real implementations of its dependencies — a real Postgres, a real Redis, a real S3 (or LocalStack). They run in seconds to minutes and catch the wiring bugs unit tests cannot.
Testcontainers is the modern standard for this layer. It spins up real services in containers per test suite and tears them down on completion. The fixture overhead is real but the confidence is high.
End-to-end tests: small, stable, valuable
End-to-end tests exercise the full system through its real interfaces — typically a browser driving the UI. They are slow, flaky, and expensive. They should number in the dozens, not hundreds, and cover the critical user journeys: signup, checkout, the core happy paths.
Playwright is the current best tool. Cypress is still credible. Both let you reduce flake to near zero if you discipline your selectors and your wait conditions.
What gets measured: coverage versus confidence
Line coverage is a leading indicator, not a goal. Aim for high coverage on the domain layer (90 percent plus), moderate on application (70 percent), and low on infrastructure adapters (smoke coverage is fine — integration tests cover the real behavior).
Branch coverage matters more than line coverage for business logic. Mutation testing (Stryker, PIT) is the next step up — it catches tests that exercise code without actually asserting on it.
Reader questions, answered
Do I need Pact?+
If you have multiple teams consuming the same internal API, yes. For a single consumer or external public API, contract tests are less essential.
Is BDD still relevant?+
BDD as a notation is fine. BDD as a process is largely dead. Use Given-When-Then for clarity, not as a development methodology.

Raza Ahmad is a technology author and IT infrastructure specialist based in Melbourne, Australia. He writes practitioner-grade guides on cloud computing (Azure and AWS), cybersecurity, enterprise networking with Cisco platforms, Linux administration, DevOps, and virtualization. His work focuses on translating complex infrastructure topics into clear, accurate guidance that engineers, system administrators, and IT decision makers can put to work in production environments. Every article published under his byline is fact-checked against current vendor documentation, official standards, and Raza's own hands-on experience operating the technologies he covers.
More from Software Engineering

Clean Architecture in TypeScript: A Pragmatic Guide
Clean architecture without the cargo cult. A working TypeScript reference for separating business logic from frameworks, databases, and HTTP.

Domain-Driven Design for Microservices Without the Cargo Cult
DDD is the most useful and the most misused framework in modern software design. Here is how to apply it to microservice boundaries without becoming a parody of itself.

Monorepo vs Polyrepo: A Decision Framework for 2026
Both Google and Amazon ship at scale; one runs a single repository, the other runs thousands. Here is how to decide which model fits your team.
One email. The technology stories that actually matter for engineers.
A curated digest of the week's most useful tutorials, reviews, and analysis — no clickbait, no AI summaries of someone else's work.
Free. Unsubscribe anytime. See our privacy policy.