In doing some code reviews on an existing project, I discovered instances of an antipattern that I've never seen described before. I'll talk about it here, but if anybody knows a reference for a similar discussion, I'd love to know about it. Thanks.
To use the Java testing framework JUnit, you can simply extend the TestCase class and add no-argument methods named testXXX(). JUnit will find these methods using reflection and execute them.
It's fairly common to create subclasses of TestCase to contain project-specific fixtures and utilities. You can then extend your subclass, add test methods, and have convenient access to those utilities. This is a perfectly fine practice.
Somtimes, though, in the course of development, you might see an existing test case class (call it TestFoo) with some useful setup code and be tempted to extend that test case with a new test case TestBar. This is, as it turns out, a bad idea, because TestBar will contain not only the utilities you inherit from TestFoo and the test methods you add, but the test methods you inherit from TestFoo as well! If you run all the test classes in a project, you might not notice that the test methods in TestFoo are being executed twice. If this happens often, the runtime of your test suite might suffer! For some reason, this behavior of JUnit, while it sounds obvious now that I've said it, isn't necessarily intuitive to junior programmers.
It occurs to me that there's an easy way to prevent this from happening: make it a rule that concrete test case classes must be final. This would prevent you from extending the class, and remind you to factor out the common utilities into an abstract test base class. So my question is: can anyone think of a reason why this would not be a good practice? I'm going to try this out in real life and see what happens.