CHAPTER 07
Intermediate
Integration Testing
Updated: May 16, 2026
25 min read
# CHAPTER 7
Integration Testing
1. Introduction
Imagine you buy a high-end lock and a heavy-duty door. You test the lock (Unit Test 1)—it works perfectly. You test the door hinges (Unit Test 2)—they swing perfectly. Then you install the lock on the door, close it, and realize the lock doesn't align with the doorframe. The door won't lock. This is the classic failure of integrating two perfectly working units. In software, Integration Testing is the phase where individual units or modules are combined and tested as a group. In this chapter, we will master the complexities of Integration Testing. We will drop our "Mocks," connect to real databases and APIs, and ensure the handoffs between different systems function flawlessly.2. Learning Objectives
By the end of this chapter, you will be able to:- Define "Integration Testing" and differentiate it from Unit Testing.
- Understand the "Big Bang" vs. "Incremental" integration approaches.
- Write tests that validate real Database interactions (CRUD operations).
- Validate data flow between the Frontend, the Backend, and Third-Party APIs.
- Set up automated testing databases.
3. What is Integration Testing?
While Unit Testing focuses on *internal logic*, Integration Testing focuses on *data flow and communication*.- The Goal: Expose faults in the interaction between integrated units.
-
The Reality Check: In Unit Testing, we used a "Mock" database. In Integration Testing, we connect to a real (but temporary) test database. We actually execute the
INSERTSQL statement and verify the data was written to the disk.
4. Integration Approaches
- 1. Big Bang Approach: All modules are developed, merged together all at once, and tested as a single massive system. (Highly discouraged; finding the source of a bug is nearly impossible).
- 2. Incremental - Top-Down: Testing the high-level UI/Controllers first, using "Stubs" to simulate the lower-level database functions that aren't built yet.
- 3. Incremental - Bottom-Up: Testing the database and lower-level services first, using "Drivers" to simulate the UI calling them.
5. Database Integration Testing
This is the most common and critical form of integration testing.- The Process:
- 1. Boot up a dedicated Test Database (e.g., using Docker or SQLite in-memory).
- 2. Run Database Migrations to create the tables.
-
3.
Execute the
UserService->create()method.
- 4. Assert that the record actually exists in the database.
- 5. Crucial Step: Clear the database before the next test runs to ensure test isolation.
6. Third-Party API Integration
Modern apps rely on Stripe (Payments), Twilio (SMS), or SendGrid (Email).- The Danger: You cannot hit the *real* production Stripe API during automated testing, or you will accidentally charge real credit cards.
- The Solution: You hit the "Sandbox" or "Test Environment" APIs provided by these services, verifying that your app sends the correct JSON payload and correctly handles the API's response.
7. Visual Learning: Data Flow
txt
*Integration testing focuses on the "Lines" (Integration Points), while Unit testing focuses on the "Boxes".*
8. Best Practices
- Use Dedicated Test Databases: Never, under any circumstances, run integration tests against a development or production database. Integration tests create and destroy data rapidly. They will corrupt your development data. Always use an isolated testing database (like a fast SQLite file) that gets wiped clean after every single test.
9. Common Mistakes
-
The "Brittle Data" Problem: Writing an integration test that assumes User ID
5already exists in the database. If someone deletes User5from the test database, the test fails. Tests should always create their own data (using Factories/Seeders) at the beginning of the test, and clean it up at the end.
10. Mini Project: Database Integration Test Workflow
Scenario: Testing the creation of an Order. Workflow:- 1. Setup: The testing framework creates an empty test database.
- 2. Arrange: The test creates a dummy User and a dummy Product in the DB.
-
3.
Act: The test calls
$orderService->placeOrder($userId, $productId).
-
4.
Assert: The test queries the DB to ensure an
ordersrow was created with the correct IDs and total price.
- 5. Teardown: The testing framework deletes all data, leaving the DB empty.
11. Practice Exercises
- 1. Explain the analogy of the lock and the door in relation to Unit vs. Integration testing.
- 2. Why is the "Big Bang" integration approach considered dangerous and outdated?
12. MCQs with Answers
Question 1
What is the defining characteristic of an Integration Test compared to a Unit Test?
Question 2
When running Integration Tests that involve database operations, what is the most important rule regarding the database environment?
13. Interview Questions
- Q: Explain the "Bottom-Up" approach to incremental integration testing.
- Q: You need to test a checkout flow that relies on the Stripe Payment API. How do you test this integration automatically in a CI/CD pipeline without charging real credit cards?
- Q: A developer complains that their integration tests fail randomly. One run they pass, the next run they fail. What is the most likely cause regarding test data management?