I would like to propose adding AssertJ <https://assertj.github.io/doc/> as a test dependency and therefore have it available for writing unit/distributed/any test assertions.
In addition to the examples mentioned on the AssertJ docs page (allows to do elaborate and comprehensible assertions on Collections, String, and *custom assertions*), here's an example of a dtest I was looking at, that could be translated to AssertJ syntax, just to give an idea of how the syntax would apply: *JUnit asserts*: try { [...] } catch (Exception e) { Assert.assertTrue(e instanceof RuntimeException); RuntimeException re = ((RuntimeException) e); Assert.assertTrue(re.getCause() instanceof ReadTimeoutException); ReadTimeoutException rte = ((ReadTimeoutException) e.getCause()); Assert.assertTrue(rte.getMessage().contains("blabla") && rte.getMessage().contains("andblablo")); } *AssertJ style:* try { [...] } catch (Exception e) { Assertions.assertThat(e) .isInstanceOf(RuntimeException.class) .hasCauseExactlyInstanceOf(ReadTimeoutException.class) .hasMessageContaining("blabla") .hasMessageContaining("andblablo"); } The syntax is more explicit and more comprehensible, but more importantly, when one of the JUnit assertTrue() fails, you don't know *why*, you only know that the resulting boolean expression is false. If a failure happened with the assertJ tests, the failure would say "Exception did not contain expected message, expected "blabla", actual "notblabla"" (same for a lot of other situations), this makes debugging a failure, after a test ran and failed much easier. With JUnit asserts you would have to additionally add a message explaining what the expected value is *and* what the actual value is, for each assert that is more complex than a assertEquals on a number, I suppose. I have seen a lot of tests so far that only test the expected behavior via assertTrue and does not show the incorrect values when the test fails, which would come for free with AssertJ. Other examples randomly picked from the test suite: *org.apache.cassandra.repair.RepairJobTest#testNoTreeRetainedAfterDistance:* Replace assertion: assertTrue(messages.stream().allMatch(m -> m.verb() == Verb.SYNC_REQ)); With: assertThat(messages) .extracting(Message::verb) .containsOnly(Verb.SYNC_REQ); As a result, if any of the messages is not a Verb.SYNC_REQ, the test failure will show the actual "Verb"s of messages. Replace: assertTrue(millisUntilFreed < TEST_TIMEOUT_S * 1000); With: assertThat(millisUntilFreed) .isLessThan(TEST_TIMEOUT_S * 1000); Same effect if the condition is not satisfied, more explicit error message explaining why the test failed. AssertJ also allows Custom assertions which are also very useful and could potentially be leveraged in the future. This would only touch on the tests' assertions, the rest of the test setup and execution remains untouched (still uses JUnit for the test execution). Thanks. -- Kévin Gallardo.