Skip to content

Commit

Permalink
Bump Robolectric plugin to latest & write a basic doc section on JUnit 5
Browse files Browse the repository at this point in the history
  • Loading branch information
mannodermaus committed May 23, 2024
1 parent 624193f commit 0015851
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 1 deletion.
1 change: 1 addition & 0 deletions docs/roborazzi-docs.tree
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<toc-element topic="build_setup.md"/>
<toc-element topic="how_to_use.md"/>
<toc-element topic="compose_multiplatform.md"/>
<toc-element topic="junit5.md"/>
<toc-element topic="gradle_properties_options.md"/>
<toc-element topic="faq.md"/>
</instance-profile>
87 changes: 87 additions & 0 deletions docs/topics/junit5.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# JUnit 5 support

Roborazzi supports the execution of screenshot tests with JUnit 5,
powered by the combined forces of the [Android JUnit 5](https://github.com/mannodermaus/android-junit5) plugin
and the [JUnit 5 Robolectric Extension](https://github.com/apter-tech/junit5-robolectric-extension).

### Setup

To get started with Roborazzi for JUnit 5, make sure to set up your project for the new testing framework first
and add the dependencies for JUnit Jupiter and the Robolectric extension to your project (check the readme files
of either project linked above to find the latest version). Then, add the `roborazzi-junit5` dependency
next to the existing Roborazzi dependency. The complete build script setup looks something like this:

```kotlin
// Root moduls's build.gradle.kts:
plugins {
id("io.github.takahirom.roborazzi") version "$roborazziVersion" apply false
id("de.mannodermaus.android-junit5") version "$androidJUnit5Version" apply false
id("tech.apter.junit5.jupiter.robolectric-extension-gradle-plugin") version "$robolectricExtensionVersion" apply false
}
```

```kotlin
// App module's build.gradle.kts:
plugins {
id("de.mannodermaus.android-junit5")
id("tech.apter.junit5.jupiter.robolectric-extension-gradle-plugin")
}

dependencies {
testImplementation("org.robolectric:robolectric:$robolectricVersion")
testImplementation("io.github.takahirom.roborazzi:$roborazziVersion")
testImplementation("io.github.takahirom.roborazzi-junit5:$roborazziVersion")

testImplementation("org.junit.jupiter:junit-jupiter-api:$junitJupiterVersion")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:$junitJupiterVersion")
}
```

You are now ready to write a JUnit 5 screenshot test with Roborazzi.

### Write a test

JUnit 5 does not have a concept of `@Rule`. Instead, extension points to the test framework have to be registered,
and Roborazzi is no exception to this. Add the `@ExtendWith` annotation to the test class and insert both the
extension for Robolectric (from the third-party dependency defined above) and Roborazzi (from `roborazzi-junit5`).
If you also have JUnit 4 on the classpath, make sure to import the correct `@Test` annotation (`org.junit.jupiter.api.Test`
instead of `org.junit.Test`):

```kotlin
// MyTest.kt:
@ExtendWith(RobolectricExtension::class, RoborazziExtension::class)
class MyTest {
@Test
fun test() {
// Your ordinary Roborazzi setup here, for example:
ActivityScenario.launch(MainActivity::class.java)
onView(isRoot()).captureRoboImage()
}
}
```

### Automatic Extension Registration

You may tell JUnit 5 to automatically attach the `RoborazziExtension` to applicable test classes,
minimizing the redundancy of having to add `@ExtendWith(RoborazziExtension::class)` to every class.
This is done via a process called [Automatic Extension Registration](https://junit.org/junit5/docs/current/user-guide/#extensions-registration-automatic) and must be enabled in the build file.
Be aware that you still need `ExtendWith` for the `RobolectricExtension`, since it is not eligible for
automatic registration. Think of it as the JUnit 5 equivalent of `@RunWith(RobolectricTestRunner::class)`:

```kotlin
// App module's build.gradle.kts:
junitPlatform {
configurationParameter(
"junit.jupiter.extensions.autodetection.enabled",
"true"
)
}
```

```kotlin
// MyTest.kt:
@ExtendWith(RobolectricExtension::class)
class MyTest {
// ...
}
```
5 changes: 4 additions & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ mavenPublish = "0.25.3"
composeCompiler = "1.5.6"
composeMultiplatform = "1.6.2"
junit5Android = "1.10.0.0"
junit5Robolectric = "0.5.2"
junit5Robolectric = "0.7.0"
robolectric = "4.12.2"
robolectric-android-all = "Q-robolectric-5415296"

Expand Down Expand Up @@ -54,6 +54,9 @@ kotlin-stdlib-jdk8 = { module = "org.jetbrains.kotlin:kotlin-stdlib-jdk8" }
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test" }
kotlin-test-junit = { module = "org.jetbrains.kotlin:kotlin-test-junit" }

android-junit5-plugin = { module = "de.mannodermaus.gradle.plugins:android-junit5", version.ref = "junit5Android" }
robolectric-junit5-plugin = { module = "tech.apter.junit5.jupiter:robolectric-extension-gradle-plugin", version.ref = "junit5Robolectric" }

androidx-activity = { module = "androidx.activity:activity", version.ref = "androidx-activity" }
androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activity" }
androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "androidx-appcompat" }
Expand Down
2 changes: 2 additions & 0 deletions include-build/roborazzi-gradle-plugin/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ dependencies {
integrationTestDepImplementation libs.android.tools.build.gradle
integrationTestDepImplementation libs.kotlin.gradle.plugin
integrationTestDepImplementation libs.compose.gradle.plugin
integrationTestDepImplementation libs.android.junit5.plugin
integrationTestDepImplementation libs.robolectric.junit5.plugin
}

sourceSets {
Expand Down

0 comments on commit 0015851

Please sign in to comment.