Back org.testng.Assert with AssertJ for behaviour-identical assertions#20
Merged
Conversation
Port the AssertJ-backed assertion implementation from testng-team/testng#3278 into this standalone artifact, so it can be dropped from the parent PR. - Assert: delegate assertNull/assertNotNull/assertSame/assertNotSame and assertThrows to AssertJ (behaviour-identical, only the failure message differs); remove the now-unused failSame/failNotSame helpers. Equality comparison intentionally keeps TestNG semantics (documented NOTE). - Mark org.testng.Assert @deprecated (recommend AssertJ); add @SuppressWarnings("deprecation") on Assertion. - pom: move assertj-core to compile scope (the main code depends on it). - docs: add MIGRATING_ASSERTIONS.md and link it from the README. expectThrows is kept unchanged (it returns the caught exception, which AssertJ's fluent API does not expose). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Follow-up to the AssertJ delegation: extend it to the remaining behaviour-identical entry points. - assertTrue/assertFalse -> assertThat(condition).as(message).isTrue()/isFalse() - fail(message) and fail(message, cause) -> org.assertj.core.api.Assertions.fail(...) These flow through the OO Assertion/SoftAssert wrappers automatically (they delegate to org.testng.Assert), so soft assertions now use AssertJ for these checks too. Only the failure-message text changes; the pass/fail behaviour is unchanged. Updated the message-format-sensitive tests accordingly: - assertTrue/assertFalse message regexps now match AssertJ's output. - SoftAssertTest#testAssertAllCount no longer counts report lines (AssertJ messages are multi-line); it asserts the failed message is reported once. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
krmahadevan
reviewed
Jun 29, 2026
| * @deprecated TestNG no longer maintains its own assertion library. Use a dedicated assertion | ||
| * library such as <a href="https://assertj.github.io/doc/">AssertJ</a> instead. The OpenRewrite | ||
| * recipe {@code org.openrewrite.java.testing.testng.TestNgToAssertj} migrates the whole class | ||
| * automatically; see {@code docs/MIGRATING_ASSERTIONS.md} for details. |
Member
There was a problem hiding this comment.
Will docs/MIGRATING_ASSERTIONS.md be part of the codebase? We should probably instead replace it with the web url of the repository so that people can come here and view this file to learn about the migration plan
Member
Author
There was a problem hiding this comment.
yes, the URL will be better
Member
There was a problem hiding this comment.
Can we fix this, so that we can get this merged?
krmahadevan
reviewed
Jun 29, 2026
krmahadevan
reviewed
Jun 29, 2026
krmahadevan
reviewed
Jun 29, 2026
krmahadevan
left a comment
Member
There was a problem hiding this comment.
@juherr - Please check some of the observations that i have logged. I am not sure if they are discrepancies or not. Just wanted to still call them out.
Address review feedback (Krishnan): point the @deprecated javadoc to the hosted migration guide URL instead of the in-repo file path, so it is clickable from generated javadoc. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
krmahadevan
approved these changes
Jun 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Ports the AssertJ-backed assertion implementation from
testng-team/testng#3278 into this standalone
org.testng:testng-assertsartifact. Once released, the parent PR can drop thesetestng-asserts/src/mainchanges and simply depend on this artifact.Only assertions whose semantics are identical to AssertJ are delegated.
assertEquals/assertNotEqualsand the collection/map/array variants keep TestNG's own comparison semantics onpurpose — see the
NOTEcomment added toAssert#areEqualImpl. The only user-visible change is theAssertJ-formatted failure messages on the delegated assertions.
Two commits:
1. Delegate behaviour-identical assertions to AssertJ
assertNull/assertNotNull/assertSame/assertNotSameandassertThrows→ AssertJ.failSame/failNotSame.org.testng.Assert@Deprecated(javadoc recommends AssertJ; notforRemoval— thisartifact is the home of
Assert);@SuppressWarnings("deprecation")onAssertion.pom.xml:assertj-coremoved fromtestto compile scope.docs/MIGRATING_ASSERTIONS.md, linked from the README.2. Delegate assertTrue / assertFalse / fail to AssertJ
assertTrue/assertFalse→assertThat(condition).as(message).isTrue()/.isFalse().fail(message)/fail(message, cause)→org.assertj.core.api.Assertions.fail(...).Assertion/SoftAssertwrappers automatically (they delegate toorg.testng.Assert), so soft assertions use AssertJ for these checks too — no change needed inSoftAssert/Assertion.assertTrue/assertFalse/test2_failsmessage regexps now match AssertJ output, andSoftAssertTest#testAssertAllCountno longer counts report lines (AssertJ messages aremulti-line) — it asserts the failed message is reported exactly once.
Notes
expectThrowsis unchanged: it returns the caught exception, which AssertJ's fluent API doesnot expose.
failis the shared failure sink for the (deliberately non-delegated)assertEquals/ collectionassertions. Delegating it routes those through AssertJ's
AssertionFailedError(a subclass ofAssertionError); the message text is still TestNG's (built byformat(...)), only theexception subtype changes. The full suite confirms no
assertEquals/collection test regressed.Lists/Maps→ JDK refactor from the source PR is not included here (already done in thisrepo via
c4d2bd2).Testing
./mvnw clean test→ BUILD SUCCESS,Tests run: 181, Failures: 0, Errors: 0, Skipped: 1../mvnw dependency:treeconfirmsorg.assertj:assertj-core:3.27.7:compile(testng/guava staytest).🤖 Generated with Claude Code