Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

The dry principle states:

"Every piece of knowledge must have a single, unambiguous, authoritative representation within a system."

However when writing tests for code you are describing the expected behavior for the system twice (once in the code and once in the test). I know both descriptions are from a different perspective but share a great deal of the underlying idea.

Any thoughts on this?

In general I think both unit tests and the DRY principle are good ideas and I try to apply them as much a possible. This question is more on a philosophical level, but I wondered if anyone had also thought of this.

share|improve this question
2  
1. Code is not the expected behaviour, it is the actual behaviour. 2. Test does not belong to the system, so DRY still stands. –  mouviciel Oct 18 '11 at 12:12

4 Answers 4

up vote 9 down vote accepted

You are operating on a faulty premise.

The code is not a description of the expected behavior, only the requirements and test cases are. And even then, the requirements and tests define two sides of the behavior. The requirements define the characteristics and functionality of the software system as a whole and test defines what the expected results should be and is matched against requirements. The code is a developer's interpretation of those requirements and the architecture of the system.

share|improve this answer
    
I am thinking along the same lines, however one note of difference: the unit tests are also based on the developer's interpretation of the requirements and architecture, so there can be no misunderstanding on this level between unit tests and code (at least with greenfield TDD - legacy code is a different issue). It is the acceptance tests which are /should be based on the customer's definition of requirements. –  Péter Török Oct 18 '11 at 11:53
    
@PéterTörök For unit tests, it depends on who writes the tests. That's absolutely true if the same developer writes the tests and the code. If one developer writes the tests and one writes the code, then you have two developers' interpretations and can see problems sooner. As for different levels of testing, I'm using the term "test" to refer to unit, integration, system, and acceptance tests, each written by an appropriate person or group for the given purpose. If the wrong people write a test (a developer writing an acceptance test, for example), the test isn't that useful. –  Thomas Owens Oct 18 '11 at 12:01

No, it doesn't violate the DRY principle because unit tests don't reproduce the functionality, they only make sure the functionality (re: responsibility) operates properly. In the case of a unit test, the method you're testing still maintains authoritative representation. Your test code may look very similar to code that implements the method in the production version, but it has its own unambiguous purpose (to assert the test).

share|improve this answer

However when writing tests for code you are describing the expected behavior for the system twice (once in the code and once in the test).

Not quite. The code is not the description of the expected behaviour, but its implementation. Which can contain errors, that's why we need the tests.

Implementing even a fairly simple algorithm or abstraction is much trickier than describing it. Any decent programmer can describe in a few sentences how binary search works - still, Jon Bentley reported that in his experiments, over 70% of the experienced programmers participating in his course failed to implement it correctly.

This is why we need unit tests. Noone likes to work twice as much to achieve the same results, but all those developers who formulated and evangelised this practice realised from their own hard-earned experience that they need them. They were clever folks who wanted to develop software as fast as possible - which requires removing all duplicated and useless chores from the development process. Unit tests are not a duplicate job.

share|improve this answer

Kind of. If they're too similar, then yes, that's a bad thing. Your test shouldn't be coded the same way as the code it's testing. So you should be defining (1) an expectation and (2) an implementation.

I like to think that it's similar to double entry accounting. An accounting system always makes at least 2 entries (a debit and a credit). This is an error checking measure. At the end of the day, the debits and the credits have to balance, or else there was an error. You can't have an error detection system without some form of redundancy.

Consider a CRC for example. Your CRC byte is a form of redundancy. It's enough to detect any small error in the signal. Similarly, audio CD's have a lot of redundant information so they still play perfectly if they're scratched. Does that violate the DRY principle? Probably, but that's how you get reliability.

There's another way to look at it too:

Your test is the authoritative answer. The code it tests is just auto-generated by you, the code monkey. If we could do auto-generation of code based on unit tests (like we auto-generate data access layers based on a database schema) then we wouldn't be violating the DRY principle (or at least not the OAOO principle).

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.