Assertion library in Platform tests: Hamcrest or AssertJ? #177
Replies: 6 comments 10 replies
-
I personally think it is fine to have both used and think the effort to migrate to only one library is to high. My personal favourite is AssertJ for it's fluent API and IIRC Hamcrest is only very slowly released (this might have changed). |
Beta Was this translation helpful? Give feedback.
-
From releng POV - if one of them is already included in the dependency chain it should be preferred (this has been the case for hamcrest but not anymore with JUnit 5, although as JUnit 4 is here to stay hamcrest is technically a required dependency). This is just to give an extra view angle which is quite often not considered early enough and creates extra work in the long term to keep things working. "Less is more" (tm) |
Beta Was this translation helpful? Give feedback.
-
In general it should not matter (also from relng POV), but the eclipse test are a bit "special" and PDE support sometimes not very optimal so I think the best would be to try I already have opened this what most probably will require |
Beta Was this translation helpful? Give feedback.
-
I've been contributing to many projects in different areas (outside the Eclipse stack). And I would summarize it as:
The choice of AssertJ over hamcrest is quite simple: You don't have to learn anything. With hamcrest you have to know how to nest some matcher methods, which of them exist and how they are named. I can't remember that. With AssertJ, your IDE code completion will always tell you which exact assertions are available when you type
Also the API really takes the extra mile all the time. You will find assertThat(foo).isEmpty() implemented on any type that has a matching semantic, no matter whether the type itself has an actual "isEmpty()" method. Or if you are asserting numbers, you can of course write the typical assertThat(number).isEqualTo(0), but you can also shorten it to assertThat(number).isZero(). In the long run, your assertions become way shorter and more readable at the same time. For a migration, AssertJ provides some regular expression based conversion directly in the documentation. But I would rather suggest to use OpenRewrite, which is a "refactoring engine for anything". I've been contributing lots of fixes there over the last year, and I meanwhile use it in production for code migrations on "unknown" projects at work quite successfully. https://docs.openrewrite.org/recipes/java/testing/assertj/assertj is the composite refactoring recipe for converting from JUnit to AssertJ, which you can run from a maven command line without adding it to your POM. If you want to see how AssertJ tests look like and "feel", then start reading the documentation at this anchor: https://assertj.github.io/doc/#use-code-completion Google Trend agrees: https://trends.google.de/trends/explore?date=today%205-y&q=assertj,hamcrest |
Beta Was this translation helpful? Give feedback.
-
Thank you all for the great input! I found the arguments pro AssertJ convincing and gave it a try by changing the Hamcrest assertions in the Platform repository to AssertJ assertions. In many cases, they became much more comprehensible and it was easier to combine different kinds of assertions on the same object in comparison to Hamcrest. I also found that mixing up both libraries is not a good idea: I found broken assertions because both libraries were used in the same compilation unit and matchers are passed to AssertJ statements, which makes the assertion ineffective: eclipse-platform/eclipse.platform#1075 You can find the migration for the Platform repository I experimented with in eclipse-platform/eclipse.platform#1076. |
Beta Was this translation helpful? Give feedback.
-
Thank you all for your helpful responses! There were some very interesting arguments in particular concerning benefits of AssertJ and concerning the releng POV on the topic. Based on this discussion I've proceeded towards JUnit 5 migration using AssertJ, as I see clear benefits over Hamcrest and once JUnit 3/4 are not required anymore, the dependency to Hamcrest will not be necessary anymore. |
Beta Was this translation helpful? Give feedback.
-
During test stabilization work and migration to JUnit 4, I have replaced several "plain" assert statements with more comprehensible assertions based on Hamcrest matchers. In order to finally migrate tests to JUnit 5, I would like to proceed with that, as particularly the plain
assertEquals
is bad in terms of comprehensibility (unclear which parameter is expected and which is actual) and in terms of migration to JUnit 5 (the parameters have been swapped in the JUnit 5 assertions signatures requiring adaptations of everyassertEquals
statement).While using Hamcrest matchers are a valid way for improving assertions, there is also AssertJ as another (maybe eben more) popular library. I chose Hamcrest over AssertJ for rather simple reasons: I was used to it and the dependency was already added to the projects I touched first. Since I propose to replace
assertEquals
statements in general, a lot more assertions will be affected and I would like to give the opportunity for discussion on whether AssertJ (or even another library) would be preferred for assertions across all Platform projects.The benefit I see in AssertJ is its fluent API providing better syntax and eased combination of assertions. I also read that AssertJ may sometimes provide better error messages. On the other hand, I see benefits in Hamcrest when it comes to custom assertions that can be implemented in complex matchers. This could, for example, be used for all the resource existence assertions in Platform resource tests, which currently rely on simple
assertTrue
and do not provide very helpful debug output.If you have an opinion on that, I would be glad if you can share it here.
Beta Was this translation helpful? Give feedback.
All reactions