Skip to main content
Lesson 7 of 20 · Codex: AI-Assisted Development

Automated Unit and Integration Tests

Lesson 7 of 20 Updated July 29, 2026 Developer
On this page
  1. Automate Test Writing
  2. Generate Unit Tests
  3. Generate Integration Tests
  4. Cover an Entire Project
  5. Improve Existing Tests
  6. Tests by Component Type
  7. Configure AGENTS.md for Tests
  8. Key Takeaways

Automate Test Writing

Tests are the first thing you cut when time runs short, and the debt that costs the most later. Codex changes the trade-off: generating full coverage for a module becomes a matter of minutes rather than an afternoon. But you must ask for more than “write tests,” an instruction that yields a handful of nominal cases—green, reassuring, and worthless.

Generate Unit Tests

The main lever is to name the edge cases yourself. You know your business domain; the agent doesn’t know that a discount greater than 100% happens once a quarter in your data.

"Generate unit tests for src/lib/pricing.ts. 
Use Vitest. Cover all edge cases: negative price, 
discount > 100%, invalid currency, zero quantity."

Codex analyzes the source code, identifies exported functions, understands their logic, and then produces a suite that covers both normal paths and the cases you cited.

// src/lib/pricing.test.ts
import { describe, it, expect } from "vitest";
import { calculatePrice, applyDiscount, formatPrice } from "./pricing";

describe("calculatePrice", () => {
  it("calculates total price for a positive quantity", () => {
    expect(calculatePrice(10, 3)).toBe(30);
  });

  it("returns 0 for a quantity of zero", () => {
    expect(calculatePrice(10, 0)).toBe(0);
  });

  it("throws an error for a negative price", () => {
    expect(() => calculatePrice(-5, 1)).toThrow("Invalid price");
  });
});

describe("applyDiscount", () => {
  it("applies a standard discount", () => {
    expect(applyDiscount(100, 20)).toBe(80);
  });

  it("rejects a discount greater than 100%", () => {
    expect(() => applyDiscount(100, 150)).toThrow();
  });
});

One detail deserves inspection: the expected error message, “Invalid price,” was taken from the actual implementation, not invented. This is the signature of a test written from the code rather than from a template, and the first thing to check when reviewing a generated suite.

Generate Integration Tests

For an API route or a service that touches the database, you need to provide more context, especially regarding what to mock.

"Generate integration tests for src/api/routes/orders.ts.
Use supertest for HTTP requests. Mock the Stripe 
service with vi.mock. Test scenarios: order creation, 
order with non-existent product, failed payment."

Codex clearly distinguishes between the two test levels: it configures appropriate mocks, handles test database setup and teardown, and simulates external services. Explicitly naming Stripe and supertest prevents it from inventing parallel infrastructure to what your team already uses.

Cover an Entire Project

On a project structurally lacking tests, a global task is more effective than a series of file-by-file requests.

"Analyze all .ts files in src/lib/ and src/services/. 
For each file without a corresponding .test.ts file, 
generate unit tests. Aim for branch coverage > 80%."

Codex then processes the files one by one, adapting tests to each module; count several minutes of execution for a complete suite. Run this task on one folder at a time rather than on the entire src/ directory: beyond that, the pull request becomes too large to review, and a test suite approved without reading protects no one.

Improve Existing Tests

Codex doesn’t just create; it can also diagnose a suite that reassures without protecting.

"Analyze tests in src/__tests__/. Identify:
- Tests that check only one path (happy path)
- Vague assertions (toBeTruthy instead of toBe)
- Tests that share mutable state
Fix these issues."

These three symptoms explain most green suites that let bugs slip through. The third is the most insidious: tests that share mutable state pass as long as they run in the usual order, and start failing randomly the day you enable parallelization.

Tests by Component Type

The type of test to request depends directly on the nature of the code, and the instruction changes with it.

Code TypeTest TypeCodex Instruction
Utility functionUnit”Test all possible inputs and outputs”
API routeIntegration”Test with supertest, mock external services”
React componentRendering”Test rendering and interactions with Testing Library”
Service with DBIntegration”Use a test DB, reset between each test”

Configure AGENTS.md for Tests

Rather than repeating these choices for every task, write them once and for all in a dedicated section of AGENTS.md.

## Tests
- Framework: Vitest
- Command: `npm run test`
- Coverage: `npm run test:coverage`
- Convention: .test.ts files next to source code
- Mocks: use vi.mock(), no manual mocks
- Assertions: prefer toBe/toEqual over toBeTruthy/toBeFalsy
- Each test must be independent (no shared state)

With these seven lines, Codex applies your conventions to every test it generates, even when a rushed developer phrases their request in three words. This is the most economical way to make your test quality independent of instruction quality.

Key Takeaways

  • Codex generates tests adapted to your code, not generic tests
  • Specify the edge cases you want to cover in your instructions
  • Codex distinguishes between unit tests and integration tests
  • Use AGENTS.md to define your testing conventions
  • Codex can improve existing tests, not just create new ones