Cedric’s having another go at JUnit Again he misses the point: extensions to JUnit are not JUnit itself, and JUnit can’t be blamed for people extending it to the wrong way.
His current complaint is about how certain extensions to JUnit override setUp(), forcing you to call super.setUp() in your own testcases. This is certainly a problem; but it’s not JUnit’s problem. The problem is how the extensions have implemented themselves.
Essentially, they’ve been lazy: they’ve supplied implementations of setUp() and tearDown(), and decreed that all users of the extension need to make sure they are call. This is wrong!
What the extension developers should have overridden was the runBare() method or the runTest() method. They could then have put in their own setup/teardown code without impacting the client. Here’s an example:
/** Override runBare to call mySetup() first, myTearDown() last */ public void runBare() throws Throwable { try { mySetup(); super.runBare(); } finally { myTearDown(); } }
This calls the extension’s setup and teardown methods before doing the ones for the test case; overriding runTest()
in a similar manner will result in the extension methods being called after the test case’s setup.
Cedric is “actually shocked that JUnit forces you to use this anti-pattern”. Well, Cedric, it doesn’t. It’s the developers of JUnit extensions who do this, not the JUnit guys themselves.
Look, folks, here’s the right way to make a JUnit extension.
- Create an instance of TestDecorator (or the subclass, TestSetup Put functionality in here so someone can use your extension without changing their inheritance hierarchy.
- Then, after doing that, create a subclass of TestCase which delegates down to the decorator as needed. Use the above mechanism to avoid putting additional constraints on client subclasses.
This isn’t rocket science, people.
I have noticed several cases of people paying out on junit in appropriately – I wonder if it is connected to the push towards other frameworks like TestNG (too much conspiracy theory ?).
Some people have said that junit is “old” as any development/contributions have stopped – but isn’t that just a sign of maturity in a tool that is used pretty much everywhere? (and nicely integrated to every java IDE).
IMHO, it’s a combination of annoyance and ignorance. People are rightfully annoyed that some popular JUnit extensions are awkward to use (I know StrutsTestCase fits in here, for example). They assume that’s because of JUnit.
They also assume that some _convenience_ features (such as the testXYZ convention) are actually constraints, when they aren’t. See my earlier post of JUnit’s architecture for more.
I totally agree Robert and have been grumbling about this for while – I don’t see what’s so bad about JUnit that you need to go write another framework. It’s actually a pretty simple (as in small) API – there’s not much to it!! It’s ideal for writing *unit* tests (to me, using the extensions takes you out of purist Unit testing and into integration / acceptance testing – but the extensions are very useful). Forget jumping on the next bandwagon – just because something’s been around for a while doesn’t mean it’s out of date. Ok, if you WANT to write a new framework fine, but don’t try to promote it by putting down the existing framework – it gives ignorant people the wrong idea 😉
One of the nice things about JUnit is that it effectively resets everything with each test method invokation (calling setUp and tearDown and so on).
This means that each test method is like a test on its own, and the TestCase class is just a logical collection of related tests. It is a bit wierd at first, but it actually makes things much simpler.
NUnit doesn’t seem to work that way, and is confusing me because of it.
JUnit makes one instance of the test case class per instance; this means that tearDown, in particular, is more about resource management than test isolation.
NUnit (and TestNG) uses one instance of the test case class only. Isolation needs to be enforced by the tearDown()/setUp() (resetting variables, etc). Apparently, the main designer of NUnit now has had second thoughts about this difference (which is quite intentional).
I tried to think up an anagram(?) for TestNG that said that it was “just another need for an xml file to write/maintain”, but couldn’t do it.
Shame.