Automated testing became mainstream something like 5 years ago. Nowadays, in 2010, automated testing is somehow accepted by most serious developers.
Design by Contract exists for 2 decades, first supported by the Bertrand Meyer’s Eiffel language. Thanks to the recent Code Contract .NET v4 library, there is nowadays, some buzz about Designing by Contract in the .NET community.
My point is that one developer shouldn’t abide by one of these practices, without adhering to the other. Especially, if you already practice automated testing, you ethically cannot ignore Code Contracts. I have the chance to be relentlessly serious in practicing Code Contracts AND Automated Testing for 5 years now. My conclusion is that, in appearance different, Code Contracts and Automated Testing represent pretty much the same thing.
Code Contracts and Automated Testing share both the same primary goals:
- Check often for code behavior correctness
- Trigger obvious failure in case of broken correctness found
- Document code behavior
Assertions put inside the code through Code Contract are really the same thing than assertions put inside test code. This advocate for a central point: Code Contracts assertions should raise obvious failure when violated during the execution of some automated tests.
Often I hear or read that just few tests covering a large portion of the code is not a valuable thing, since few tests contain few assertions and thus, there is a high chance for a bug to remain undetected. In other words, some pretend that high test coverage ratio of the code is not so much valuable. But if the large portion of the code contains a well-written set of code contracts assertions, the situation is completely different. During the few tests execution, tons of assertions (mainly Code Contracts assertions) have been checked. In this condition, chances that a bug remains undetected are pretty low. Chances that a bug remains undetected are pretty close to 0 when the code is both 100% covered by tests and contains an optimal set of contract assertions.
More concisely Contracts are not a replacement for Tests and vice-versa: both should be
- Contracts need Automated Tests to be exercised often in a repeatable way.
- Automated Tests need Contracts as a much finer way to check code behavior correctness, inside the code itself.
Finally, some might discuss that unit tests are class oriented, that integration tests are modules oriented that Design by Contract is class collaboration oriented, bla bla bla. While I agree that there should be a clear frontier between the set of quick unit tests (ran in seconds), and the set of slow integration tests (ran in minutes) I am not so strict about the scope of tests and contracts. My mission as a developer is to write bug-less code in a competitive time. Relentlessly applying both automated tests and Design by Contract is so far, my best weapons to achieve this task.