Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ evolve and be released independently.

* JDK 11 (or higher)

The assertion classes themselves depend only on the JDK. TestNG is required at **test scope** only
(to run the assertion tests via the TestNG runner).
`org.testng.Assert` delegates the behaviour-identical assertions (`assertNull`/`assertNotNull`/
`assertSame`/`assertNotSame`, `assertThrows`) to [AssertJ](https://assertj.github.io/doc/), so
`assertj-core` is the only runtime dependency (brought transitively). TestNG is required at **test
scope** only (to run the assertion tests via the TestNG runner).

## Usage

Expand All @@ -31,6 +33,8 @@ If you previously relied on `org.testng.Assert` / `org.testng.asserts.*` coming
`org.testng:testng`, add `org.testng:testng-asserts` explicitly.

For new code or larger refactoring efforts, [AssertJ](https://assertj.github.io/doc/) is recommended.
See [docs/MIGRATING_ASSERTIONS.md](docs/MIGRATING_ASSERTIONS.md) for the migration guide, including
the automated OpenRewrite recipe.

## Building

Expand Down
158 changes: 158 additions & 0 deletions docs/MIGRATING_ASSERTIONS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
# Migrating away from `org.testng.Assert`

`org.testng.Assert` is **deprecated**. TestNG no longer wants to maintain its own assertion library
and instead recommends a dedicated one such as [AssertJ](https://assertj.github.io/doc/).

This is part of a longer plan:

- [testng-asserts#15](https://github.com/testng-team/testng-asserts/issues/15) — deprecate the
internal assertion API and let users choose their preferred library.
- [testng#3197](https://github.com/testng-team/testng/issues/3197) — make the `testng-asserts`
module optional.

`org.testng.Assert` now lives in the standalone `org.testng:testng-asserts` artifact, separate from
the main `org.testng:testng` jar. Migrating now keeps your test suite working across that transition.

## What replaces `org.testng.Assert`?

[AssertJ](https://assertj.github.io/doc/). Its fluent API covers everything `org.testng.Assert`
offers, with better failure messages:

```java
// Before — org.testng.Assert
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;

assertEquals(actual, expected);
assertTrue(result);

// After — AssertJ
import static org.assertj.core.api.Assertions.assertThat;

assertThat(actual).isEqualTo(expected);
assertThat(result).isTrue();
```

> **Note the parameter order.** `org.testng.Assert` uses `(actual, expected)`. AssertJ reads
> `assertThat(actual).isEqualTo(expected)`. The automated recipe below handles this for you.

Add AssertJ to your build:

```xml
<!-- Maven -->
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
```

```kotlin
// Gradle
testImplementation("org.assertj:assertj-core:<latest>")
```

## Automated migration with OpenRewrite

[OpenRewrite](https://docs.openrewrite.org/) provides a recipe that rewrites **the entire**
`org.testng.Assert` API to AssertJ. The full Assert coverage is available since
[rewrite-testing-frameworks v3.39.0](https://github.com/openrewrite/rewrite-testing-frameworks/releases/tag/v3.39.0).

Recipe: `org.openrewrite.java.testing.testng.TestNgToAssertj` — *"Migrate TestNG assertions to
AssertJ"*. It handles both qualified (`Assert.assertEquals(...)`) and static-import
(`assertEquals(...)`) usages.

### Gradle

Apply the OpenRewrite plugin and activate the recipe:

```kotlin
plugins {
id("org.openrewrite.rewrite") version "<latest>"
}

dependencies {
rewrite("org.openrewrite.recipe:rewrite-testing-frameworks:<3.39.0-or-newer>")
}

rewrite {
activeRecipe("org.openrewrite.java.testing.testng.TestNgToAssertj")
}
```

Run it:

```bash
./gradlew rewriteRun
```

### Maven

```xml
<plugin>
<groupId>org.openrewrite.maven</groupId>
<artifactId>rewrite-maven-plugin</artifactId>
<version><!-- latest --></version>
<configuration>
<activeRecipes>
<recipe>org.openrewrite.java.testing.testng.TestNgToAssertj</recipe>
</activeRecipes>
</configuration>
<dependencies>
<dependency>
<groupId>org.openrewrite.recipe</groupId>
<artifactId>rewrite-testing-frameworks</artifactId>
<version><!-- 3.39.0 or newer --></version>
</dependency>
</dependencies>
</plugin>
```

Run it:

```bash
mvn rewrite:run
```

> Check the [OpenRewrite docs](https://docs.openrewrite.org/) for the current plugin and recipe
> versions. After the recipe runs, add the `org.assertj:assertj-core` test dependency (shown above)
> and run your test suite to confirm everything passes.

## Manual migration

If you prefer to migrate by hand, the most common mappings are:

| `org.testng.Assert` | AssertJ |
| --------------------------------------- | ------------------------------------------------ |
| `assertEquals(actual, expected)` | `assertThat(actual).isEqualTo(expected)` |
| `assertNotEquals(actual, expected)` | `assertThat(actual).isNotEqualTo(expected)` |
| `assertTrue(condition)` | `assertThat(condition).isTrue()` |
| `assertFalse(condition)` | `assertThat(condition).isFalse()` |
| `assertNull(object)` | `assertThat(object).isNull()` |
| `assertNotNull(object)` | `assertThat(object).isNotNull()` |
| `assertSame(actual, expected)` | `assertThat(actual).isSameAs(expected)` |
| `assertNotSame(actual, expected)` | `assertThat(actual).isNotSameAs(expected)` |
| `assertThrows(Type.class, runnable)` | `assertThatThrownBy(runnable).isInstanceOf(Type.class)` |
| `fail(message)` | `fail(message)` (`org.assertj.core.api.Assertions.fail`) |

See the [AssertJ documentation](https://assertj.github.io/doc/) for the full API.

## Packaging notes

`org.testng.Assert` is no longer bundled in the main `org.testng:testng` jar. To keep using it, add
the standalone artifact, which brings AssertJ transitively:

```xml
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng-asserts</artifactId>
<scope>test</scope>
</dependency>
```

> **OSGi:** `testng-asserts` currently ships as a plain JAR, not an OSGi bundle. `org.testng.Assert`
> and `org.testng.FileAssert` share the `org.testng` package with the core classes exported by the
> `testng` bundle, so giving `testng-asserts` its own bundle would create a split package. Proper
> OSGi support is tracked as a follow-up
> ([testng#3197](https://github.com/testng-team/testng/issues/3197)); OSGi users should prefer
> migrating to AssertJ.
14 changes: 7 additions & 7 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -63,20 +63,20 @@

<dependencies>
<!--
The main code has NO runtime dependency: it only uses the JDK.
AssertJ is the only runtime dependency: org.testng.Assert delegates the
behaviour-identical assertions (assertNull/NotNull/Same/NotSame, assertThrows) to it.
TestNG is required at test scope only, to run the assertion tests
(annotations, runner) and for the collection helpers used by the tests.
-->
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>[7.10.2,)</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.27.7</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>[7.10.2,)</version>
<scope>test</scope>
</dependency>
<dependency>
Expand Down
Loading