Re: Redesigning Hamcrest
Just in case you do not know: Hamcrest is a library to compare expected and actual values and provides nice descriptions if the comparison fails. While it was originally written in Java offsprings exist in PHP, Objective-C, Python and Ruby.
JUnit relies heavily on Hamcrest meanwhile not only in simple assertions (assertThat) but also in JUnit Rules like the ErrorCollector which collects validation results and makes the test fail if one of them failed.
Our framework for UI-Tests (for our rich web application) also relies heavily on Hamcrest. We have combined it with our Wait-Pattern to wait for a certain state of the UI to reach as described for example in my blog post Death to sleeps! Raise of Conditions!
Having it integrated so deeply we also realized some of the shortcomings Jacob mentioned:
- We also only relied on the TypeSafeMatcher, so the Matcher interface itself is obsolete.
- While not yet using Java 8 for development we also made the experience of the clash of Predicates and Matchers. For now we use the Predicates provided by Guava. And to combine both worlds we don’t have an extra LambdaAssert class as Jacob but a PredicateMatcher which wraps a predicate and makes it a matcher.
And one additional flaw we found: Matchers do not remember their state. While I would not recommend to change Matchers to remember the state, users of Matchers (like JUnit) make a wrong assumption when building the failure description: They assume that the object under test did not change between validation and error report. But as soon as it comes to integration tests (and especially UI-tests) it is very likely that your objects changed from comparison until the error report is generated (for example the UI-element which was missing when the check is performed suddenly occurred while the error description is built). Therefore we keep the state in our Conditions (part of the Wait-Pattern, not to be mixed with Hamcrest’s Conditions).
All in all we love Hamcrest – but a redesign makes sense especially with the raise of Java 8’s Lambdas.