I've just found interesting post Test Driven Code Review. Its title and the 2nd sentence caught my attention:
When reviewing or just reading such code, it's often best to first read the tests.That is something I started to use some time ago and I had very good experience with it many times. But not always. As Philip Zembrod writes further he had similar experience and coined terms well-specifying tests and poorly-specifying tests. I like them. What could be the better place to understand code you've just got to review without deep understanding of requirements and domain it touches? Well, I agree with the author it should be tests. But they have to be clean, easy to read and simple. After being guilty myself in writing obscure tests in the past, I try to make them as easy and concise as possible for last couple of years. I think my turning point was when I (gradually with time) created a unit test using 13 mocks. Every time some of test (usually more at once) failed I had to go to deep analysis whether I really introduced bug or I just need to tweak one of those inconvenient mocks, because requirements changed.
I have learned a lot from that experience
- Limited responsibility of class will ask for less mocks. It is always possible to rearrange responsibilities in some way to allow simpler testing (and understanding both production and test code).
- Test should explain main points, hiding irrelevant details (like creation of data it needs, but they are not the reason for existence of this test; hiding details of how mocking library works while saying what you want to achieve).
- Test should be concise, only couple of lines all focused to tell you a story. What environment you have, what you do with tested class and what effects you should see as the result.
But not everybody does
Sad part is I always find hard to read tests that are completely obscuring the main point. Apart from plenty of "easy" to fix tests I have seen also couple of ugly ones. The worst was 3500 lines long test with 32 mocks! It was worse than really thick book with unappealing name. I've never bothered to look at production code. (Fortunately I did not need to). OK, there is even sadder part: I am afraid the author(s) will never learn anything from this test experience. Maybe only one incorrect thing - unit testing is meant to be hard :-)Back to reviews
I usually try to spread good ideas and I've found the code reviews are pretty good medium for suggesting simple improvements in tests without being caught as mentoring. Many times I found developers are too proud to accept explicit help, which is pity in my opinion. Disadvantage of this approach is high probability helped person will miss the bigger picture. But that might come later.About 2 weeks ago I had discussion with a few colleagues of mine. I have asked them what they think about following Javadoc and how to enhance it.
class Person { // definition of attributes, I am not stating them to // avoid attracting your attention now /** * Gets value of the first name property. * @return first name of person */ public String getFirstName() { return m_FirstName; } }I have provided additional constraints:
- the class is as-is, we do not care about e.g. persistence (to avoid temptation to define maximum size).
- we do not care about constructor (or setter) and what constraints it brings.
- only this getter for Java Bean interests us here as my idea is to represent any simple method in general.
- do not speculate what else could be done in this method, just provide useful Javadoc.
- I have selected Person and first name as widely understood concept to make it harder to provide useful Javadoc (in order to shed more light into this apparently confusing concept ;-) )
- "Maybe format could be described" (there is none in my example).
- "In case of future enhancements (e.g. encryption) it is better to have Javadoc present since beginning, because some developers will not add one when they are modifying it" (I have simplified this suggestion to make it shorter. Well, I am not sure if a group of developers who would not modify existing Javadoc is not bigger...)
Comments are always failures. We must have them because we cannot always figure out how to express ourselves without them, but their use is not a cause for celebration.I am not as strict about this (I am probably not able to express all my ideas cleanly often), but in general I agree that strict asking for Javadoc is healing symptoms instead of real root cause in typical code. Are you not persuaded yet? Well, what do you think about following example describing common usage of Logger?
/** Logger */ private static final Logger LOG = Logger.getLogger(Person.class);While it is probable that there is only one
Person.getFirstName()
in codebase and it deserves some kind of documentation, what should I think about comment describing well known way how logger is used in about 2000 classes I have seen in our project till now?
Conclusion
I wanted to make title of this post attractive... I generally consider Javadoc to be useful. But I wanted to point out that sometimes there are valid reasons to skip it. Unfortunately Checkstyle is not able to identify these situations while people are.I mentioned readable tests yesterday and I have found following text in book Clean Code today.
What makes a clean test? Three things. Readability, readability, and readability. Readability is perhaps even more important in unit tests than it is in production code. What makes tests readable? The same thing that makes all code readable: clarity, simplicity, and density of expression. In a test you want to say a lot with as few expressions as possible.It is nice to find confirmation of my beliefs in the book I like a lot. Thinking about it I am not sure how I acquired this knowledge. Whether it was from some book or article or I just realized it after seeing a lot of bad tests (and writing them too). Indeed, it happened many times that I found much easier to understand production code and then I was not able to decipher tests to see how to modify them (or how to add new test). Or to find why test is failing. Many times it seems that people care much less about the tests. It would be interesting to know whether they do not care or do not believe they are worth of effort or they just do not know how to do them better. I suspect the last possibility is culprit most of the times. Fortunately this is the easiest to fix. It just needs learning...
My colleague wanted to add comment to recent post, asking how it is possible to achieve good quality of code. Somehow it did not work as he did not see captcha code. Anyway, I owe him an answer (I hope it was not rhetorical question).