I read a great blog article the other day by Matthew Podwysocki “.Net Code Contracts and TDD Are Complementary”. I also wrote an article on the subject a few weeks ago http://codecontracts.info/2010/01/02/test-driven-development-versus-design-by-contract/. Those articles describe different roles these techniques play in the development process and how they both contribute to better software quality. I won’t repeat the logical arguments made there. But I had an idea for a metaphor to help make these ideas memorable, communicating the synergy achieved by combining both of these techniques.
Computer software is like a person looking for a job. The job applicant has a resume which describes the goals, experience, and skills of the applicant. Here is an example of a resume
Looking for a job that involves physical activity and some interaction with computers
Carried boxes (5-15 lbs) to the loading dock
Completed inventory on a weekly basis
Can type 20 words a minute
Can lift boxes of 100 pounds safely
Certified to operate a Clarke model FL20 forklift
Computer software is written to meet goals that are expressed in high-level tests and comments.
In software, automated unit tests demonstrate what the code can do by illustrating what it has done (what has been tested). With code, as with job applicants, past results are indicative of future performance.
In software, code contracts precisely define what the code is capable of doing. Just as a knowledge of and applicants skills allow the employer to envision new and different ways they can serve the business, likewise, code contracts allow other programmers to envision new and different ways that the code could be combined to solve different problems.
However, one of the differences between software and a resume is the fact that we often highlight our strengths in resumes, without indicating our weaknesses or limitations. We usually wait for the interviewer to uncover our weaknesses and limitations. At least this is consistent with job hunting in American culture. In contrast, with software, we write code contracts to be fully revealing of the strengths and weaknesses of the code. As a job seeker, I may be eager to get a job offer, and sensitive about how I portray myself; I do have an ego after all. But a class has no need to buy food or clothing. And it has no insecurities about it capabilities. Nor does it write its own resume. I as a programmer write the code. I want to be brutally candid about what it can do and what it cannot do. And code contracts are an excellent way to express the possibilities and limitations of a class and its features.
In summary, I believe it automated testing and code contracts are complementary practices, and each contributes value towards the creation of reliable software. Automated unit tests demonstrate what the code has done and how it can be used similarly in the future. Automated integration and story tests give a better picture of the higher-level goals. And code contracts describe the inherent qualities of the code, including both what it can do and what it cannot do. The information offered by code contracts allows designers to make changes in the code more effectively because they have a deeper understanding of what the code is and is not intended to do.