In fuzzing, Foundry randomly generates input data based on the constraits you set and feeds them into a function.
In invariant testing, Foundry calls a sequence of functions in random order and checks if an "invariant" is always satisfied.
What is an "invariant"?
Invariants are conditions expressions that should always hold true over the course of a fuzzing campaign. A good invariant testing suite should have as many invariants as possible, and can have different testing suites for different protocol states.
Writing an invariant test
To transform a regular test case to invariant test, we must name it with the prefix "invariant". For example:
functioninvariant_flag_is_always_false() public {assertEq(target.flag(),false); }
Foundry is smart enough to call func_1() through func_5() in random sequences with 20% probability for each function. Eventually it is going to hit func_5() so the invariant fails.