# Test bodies are not empty or TODO-only

- **Pattern:** `ab-000303` (`ai-slop-test-theater.coverage-reality.tests-not-empty-or-todo`)
- **Severity:** medium
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-000303
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-000303)

## Why it matters

An empty `it('creates a user', () => {})` body or one containing only `// TODO` passes unconditionally in every test runner — it shows green in CI, increments the test count, and contributes nothing. AI coding tools scaffold test stubs frequently and treat them as "complete" once the file is syntactically valid. The downstream effect: the team believes behavior is tested when it isn't, and a growing backlog of TODO-only tests never gets implemented because they never fail to remind anyone. ISO-25010:2011 testability requires that tests verify actual behavior.

## Severity rationale

Medium because empty test bodies silently inflate the reported test count and create a false sense of coverage without catching any real defects.

## Remediation

Implement or delete every empty or TODO-only test body. Use `it.todo()` instead of `it('name', () => { /* TODO */ })` — `it.todo` is semantically correct and most runners surface it as a pending test rather than a pass:

```ts
// Before: passes silently, zero verification
it('creates a user', () => {})
it('verifies password', () => { /* TODO */ })

// After option A: implement with real assertions
it('creates a user', async () => {
  const user = await createUser({ email: 'a@b.com' })
  expect(user.id).toBeDefined()
})

// After option B: mark as genuinely pending
it.todo('creates a user') // shown as pending in vitest/jest output, not a pass
```

## Detection

- **ID:** `tests-not-empty-or-todo`
- **Severity:** `medium`
- **What to look for:** Walk all test files. Count all `it(`/`test(` blocks whose body contains ONLY a `TODO` comment, ONLY a `// implement me` comment, OR is completely empty (just whitespace). Also count all blocks whose body is just `expect.assertions(0)` (which marks the test as expecting zero assertions).
- **Pass criteria:** 0 test bodies are empty, TODO-only, or `expect.assertions(0)`. Report: "X test blocks inspected, 0 empty/todo."
- **Fail criteria:** At least 1 test block has an empty body OR a TODO-only body.
- **Skip (N/A) when:** Project has 0 test files.
- **Detail on fail:** `"3 empty/todo test blocks: tests/api.test.ts line 12 'it(\"creates a user\", () => {})' (empty body), tests/auth.test.ts line 23 'it(\"verifies password\", () => { /* TODO */ })'"`
- **Remediation:** An empty test passes silently. Either implement it or delete it:

  ```ts
  // Bad: passes regardless of production code
  it('creates a user', () => {})

  // Good: actually implemented
  it('creates a user', async () => {
    const user = await createUser({ email: 'a@b.com' })
    expect(user).toBeDefined()
  })

  // Or: explicit TODO that fails CI
  it.todo('creates a user')  // marked as todo, doesn't silently pass
  ```

## External references

- iso-25010 maintainability.testability

Taxons: code-quality

HTML version: https://auditbuffet.com/patterns/ab-000303
