For the complete documentation index, see llms.txt. This page is also available as Markdown.

Integration Testing with AI Agents

Test real HTTP and application boundaries with Claude Code, Cursor, or Codex, then use ContextQA MCP for deployed API and workflow checks.

Quick answer

Ask your coding agent to identify the real boundary at risk, provision isolated test dependencies, and assert both the response and the relevant state. Run the test with your repository's runner. For deployed API coverage, ContextQA MCP can generate cases from an OpenAPI specification and retrieve execution evidence. A test with every dependency mocked does not prove those integrations work.

An integration test might connect an HTTP client to a real service, a repository layer to a real test database, or a consumer to a sandbox provider. State precisely which boundary is exercised. This guide's runnable example covers HTTP serialization, request validation, and a shipping policy function; it deliberately does not claim database, payment, or production integration coverage.

Prerequisites and scope

Use a checkout with an established test command, documented API behavior, and isolated dependencies. For database tests, know how to create, reset, and dispose of the test database. For provider tests, use a sandbox account with approved credentials and a controlled quota. Avoid shared identifiers that let concurrent jobs overwrite one another's data.

The local example requires Node.js 24 or later, uses only built-in modules, and starts a server on an available loopback port. No external service or ContextQA account is required. If you already use Playwright Test, its request client can also test HTTP APIs and prepare or verify application state. Playwright API testing.

1. Define the boundary and observable contract

For an illustrative shipping API, POST /quote accepts JSON containing subtotalCents and country. Valid input returns an exact shipping fee. Invalid JSON returns 400; valid JSON with an invalid value returns 422. Other paths return 404. The fee policy is the one in the unit-testing guide.

Write down what this does not exercise: authentication, a database, deployment networking, tax, or carrier pricing. Those need their own requirements and test environments. This scope statement prevents a small local green result from becoming an unsupported release claim.

For an actual database integration, add an assertion using a new transaction or independent read connection after the write. An HTTP 201 alone cannot prove that the intended record was committed with the correct tenant and values.

2. Give the agent the contract and lifecycle

Inspect our API implementation, schema, existing integration runner,
and test-environment setup. Identify which boundaries are real and
which are mocked. Do not label fully mocked interactions integration.

Add tests for valid requests, malformed JSON, invalid values, and
unsupported routes. Assert exact response bodies, not status alone.
For persisted operations, verify committed state through an independent
read and clean up only records created by this test run.

Use an isolated environment and unique data. Await startup, use bounded
request timeouts, and close connections even when assertions fail.
Run the focused suite and report commands, exit codes, actual boundaries,
failed cases, and any dependency that prevented execution.

Tell Claude Code, Cursor, or Codex which fixture/reset commands already exist. Do not let the agent silently replace an unavailable real dependency with a mock and keep the original coverage claim.

3. Build a small real HTTP fixture

Copy shipping.mjs from the unit guide into a local directory. Save this illustrative application adapter beside it as quote-server.mjs:

This intentionally small, loopback-only teaching server is not a production API template: it has no authentication, body-size limit, or operational error middleware. In your application, import the real server factory rather than copying this handler into tests.

Save quote.integration.test.mjs beside it:

Run:

The request uses an actual HTTP socket. Replacing fetch with a stub returning the expected body would remove the boundary this example is intended to test. Node's runner awaits an async test's returned promise; preserve that lifecycle when adapting the fixture. Node test runner.

4. Add the risks your integration actually has

Extend the contract rather than adding generic cases indiscriminately:

Boundary
Useful negative or boundary checks

Authentication and tenancy

Missing token; expired token; another tenant's resource ID; correct denial with no data change

Database write

Duplicate key; transaction rollback; concurrent updates; committed values read back independently

External provider

Timeout; documented error response; rate limit; idempotent retry; no duplicate side effect

Event or queue

Schema mismatch; duplicate delivery; delayed event; final state within an explicit deadline

For eventually consistent systems, poll a meaningful state with a finite deadline and report the last observation. A fixed sleep may be too short on a slow run and wastes time on a fast one. An absent sandbox or unavailable dependency is a blocked test, not a passing result.

5. Add ContextQA MCP coverage for the deployed boundary

Set up ContextQA MCP and confirm the connected workspace. The documented generate_tests_from_swagger input is file_path_or_url. Review the connected tool's actual schema before supplying a local path: a hosted tool may not share your computer's filesystem. Use a specification source the configured tool can access without publishing private API details. Generation tool reference.

Use the documented create/run/result sequence from execution and results. ContextQA cases and native repository integration tests remain separately runnable assets. For a workflow combining browser actions and API checks, continue with end-to-end testing.

Debugging and verification

When a test fails, preserve the request shape, status, relevant response, environment, and correlation ID without exposing tokens. Check connectivity before changing assertions. If a response is wrong, separate transport failure, contract mismatch, and incorrect business behavior. Rerun after a fix with the original failure attached; a retry does not invalidate the first observation.

Common questions

Is an API test always an integration test?

No. A client tested entirely against a mocked response checks client behavior. A real HTTP request to the intended service exercises that boundary; a database or external provider is covered only if it participates.

Does OpenAPI generation prove all business rules?

No. The specification may omit permissions, side effects, concurrency, or domain rules. Add those requirements and verify the generated assertions.

Can I export these tests?

Keep native tests in Git. For ContextQA browser artifacts, follow export and portability and inspect the generated project; do not assume every API fixture or provider setup transfers unchanged.

Next step: Connect the MCP server, then book an integration-testing demo using one API contract and its downstream state checks.

Last updated

Was this helpful?