GuideIntermediate
Contract and Integration Testing
Learn two disciplines that pick up right where unit tests with doubles leave off: contract testing (verifying that two components that talk to each other agree on their contract, consumer/provider) and integration testing (verifying that components actually work TOGETHER, crossing the seam, against real resources). The thread running through it: a green unit test can hide a broken integration, because the double was lying. Working on the Reservo case extended with a real SQLite-backed `BookingRepository` (alongside the familiar fake), you'll practice writing a consumer-driven contract test that runs the same battery against the fake and against the real implementation, verifying the contract from both sides (consumer and provider), and writing integration tests that cross the system's real boundaries — a SQLite transaction, a file, a minimal HTTP boundary — deciding what to keep real and what to double. It closes with data isolation in integration testing (transaction rollback, temporary resources) and a final project that combines a contract verified against both implementations with a full integration test of the `BookingService`.
- 64
- lessons
- 8
- modules
- English · Spanish
- available in
- Yes
- certificate
- Free
- access
Outcomes
What you'll be able to do
- Understand why a green unit test can hide a broken integration, and where contracts and integration fit in the test pyramid
- Recognize when a double (fake/stub) DIVERGES from the real component, and how that bug passes the unit test but blows up in production
- Write a consumer-driven contract test: a shared spec that runs the same battery of tests against the fake and against the real implementation
- Verify a contract from both sides — the consumer test ("I send X, I expect Y") and the provider test ("given X, I return Y") — to catch breaking changes before deployment
- Write integration tests that cross the seam for real, deciding what to keep real and what to double in an integration test
- Test at the system's real boundaries: a SQLite transaction, a file, a minimal HTTP call, keeping those tests fast and deterministic
- Isolate data and state in integration testing: transaction rollback, real-resource fixtures (creating and tearing down a temporary database), independent and repeatable tests
- Combine contract and integration testing on a real case: verify a repository against its fake and its SQLite implementation, and test the full service against the real repository
Before you start
What you need to bring
It's for you if...
- Devs who already use test doubles comfortably and want to verify those doubles aren't lying about real behavior
- Teams with more than one service or component talking to each other that need to catch broken contracts before deployment
- Devs who want to move from "unit test with a fake" to "test against a real database and HTTP boundary" without adopting a full web framework yet
- Devs laying the groundwork to test a real backend app (FastAPI, a production database) later on
Requirements and materials
- Test Doubles and Test Data guide completed (or equivalent: knowing how to use and build a fake, a stub, a mock)
- Testing Fundamentals and TDD guide completed (or equivalent: pytest, the TDD cycle, fixtures)
- Python 3.14 and pytest 9.1.1 installed locally (`sqlite3` and `http.server` are part of the standard library; Pact is treated as a concept, not installed)
Content
The syllabus, module by module
Open any of them to see its lessons.
- 1. Module introduction: the double that lies
- 2. Why doubles drift
- 3. When the fake returns `None` and the real one raises
- 4. Divergence of types and order
- 5. Divergence of uniqueness and transactions
- 6. Why the unit test can't see it
- 7. The cost in production
- 8. Mini-project: find the divergence the unit test doesn't reveal
- 1. Module introduction: from the problem to the cure
- 2. What a contract is
- 3. Consumer-driven contracts
- 4. The parametrized battery against the fake and SQLite
- 5. The contract catches module 2's divergence
- 6. State contracts versus interaction contracts
- 7. The concept of Pact
- 8. Mini-project: write the `BookingRepository` contract
- 1. Module introduction: the contract has two sides
- 2. The consumer side
- 3. The provider side
- 4. The same battery against the fake and the real one
- 5. Catching a provider breaking change
- 6. Catching a consumer over-assumption
- 7. Who owns the contract: consumer-driven
- 8. Mini-project: verify the contract from both sides
- 1. Module introduction: now, the pieces together
- 2. What a real integration test is
- 3. `BookingService` and SQLite, together
- 4. What to double and what to keep real
- 5. Solitary versus sociable tests
- 6. Integration catches what the unit doesn't
- 7. The cost of integration
- 8. Mini-project: a `book`→`get` integration against SQLite
- 1. Module introduction: the system's boundaries
- 2. What a boundary is
- 3. The database boundary: a real transaction
- 4. `:memory:` versus a file
- 5. The file boundary with `tmp_path`
- 6. The HTTP boundary with a real `http.server`
- 7. Fast and deterministic: when to touch the real thing and when to double
- 8. Mini-project: Reservo's three boundaries
- 1. Module introduction: the state that doesn't go away on its own
- 2. Why shared real state contaminates
- 3. The transaction rollback as isolation
- 4. Temporary DB fixtures with yield
- 5. `:memory:` versus temporary file
- 6. Seeding integration data
- 7. Independent and repeatable
- 8. Mini-project: isolate a Reservo integration suite
- 1. Module introduction: Reservo's complete process
- 2. Write the repository's consumer-driven contract
- 3. Verify the contract against the `FakeBookingRepository`
- 4. Verify the contract against the real `SqliteBookingRepository`
- 5. The end-to-end integration test: `book`→`get`→`cancel`
- 6. Isolate the integration with fixture and rollback
- 7. Catch a breaking change with the contract
- 8. Project: Reservo's contract + integration
Common questions
What people usually ask
No limit. It's a free guide: come in whenever you like, as often as you like.
No. Modules run from easier to harder, but you can jump to the one you need. Progress is saved per lesson.
Whatever is needed is listed under “What you need to bring”, above. If nothing is listed there, you can start from zero.
In the Club's WhatsApp group, and every two weeks there's a live with an instructor where questions get worked through.
Yes. It's issued automatically once you finish every lesson, with a verifiable code you can share on LinkedIn.
Start whenever you like
What students say
These reviews are from enrolled students who completed at least 50% of the course. We moderate reviews only on content grounds (spam, offensive language, personal data), never for being critical or negative.
No approved reviews yet.
Be the first to share your experience!