I agree 100%, and I would encourage you to follow that approach.
Why don’t we use tests in Julia to define contracts?
There’s nothing stopping you
.
I use this approach myself in the QuantumControl packages via “interfaces”.
One aspect is to not run them as “tests”, but automatically on the arguments of certain high-level functions, unless check=false. This works in my case because optimize often runs for seconds, if not hours. You wouldn’t want to run interface checks every time inside performance-critical tight loops.
And that’s really the caveat with the approach: it works at runtime. If there was more Julia could do at compile time to verify formal interfaces, that would be a performance improvement.
The second aspect is that if as a user of QuantumControl I want to implement my own type that can serve as a “generator” of the dynamics (which the framework encourages), I can call check_generator to verify that everything is defined correctly to meet the expectations of the QuantumControl.propagate and QuantumControl.optimize functions.
I absolutely believe we should do more of that. If there’s some interface like, let’s say AbstractArray, there should be a pre-defined test suite that I can run my custom array-like type through to verify that it fulfills the interface.