I heard someone say that unit tests (e.g. nUnit, jUnit, xUnit) should be
(E.g. unit tests should contain "damp code" not "dry code")
What are they talking about?
I heard someone say that unit tests (e.g. nUnit, jUnit, xUnit) should be
(E.g. unit tests should contain "damp code" not "dry code")
What are they talking about?
DAMP and DRY are not contradictory, rather they balance two different aspects of a code's maintainability. Maintainable code (code that is easy to change) is the ultimate goal here.
To maintain code, you first need to understand the code. To understand it, you have to read it. Consider for a moment how much time you spend reading code. It's a lot. DAMP increases maintainability by reducing the time necessary to read and understand the code.
Removing duplication ensures that every concept in the system has a single authoritative representation in the code. A change to a single business concept results in a single change to the code. DRY increases maintainability by isolating change (risk) to only those parts of the system that must change.
Tests often contain inherent duplication because they are testing the same thing over and over again, only with slightly different input values or setup code. However, unlike production code, this duplication is usually isolated only to the scenarios within a single test fixture/file. Because of this, the duplication is minimal and obvious, which means it poses less risk to the project than other types of duplication.
Furthermore, removing this kind of duplication reduces the readability of the tests. The details that were previously duplicated in each test are now hidden away in some new method or class. To get the full picture of the test, you now have to mentally put all these pieces back together.
Therefore, since test code duplication often carries less risk, and promotes readability, its easy to see how it is considered acceptable.
As a principle, favor DRY in production code, favor DAMP in test code. While both are equally important, with a little wisdom you can tip the balance in your favor.
DAMP - Descriptive And Meaningful Phrases.
"DAMP not DRY" values readability over code re-use. The idea of DAMP not DRY in test cases is that tests should be easy to understand, even if that means test cases sometimes have repeated code.
See also Is duplicated code more tolerable in unit tests? for some discussion on the merits of this viewpoint.
It may have been coined by Jay Fields, in relation to Domain Specific Languages.
"DRY" is "Don't repeat yourself"
This is a term which is used to tell people to write code that is reusable, so that you don't end up writing similar code over and over again.
"DAMP" is "Descriptive And Meaningful Phrases".
This term is intended to tell you to write code which can easily be understood by someone who is looking at it. If you are following this principle, you will have long and descriptive variable and function names, etc.
Damp = 'Descriptive And Meaningful Phrases' - your unit tests should be able to be 'read':
From the article:
DAMP stands for “descriptive and meaningful phrases” and is the opposite of DRY, not in the sense that it says “everything should look like a trash heap and be impossible to read”, in that readability is more important than avoiding redundant code.
What does this mean and where to use it?
DAMP mostly applies when writing test code. Test code should be very easy to understand to the point that some redundancy is acceptable.
There are several answers here already, but I wanted to add another as I didn't think they necessarily explained it as well as they could.
The idea of DRY (Don't repeat yourself) is that in your application code you want to avoid redundant or reptetive code. If you've got something that your code needs to do multiple times you should have a function or class for it, rather than repeating similar code in several places.
This is a fairly well known programming concept.
DAMP (Descriptive and Meaninful Phrases) is for your unit tests. The idea here is that your unit test method names should be long and descriptive -- effectively short sentences that describe what you're testing.
eg: testWhenIAddOneAndOneIShouldGetTwo() { .... }
When you read a DAMP method name like this, you should understand exactly what the test writer was trying to acheive, without even having to read the test code (although the test code can also follow this concept as well of course with wordy variable names, etc).
This is possible because a unit test method has very specific input and expected output, so the DAMP principle works well for them. Methods in your main application code are unlikely to be specific enough to warrant names like this, especially if you've written it with the DRY principle in mind.
DAMP and DRY do not contradict each other -- they cover different aspects of how your code is written -- but nonetheless they aren't typically used together because methods written with the DRY principle in mind would be general-purpose and unlikely to be suited to highly specific method name. In general therefore, as explained above, your application code should be DRY and your unit test code DAMP.
I hope that helps explain it a bit better.
DAMP stands for “descriptive and meaningful phrases” and is the opposite of DRY, not in the sense that it says “everything should look like a trash heap and be impossible to read”, in that readability is more important than avoiding redundant code.
I agree with Chris Edwards in that you need to strike a balance between the two. Another thing to note is that if, in an attempt to remove duplication, you end up adding a lot of additional structure in your unit test code (i.e. when taking DRY to extremes), you run the risk of introducing bugs in there. In such a situation, you would either have to unit test your unit tests or leave bits of structure untested.
I don't wish to duplicate the effort here, but you can have tests that are DAMP but have the benefit of DRY. On the flip side, DRY tests won't satisfy DAMP tests in some cases.
I've blogged about DRY vs DAMP which includes some examples.
Neither approach should be your only solution, sometimes DAMP is overkill, other times a very nice addition.
As a general rule you should apply the rule of three. If you spot duplication a third time, it may be worth looking into writing DAMP style tests, but even then not all duplication is bad. Context matters.
A colleague and I defined DAMP as Descriptive And Minimally Pasted. Production code should be DRY, but test code should be DAMP. Expressiveness in test code should trump duplication, but you should still strive for minimal duplication.
Jay Fields mentions Descriptive And Maintainable Procedures in his book Working Effectively with Unit Tests.
© 2022 - 2024 — McMap. All rights reserved.