Why We Refactored JUnit 192
Bill Venners writes "In this article, three programmers tell the story of how their frustration with JUnit's API led to the creation of Artima SuiteRunner, a free, open source test toolkit and JUnit runner. These programmers simply wanted to create a small add-on tool to JUnit, but found JUnit's design non-intuitive and API documention poor. After spending time reading through JUnit's source code and attempting to guess at the API contracts, they gave up and rewrote it."
Re:The truth about XP (Score:5, Insightful)
"at one point I just threw up my hands and said to myself, "Why is this so hard? It would be easier to rewrite JUnit than figure it out."
Just some friendly advice: if you ever find yourself saying it would be easier to rewrite something rather than figure it out, slap yourself. Chances are you are wrong. I certainly was. Creating SuiteRunner was a huge amount of work. Despite my frustrations with JUnit, it would have been orders of magnitude easier to decipher JUnit's source code than to create a brand new testing toolkit."
Intuitive (Score:5, Insightful)
Recursion is intuitive but not necessarily efficient in terms of performance.
At what point do we decide which is better intuitive design or efficient design.
Re:Origins of XP (Score:5, Insightful)
Re:Intuitive (Score:3, Insightful)
The author of this article is talking about the JUnit API. An intuitive API is always a good thing.
Re:refactor == rewrite? (Score:3, Insightful)
Re:The truth about XP (Score:5, Insightful)
If you're a programmer, that's the wrong book to start with. Read Extreme Programming Installed [amazon.com], by Jeffries, et al.
I'm starting to think that XP really is just one big hot air balloon.
In my experience, it's not. Since adopting it a couple years back, my designs are better, my bug counts are much lower, and I am much happier. Feel free to drop me a line if you have questions.
Paradigm shift? (Score:5, Insightful)
While I can understand what they wanted to do, I guess I don't see why they didn't do this the much easier and (to me, anyway) more obvious way: you write code that uses the API, and if it compiles, then the API is implemented. You write one tiny test class for each API. You have each JUnit test run a compiler over one single class, this proofing each API. This isn't exactly rocket science: you have a directory full of probe-class source code, a single method that tries the compile, and then any number of TestCases that each try to compile one class and pass if they succeed. This is hard?
If you use the unpublished APIs to "javac," you could do this at lightning speed. Alternatively, you could just use a Java parser like the one that comes with ANTLR (since you don't actually need to generate any code) and do it even faster.
This is what I like about Open Source Software (Score:4, Insightful)
Re:Intuitive (Score:3, Insightful)
For that matter, how fast do you want the testing infrastructure to run?
Re:Intuitive (Score:5, Insightful)
Re:The truth about XP (Score:5, Insightful)
Sometimes, it really is easier to treat the first one as a prototype of what you'd really like, and then write that second one correctly, from scratch. Witness Mac Classic -> Mac OSX, Win9x -> WinNT, Perl5 -> Perl6, etc.
A lot of these prominent "next-generation" systems may share ideas & even code from their predecessors, but the essential point with each is that they all represent deliberate jump-cuts from the past. Sometimes it really is easier and better to rewrite something, whether or not you fully grok the original.
The real trick is to design systems well enough that, when someone comes along with better ideas, the framework you provide is robust enough to adapt. Mac Classic, Win9x/DOS, and Perl5 are all too inflexible for future use, though at this point each of them is still useful to certain groups. Their successors, however, are all designed with future expandability in mind, so that the "second system curse" can hopefully be avoided. History will tell if it ended up working in any of these cases...
if it ain't broke.... (Score:2, Insightful)
Re:The truth about XP (Score:5, Insightful)
Design first, or refactor? Re:Origins of XP (Score:5, Insightful)
I believe that this quote is true for commercial software. The word processors, email clients and web browsers in the world should not be designed at the beginning of a project. The cost of doing that far outweighs the benifits. But...
When you are designing life critical applications (fly-by-wire, ABS, pacemaker, cancer radiation machine...etc) it is not acceptable to be redesigning while coding.
If you cannot model the way a system must react at all times, under any input, then what makes you think that your software should be responsible for someones life.
More and more software is being designed for life critical applications. If XP is being used to develop them, I'm worried. You cannot stumble onto 100% correct software. In a large system it takes a lot of money - an exponential curve, the last 3 bugs will likely take more money than the first 100 - time and a good design.
Re:Paradigm shift? (Score:5, Insightful)
Can you write a test-compile program that checks whether the proper public/private/proctected access modifier keywords are set up right on each method? That the method was specified for 'short foo' but the implementor used 'int foo'? Or like Mithrandir said, that no additional methods have been added (such as an overloaded version)?
Basically, compile-compatability is not the same as using the precise APIs in the spec.
Re:genericity in testing (Score:5, Insightful)
Ah, you do not understand the zen of XP yet. First you write the test. Then you write the code. Then you correct the code so the test passes. The sun is warm; the grass is green.
Re:genericity in testing (Score:1, Insightful)
But you, poor Grasshopper, do not truely understand Zen.
Re:The truth about XP (Score:3, Insightful)
You don't learn as much from reading someone else's code as they did from writing it. Don't try mis-quote Brooks to justify not understanding an existing product. Brooks was referring to large-scale team oriented development (like the System 360, or IBM 650 probjects). He wasn't claiming that you should throw out someone else's code because it was the first solution to a problem.
Re:I tried too.. (Score:4, Insightful)
Open source software don't come up often with design documents. This one does. To those who say JUnit is hard to understand, go and read the Cook's tour [sourceforge.net]. Then you'll understand everything. Things have changed a little bit but not that much. Of course if you are not familiar with Design Patterns, I recommend to read Design Patterns [hillside.net] first. Yes that's by Erich Gamma and co also called the Gang of 4 [c2.com]
I see allready people coming and say design pattern is crap, and that's a proof. But before coming in and complaining, remember the lessons learned by the people who have worked longer than us in this industry. KISS(Keep It Simple...) [techtarget.com] and don't reinvent the wheel: I am pretty sure that the elegant design used in JUnit could have been refactored quickly to do what those guys wanted without having to rewrite everything from scratch.
The author of this new test suite says it all:
Solid Foundation For Software Refactoring (Score:3, Insightful)
For those interested in the value of refactoring (whether it's merely a buzzword), I can refer to a research project of ours, at http://win-www.uia.ac.be/u/lore/refactoringProject [uia.ac.be]
By the way: since the article does not go into behaviour-preserving restructuring of JUnit, they shouldn't mention 'refactoring' in the title.
Re:Origins of XP (Score:5, Insightful)
Well, duh. If it is well written it won't have bugs, by definition. But how do you find out whether the code is well written, except by thoroughly testing it?
Re:genericity in testing (Score:3, Insightful)
You'd probably love XP then. A lot of the XP methodologies (with the possible exception of Pair Programming) make heaps of sense, and it's extremely nice to have them all in one tidy package that you can sell to management.