Not the writer, but it seems obvious to me. It’s a luxury version of assert. You leave them enabled in debug builds to get better bug reports from testers.
Those testers may hit cases you forgot to write unit tests for.
Of course, you can also forget to write invariants, or write invariants that are less tight than they should be, but I think it often is easier to write invariants than to write exhaustive unit tests.
Firstly, writing “p should always be a prime” is clearer than writing “if p is a prime, and you call f, p should be a prime afterwards”, and secondly, invariants can apply to multiple methods that you, otherwise, would have to write separate tests for (“foo keeps p a prime”, “bar keeps p a prime”, “bar keeps p a prime when called with a null argument”, “baz keeps p a prime if it throws an exception”, etc)
Also, invariants, IMO, can be way better documentation than unit tests.
Finally, invariants leave open the possibility of using a theorem prover to (dis)prove that they hold.
Those testers may hit cases you forgot to write unit tests for.
Of course, you can also forget to write invariants, or write invariants that are less tight than they should be, but I think it often is easier to write invariants than to write exhaustive unit tests.
Firstly, writing “p should always be a prime” is clearer than writing “if p is a prime, and you call f, p should be a prime afterwards”, and secondly, invariants can apply to multiple methods that you, otherwise, would have to write separate tests for (“foo keeps p a prime”, “bar keeps p a prime”, “bar keeps p a prime when called with a null argument”, “baz keeps p a prime if it throws an exception”, etc)
Also, invariants, IMO, can be way better documentation than unit tests.
Finally, invariants leave open the possibility of using a theorem prover to (dis)prove that they hold.