Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BCEL-343 JUnit Assertion improvement #69

Merged
merged 8 commits into from
Oct 7, 2020

Conversation

mureinik
Copy link
Contributor

@mureinik mureinik commented Oct 7, 2020

As a followup to #68 (BCEL-342), now that the tests are migrated to JUnit Jupiter, it's a good opportunity to go over the assertions and clean them up.
The main gain from this PR is improving the readability and maintainability of the tests. There is a theoretical performance improvement here too, but my benchmarking it on my limited resources, I could not observe a meaningful difference.

This PR offers the following improvements:

  1. Remvoes unused methods from test classes
  2. Removes unnescesary casts from test classes
  3. Simplifies the idiom of assertTrue(!condition, message) to assertTrue(condtion, message) in order to make the tests easier to understand
  4. Simplifies the idiom of assertTrue(x.equals(y), message) to assertEquals(x, y, message) in order to make the tests easier to understand. As a side bonus, most of these messages were constructed dynamically with the values of x and y, and using assertEquals allowed relying on JUnit's existing functionality to display them in case of failure instead of reinventing the wheel. This not only shortens the code by removing boilerplate logical, but also theoritically improves performance as this string needs to be constructed only in case of a test failure.
  5. Simplifies the idiom of assertTrue(primitiveX == primitiveY, message) to assertEquals(x, y, message), for similar benefits as the previous point.
  6. Simplifies the idiom of if(!x.equals(y)) fail(message) to assertEquals(x, y, message), for similar benefits as the previous point.
  7. Simplifies the idiom of catching an exception and explicitly failing to allowing the test methods to throw those exceptions and have the test runner handle it.
  8. In the remaining cases where an assertion had a non-constant string message it was replaced with a Supplier<String> that supplies the same message so that it's only evaluated in case of an assertion failure.
  9. Some minor typos in assertion messages were fixed where noticed.

Fix a typo in FieldAnnotationsTestCase#checkValue: "Didnt" to
"Didn't".
Simplify assertTrue calls with negative conditions to assertFalse
calls which are easier to understand.
Copy link
Member

@garydgregory garydgregory left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mureinik
Thank you for your PR; I just have a few comment (see each file).

@@ -81,7 +80,8 @@ private void compare(final JavaClass jc, final InputStream inputStream, final St
int i = 0;
for (final int out : baos.toByteArray()) {
final int in = src.read();
assertEquals(in, out & 0xFF, name + ": Mismatch at " + i);
int j = i;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need j?

Copy link
Contributor Author

@mureinik mureinik Oct 7, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes - values in a lambda expression must be final or effectively final, and i isn't, so I assigned it to j, which is (since it's scoped in the loop's body and is never modified).

Alternatively, we can leave the message as is and not replace it with a Supplier.

@garydgregory
Copy link
Member

Clean up assertions code by using the built-in assertions in
org.junit.jupiter.api.Assertions instead of reinventing the wheel.

assertTrue(x.equals(y)) and assertTrue(primitiveX == primitiveY)
are simplified to assertEquals(x, y).

The main gain by this patch is cleaning up the code and making it
easier to maintain.
A side bonus is that many assertions simplified to assertEquals calls
had messages that were manually constructed to show the difference
between the two values being compared, and these messages were
constructed regardless of the assertion success or failure. By using
assertEquals, these string concatenations are avoided as long as the
assert succeeds.
Clean up assertions code by using the built-in assertions in
org.junit.jupiter.api.Assertions instead of reinventing the wheel.

This patch simplifies the idiom of using an if to explicitly check for
equality:
```
if (!a.equals(b)) {
    fail("a should equal b");
}
```

with the build it assertEquals(a, b, "a should equal b").
Replace the idiom of catching an exception and then explicitly calling
org.junit.jupiter.api.Assertions with just allowing the error to be
thrown from the test method and leaving the it up to the runner to
handle the failure.
In the cases that assertions have non-constant failure messages, these
messages are replaced with Suppliers that produce them in order to
avoid producing the calculated string unconditionally.
@mureinik
Copy link
Contributor Author

mureinik commented Oct 7, 2020

@garydgregory Fixed the formatting issues and answered wrt the usage of j (see inline - left that comment unresolved for your decision)

@garydgregory garydgregory changed the title BCEL-343 Assertion improvement BCEL-343 JUnit Assertion improvement Oct 7, 2020
@garydgregory garydgregory merged commit 215508b into apache:master Oct 7, 2020
@mureinik mureinik deleted the BCEL-343-assertions branch October 7, 2020 14:18
asfgit pushed a commit that referenced this pull request Oct 7, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants