How Antithesis Works
Developers need something better. Testing has barely benefited from the cheap compute that Moore’s law enabled, as it relies instead on engineering labor. Engineers spend their time writing an extensive test suite. Engineers spend their time trying to recreate flaky bugs. Engineers spend their time trying to bisect an identified bug. And even with all that, bugs slip through at every stage of development.
Of course, this wastes a lot of time. But much worse than that: it makes shipping new features a potential disaster to fear, rather than an opportunity to pursue. It forces developers to spend time testing and debugging rather than doing the development that they – and your customers – find rewarding.
Antithesis believes that testing is ripe for radical improvement, so that you can develop boldly.
What is Antithesis
Antithesis is a platform for radically improved testing – autonomous testing. But how does it work?
Software testing (with any platform) requires three things:
- check the correctness of your system,
- do that under a wide variety of conditions,
- and be able to reproduce the results of any issues that are found.
The Antithesis platform offers three features to meet these requirements:
- it uses test properties for identifying bugs,
- and intelligently explores your software,
- all within a (3) deterministic simulation of your system.
While each individual feature is valuable, the radical improvement to testing comes from the combination of all three. We call it autonomous testing: which means Antithesis automatically generates your test cases, unlike automated testing, which only automates running them.
What does it take to achieve autonomous testing? The number of possible states of your software is incomprehensibly large – you need intelligent exploration in order to make exploration tractable. You can generate many possible universes, but how do you know if you have found bugs? You need test properties in order to know if a given universe has identified a bug. And what good is it to find bugs if you cannot recreate them afterwards? You need determinism in order for identification of bugs to have any value.
Antithesis believes that these three features are more than just individual good ideas. They are the building blocks of autonomous testing.
Test properties
Antithesis provides a powerful implementation of property-based testing. Instead of writing a vast test harness to ensure the correctness of your software, you simply assert your system’s desired functionality via test properties.
Did you struggle with fixing a tricky memory leak? You might assert that your program never runs out of memory. This property would catch that memory leak in the event of a regression. But it would also catch any memory leak, so this property replaces all your tests about memory leaks. Test properties allow you to replace an elaborate test harness with a few dozen, well-chosen properties. Antithesis cuts down on writing tests, so you can get back to development.
Intelligent exploration
When testing, Antithesis intelligently explores your software. It searches for bugs by generating a multiverse of states in your software’s execution history. In each universe, it checks to see if your system’s properties have been violated.
Antithesis generates universes by feeding inputs to your system (similar to fuzzing) and also by injecting simulated faults, such as network outages. With this fault injection, every test you run can test your code far off the happy-path. Does your new function have subtle, incorrect behavior after post-crash recoveries, during leader elections, or after a rollback? Antithesis tells you immediately, so you can get back to development.
Determinism
Antithesis simulates every aspect of your system, both the software and the hardware it runs on. This hardware simulation allows Antithesis to test everything from APIs to complex distributed systems. Antithesis can simulate multinode distributed systems while having total control over the behavior of the clients, the server, and the network itself. This allows Antithesis to painlessly surface bugs related to concurrency, race conditions, leader elections, rollbacks – and every other word you hate to see on a ticket.
Have you ever been frustrated with wasting time trying to reproduce a flaky bug? Antithesis is deterministic, so the same series of inputs always gives the same output. For a given software build, applying the same set of inputs always surfaces exactly the same bug – even for complicated concurrency bugs. Antithesis ensures that all bugs are always perfectly reproducible, so you can get back to development.