# Test (/academy/test)



A test is a script that refuses to let last night's [bug](/academy/bug) happen twice.

You do not re-click the whole app by hand after every change. You write a small program whose only [job](/academy/job) is to run another piece of code and confirm it did the right thing. Give it this input. Expect that output. Green means it still does. Red means you just broke it — including future you, including the [agent](/academy/agent) that "refactored" at 3 a.m.

A **unit test** pokes one function. An integration test pokes a few pieces wired together. Neither is a judge clicking through the demo. That's a different, slower check. Start with the one path that already bit you.

**Why this matters when AI writes the code**

An agent can produce a lot of code fast. It can break a room three files away just as fast. Tests are how you keep it honest. The agent makes a change, you — or [CI](/academy/ci-cd) — run the suite, and if it snapped something you cover, you find out before you [deploy](/academy/deploy). An [eval](/academy/eval) is a test for prompts. A [type](/academy/type-error) check is a test the compiler already wrote. Pair them.

Green does not mean nothing is broken. Green means the things you pointed at still work. That's why a real net is a lot of good tests, not one that asserts `true`.

The [CLI](/academy/cli) already has the verb: `bun test`. The [builder](/builder) can scaffold a project that knows it. CI is the teammate who runs it on every [pull request](/academy/pull-request) so tired you cannot skip it.

At a hackathon, write the tripwire for the one query the demo dies without. Don't write a framework. If the agent lies, the tripwire screams before the judge does.

**What this unlocks**

Changing code stops being a held breath. You make the edit, you run the suite, and "I think it works" becomes "I checked the parts I care about." Agents stay fast without flying blind. The bug that bit you once has a name and a red light, and it does not get to bite the judge.
