Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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