Now four.
(Generously assuming you respect my opinion of course.
)
I use the assert :ok == a_prerequisite_function(...) thing religiously. Anything that requires something else besides what you included in setup_all and setup should also be tested. Every step should be assured to succeed or yell loudly if it doesn’t.
Example #1
I was writing a function that inserted several records in the DB and they had to be inter-connected in a specific manner and had to have X amount of fields filled with certain values. Absolutely every single detail of those expectations is tested. A week later I forgot to enforce one of these data connections (in a second function that was 80% identical to the first one) and the test blew up 2 minutes later. Fixed the problem on the spot, before a commit even.
A project growing and growing can invalidate even the most basic of assumptions – seen it happen many times.
Example #2
People have called me crazy and told me I am wasting time for making sure that the Repo.insert result indeed puts the right column values in the DB – but they forgot that their changeset function (the one that’s called before the insert) was actually modifying the data that was given to it and they assumed the values would be inserted as-is which they of course were not.
It can happen to each and every one of us. The tests were there to slap my colleagues and say “hey doofus, you thought you had value X but actually you have Y, go check why”.
My weekends have been saved no less than 50 times in my career by having semi-paranoid tests.
Example #3
Make sure that when inserting, if you omit a required field you’ll get an error in your changeset. Sure enough, just some days later I added a new field to an Ecto.Schema and forgot to put its name in the required fields list. Running tests, boom! The changeset complains “field X can’t be null”. Went into the schema module file and added the field, everything is green.
Is that a minor gripe? Maybe. But we should not forget that code is secondary. Data rules everything. Data must be consistent. Data’s invariants must be always held. The code is servant of the data.
This does not contradict what me and others have said. Personally I’d prefer to be informed if an assumption about the pre-conditions of the code that I am testing are broken.


















