+1 from me

In CASSANDRA-15564 I build my own assert chain to make the tests cleaner;
did it since assertj wasn't there.

On Tue, Mar 10, 2020, 9:28 AM Kevin Gallardo <kevin.galla...@datastax.com>
wrote:

> 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.
>

Reply via email to