How Antithesis works
What’s software testing really about?
A piece of stateful software is essentially a giant state machine, and every such state machine contains some rare states that we don’t want to happen — commonly known as bugs.
If you think about it this way, it becomes clear that software testing is about exploring a very large state space.
An integration test threads a single path through this immense space. You can see that there are no adverse states (bugs) along that one path, but until you explore the state space fully, you don’t know what else is out there.
How does Antithesis test software?
Running in Antithesis is like an extreme version of chaos engineering, where everything is running in our fault-filled environment — not just your software, but your dependencies, your client, and your checkers as well. We throw random inputs at it (as though we’re fuzzing), while filling the environment with a wide range of faults, like network partitions or node kills.
The goal of this process is to expose as many different states as possible, including the rare, unanticipated, “I-didn’t-even-know-it-could-do-that” states where bugs lurk.
To accelerate the process, we don’t just throw random inputs and faults at the system — we have an intelligent guidance component (it uses RL, but you can tell your boss it’s AI) that drives the platform to seek out new and interesting states.
The Antithesis multiverse
As your software runs, Antithesis analyzes every event that happens in the environment: every transaction the software commits, every fault Antithesis injects, etc. Each event potentially starts a new timeline. In one universe, the network partitioned at time=t, and in many others, it didn’t.
Over the course of a single test run, the fault injection and input randomization create an immense tree of branching timelines. You can think of these as tens (or hundreds) of thousands of alternate universes. Below is a view of an actual Antithesis test run — a vastly zoomed out version of the diagram above.
We refer to the collection of timelines produced in a single Antithesis test run, the entire tree in the diagram above, as that test run’s multiverse — a giant collection of paths through your system’s state space.
How does Antithesis identify bugs?
Antithesis does a form of property-based testing. You directly state how your system should ought to behave (e.g. “this application should always recover after a single node dies”), and Antithesis scans the multiverse to see if it ever deviates from those promises.
Even if you’ve never heard of property-based testing before, you’re already thinking about system properties without realizing it — you know, for instance, that your database should always return the last write. Antithesis just gets you to express these implicit assumptions explicitly, by writing assertions in your test harness.
If there’s a bug in your software, then in a single Antithesis test run — a single multiverse — Antithesis will often find many timelines where the bug triggered, and many timelines when it didn’t.
How does Antithesis help fix bugs?
The Antithesis environment is fully deterministic. This makes every bug we find perfectly reproducible, so you’ll never waste time trying to reproduce a flaky bug again.
Determinism enables us to provide detailed artifacts and powerful, one-of-a-kind debugging tools.
What next?
Ready to get started? Contact us to request a container registry and credentials. Once you have those, you can dive right in.