An integration test checks whether multiple software components work together correctly. Rather than isolating one unit, it exercises interactions between modules and looks for communication problems that appear only when the pieces are combined. It supports broader checks of reliability, correctness, efficiency, security, and compatibility, while helping uncover defects early. section 6.0 section 6.7
A practical integration test can drive an end-to-end path through an application. For a FastAPI controller, use the framework’s test client, create the collaborating repository, port, and controller objects, seed representative data, then invoke the route and check the response. This tests the route together with the components behind it rather than testing each implementation in isolation. section 6.1.2
When using an AI assistant to draft an integration test:
- Provide the controller definition and its routes so the generated test has the interfaces it needs. section 6.1.2
- State the intended repository implementation, such as an in-memory repository, or correct that dependency after generation. section 6.1.2
- Review the generated setup and assertions against the actual application before relying on the test. section 6.1.2
Testing an asset endpoint
Create an in-memory asset repository and add two assets. Connect it to an asset REST port and an AssetController, then use a FastAPI TestClient to exercise the controller’s route. The example’s value is the assembled path: repository data flows through the port and controller to an HTTP-facing test, where the returned result can be asserted. section 6.1.2 section 6.7
Listing 6.7 Copilot Chat-generated integration test of AssetController
from fastapi.testclient import TestClient
from itam.infrastructure.adapters.memory_asset_repository import MemoryAssetRepository
from itam.infrastructure.ports.asset_rest_port import AssetRestPort
from itam.interfaces.asset_controller import AssetController
def test_get_assets():
# Create an instance of the InMemoryAssetRepository
asset_repository = InMemoryAssetRepository()
# Add some assets to the repository
asset_repository.create(Asset(name="Asset 1", unit_cost=1000))
asset_repository.create(Asset(name="Asset 2", unit_cost=2000))
# Create an instance of the AssetRestPort using the MemoryAssetRepository
asset_rest_port = AssetRestPort(asset_repository)
# Create an instance of the AssetController using the AssetRestPort
asset_controller = AssetController(asset_rest_port)
# Create a TestClient instance using the AssetController's router
client = TestClient(asset_controller.get_router())
# Send a GET request to the /assets endpoint
response = client.get("/assets")
# Check that the response status code is 200 OK
assert response.status_code == 200
# Check that the response body contains the expected assets
assert response.json() == [
{"id": 1, "name": "Asset 1", "unit_cost": 1000},
{"id": 2, "name": "Asset 2", "unit_cost": 2000},
This listing shows a generated starting point for wiring an in-memory repository, REST port, and controller into an integration test. section 6.1.2
Keep the test’s scope distinct from nearby testing approaches. Unit tests target individual components and are commonly the most numerous tests. Behavior tests instead assess the whole system from an end user’s perspective against requirements and specifications. Integration tests occupy the middle ground by concentrating on component boundaries and collaboration. section 6.1.1 section 6.1.2 section 6.7






























