# Every test file contains at least one assertion

- **Pattern:** `ab-000291` (`ai-slop-test-theater.assertion-quality.every-test-file-has-assertion`)
- **Severity:** critical
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-000291
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-000291)

## Why it matters

An assertion-free test file is indistinguishable from a passing test in CI — it runs, it exits 0, and it tells you nothing. AI-generated test suites routinely produce these: scaffolded `describe`/`it` blocks that call setup helpers but never verify a return value, a side effect, or a thrown error. The gap only surfaces when a real defect slips to production and you realize your test suite was never checking anything. ISO-25010:2011 testability requires that tests can actually detect faults; assertion-free files by definition cannot.

## Severity rationale

Critical because a test that cannot fail provides zero defect-detection value regardless of how many times it runs.

## Remediation

Add at least one assertion to every `it`/`test` block. Every call to `createUser`, `fetchOrder`, or any production function should be followed by an `expect` on its return value or side effect. Replace empty or setup-only test bodies with real verifications:

```ts
// Before: passes when createUser is completely broken
it('creates a user', async () => {
  await createUser({ email: 'test@example.com' })
})

// After: fails if id, email, or timestamp is wrong
it('creates a user', async () => {
  const user = await createUser({ email: 'test@example.com' })
  expect(user.id).toBeDefined()
  expect(user.email).toBe('test@example.com')
  expect(user.createdAt).toBeInstanceOf(Date)
})
```

## Detection

- **ID:** `every-test-file-has-assertion`
- **Severity:** `critical`
- **What to look for:** Walk all test files. Count all test files found and verify each contains at least 1 of these assertion patterns: `expect(`, `assert(`, `assert.`, `.toBe(`, `.toEqual(`, `.toMatch(`, `.toHaveBeenCalled`, `.toHaveBeenCalledWith(`, `.toContain(`, `.toBeTruthy(`, `.toBeFalsy(`, `.toThrow(`, `.toResolve(`, `.toReject(`, `.should.`, `should(`, `chai.`, `t.is(`, `t.equal(`, `t.deepEqual(`, `t.true(`, `t.false(`, `t.throws(`, `t.notThrows(` (AVA), `expect.assertions(`, `.toMatchSnapshot(`, `.toMatchInlineSnapshot(`. Count: total test files, total with at least 1 assertion, total assertion-free.
- **Pass criteria:** 100% of test files contain at least 1 assertion pattern. Report: "X test files inspected, Y with assertions, 0 assertion-free."
- **Fail criteria:** At least 1 test file has zero assertion patterns.
- **Do NOT pass when:** A test file contains only `it(` calls with empty bodies or bodies that only call setup functions — those don't count as assertions.
- **Skip (N/A) when:** Project has 0 test files.
- **Report even on pass:** Always report the count of test files inspected and the assertion library detected. Example: "Test framework: vitest. 47 test files inspected, 47 with assertions (100%)."
- **Cross-reference:** For broader code quality metrics including test presence and structure, the Code Quality Essentials audit (`code-quality-essentials`) covers test organization patterns.
- **Detail on fail:** `"3 assertion-free test files: tests/auth.test.ts (only contains describe/it blocks with empty bodies), src/lib/__tests__/utils.test.ts (calls helper functions but no expect calls)"`
- **Remediation:** A test file with zero assertions tests nothing — it just exercises the code path and counts as a "passing test" without verifying anything. Add real assertions:

  ```ts
  // Bad: no assertion, this passes even when the function is broken
  it('creates a user', async () => {
    const user = await createUser({ email: 'test@example.com' })
  })

  // Good: actually verifies the result
  it('creates a user', async () => {
    const user = await createUser({ email: 'test@example.com' })
    expect(user.id).toBeDefined()
    expect(user.email).toBe('test@example.com')
    expect(user.createdAt).toBeInstanceOf(Date)
  })
  ```

## External references

- iso-25010 maintainability.testability

Taxons: code-quality

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