test(compose): Robolectric JVM Compose testing infra + PoC (#373)
Enables unit-testing Jetpack Compose UI on the JVM via Robolectric, so render-only screens can leave the jacocoNonJvmTestableSurface exclusion list and be counted by JaCoCo without an emulator. - add Robolectric 4.16.1 (test scope) + Compose ui-test-junit4/-manifest - testOptions.unitTests.isIncludeAndroidResources = true so resources (strings, Material3 theme) resolve on the JVM - src/test/resources/robolectric.properties pins sdk=36 (targetSdk 37 is a preview level Robolectric 4.16 has no sandbox for) - PoC: AddAnotherAccountScreenJvmTest drives the screen with the v2 createComposeRule under RobolectricTestRunner (3 tests, green on the JVM) - drop AddAnotherAccountScreen from jacocoNonJvmTestableSurface (now JVM-covered); floor stays 0.79 — re-ratchet deferred to end of #373 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
package org.libremail.ui.onboarding
|
||||
|
||||
import android.content.Context
|
||||
import androidx.compose.ui.test.assertIsDisplayed
|
||||
import androidx.compose.ui.test.junit4.v2.createComposeRule
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.performClick
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.libremail.R
|
||||
import org.libremail.ui.theme.LibreMailTheme
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
import org.robolectric.RuntimeEnvironment
|
||||
import org.robolectric.annotation.Config
|
||||
import org.robolectric.annotation.GraphicsMode
|
||||
|
||||
/**
|
||||
* Robolectric feasibility PoC (issue #373): proves Jetpack Compose UI can be unit-tested on the JVM
|
||||
* without an emulator. `createComposeRule()` drives [AddAnotherAccountScreen] under
|
||||
* [RobolectricTestRunner]; `stringResource(...)` and Material3 theming resolve because
|
||||
* `testOptions.unitTests.isIncludeAndroidResources` is enabled in `app/build.gradle.kts`. Runs under
|
||||
* `:app:testDebugUnitTest`, NOT `androidTest` — the instrumented `AddAnotherAccountScreenTest` stays.
|
||||
*
|
||||
* `@Config(sdk = [36])` because compileSdk/targetSdk 37 (preview) has no Robolectric 4.16 sandbox
|
||||
* (also the default in `src/test/resources/robolectric.properties`); `@GraphicsMode(NATIVE)` is
|
||||
* required for Compose to render under Robolectric.
|
||||
*/
|
||||
@RunWith(RobolectricTestRunner::class)
|
||||
@GraphicsMode(GraphicsMode.Mode.NATIVE)
|
||||
@Config(sdk = [36])
|
||||
class AddAnotherAccountScreenJvmTest {
|
||||
|
||||
@get:Rule
|
||||
val composeTestRule = createComposeRule()
|
||||
|
||||
private val context: Context get() = RuntimeEnvironment.getApplication()
|
||||
|
||||
private fun string(resId: Int): String = context.getString(resId)
|
||||
|
||||
private fun setContent(onAddAnother: () -> Unit = {}, onFinish: () -> Unit = {}) {
|
||||
composeTestRule.setContent {
|
||||
LibreMailTheme(darkTheme = false, dynamicColor = false) {
|
||||
AddAnotherAccountScreen(onAddAnother = onAddAnother, onFinish = onFinish)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun rendersAccountAddedTitleFromResources() {
|
||||
setContent()
|
||||
|
||||
// Proves the merged Android resource table loaded on the JVM (isIncludeAndroidResources).
|
||||
composeTestRule.onNodeWithText(string(R.string.onboarding_account_added_title)).assertIsDisplayed()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun tappingYes_invokesOnAddAnother() {
|
||||
var addAnother = false
|
||||
setContent(onAddAnother = { addAnother = true })
|
||||
|
||||
composeTestRule.onNodeWithText(string(R.string.onboarding_add_another_yes)).performClick()
|
||||
|
||||
assertTrue(addAnother)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun tappingNo_invokesOnFinish() {
|
||||
var finished = false
|
||||
setContent(onFinish = { finished = true })
|
||||
|
||||
composeTestRule.onNodeWithText(string(R.string.onboarding_add_another_no)).performClick()
|
||||
|
||||
assertTrue(finished)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
# Default SDK for every Robolectric (JVM) test (issue #373). compileSdk/targetSdk are 37, a
|
||||
# preview level Robolectric 4.16.x does not ship a sandbox for; 36 (Baklava) is its newest
|
||||
# supported level and needs JDK 21 (the project's Gradle JDK). Individual tests may still override
|
||||
# with @Config(sdk = [..]). Only affects tests run with RobolectricTestRunner; plain JUnit unit
|
||||
# tests are unaffected.
|
||||
sdk=36
|
||||
Reference in New Issue
Block a user