I recently found out you refactored all the unit tests. Seems like they are already structured according to certain "groups of checks". Looks very good, yet I immediately had the idea we might be able to reduce test code a lot. Here's my story...
A week ago or so, my colleagues and me were so lucky to view a presentation by J. B. Reinsberger (author of "JUnit Receipes") about testing http://www.infoq.com/presentations/integration-tests-scam. He advocated a testing style comprised of interaction tests and contract tests. Whenever two objects interact, put in interfaces between them, test each object in isolation with the other object(s) replaced by test doubles. I'll skip interaction tests. The second half of the testing strategy is what he calls "contract tests". They essentially make sure that each and every implementation in my system which claims to implement an interface actually obeys its contract..
I recognized there are probably similar patterns in FEST-Assert. In other words: I believe there are groups of assertion classes, which implement a number of interfaces, with the interfaces defining a contract.
"ComparableAssert" is, in my eyes, one of these contracts. It might also be termed an "abstract contract", or in Java terms "generic contract", because it can be applied to a number of concrete types, which of course must be comparable. I'm quite sure we can identify most of the assertions we currently support belong to a contract of some form. More examples could be: NullableAssert (isNull, isNotNull), GroupAssert (hasSize, isEmpty, isNotEmpty), ...
Last weekend, I drafted some experimental code which is intended to support systematic contract testing. It basically ensures that, whenever you define an interface (and annotate it as @Contract), all the implementors of this contract are tested to comply to the contract. This is done by creating a number of tests on dynamically (for TestNG at the moment, since we use TestNG at work), but I think it can easily be ported to JUnit; probably by defining a custom TestSuite). It aims at defining the test code once per abstract contract, and provide the relevant test data on a per-concrete-contract-basis. I. e. imagine:
interface ComparableAssert<T> as the abstract contract, and BigDecimalAssert implements ComparableAssert<BigDecimal> as an implementor of a concrete contract derived from ComparableAssert. In this setting, you'd define one (generic) test to check that each implementor obeys to ComparableAssert, and one test data factory for each concrete contract (e. g. ComparableAssert<BigDecimal>).
I'm planning to make this testing aid a github project once it's at least a bit useful. I'm not sure it works out for generic contracts, so no jumping for joy yet. What do you think?