paparazzi: RobolectricTestRunner/AndroidJunitTestRunner not supported if includeAndroidResources = true

Description java.lang.UnsupportedOperationException: class redefinition failed: attempted to change the schema (add/remove fields)

This relates to this Issue: https://github.com/cashapp/paparazzi/issues/425

Steps to Reproduce

  1. Add Robolectric to gradle testImplementation "org.robolectric:robolectric:4.10.3"
  2. Add includeAndroidResources = true necessary for Robolectric, otherwise the test is skipped
testOptions {
        unitTests {
            includeAndroidResources = true
        }
}
  1. Add the RobolectricTestRunner or AndroidJunitTestRunner to your screenshot test
@RunWith(RobolectricTestRunner::class)
@Config(sdk = [33])
class CoffeeDrinkAppBarComposableHappyPathTest {
    @get:Rule
    val paparazzi =
        Paparazzi(
            deviceConfig =
            DeviceConfig.PIXEL_5.copy(
                nightMode = NightMode.NOTNIGHT,
                fontScale = 1.0f,
                locale = "en",
            ).setPhoneOrientation(PhoneOrientation.PORTRAIT),
            renderingMode = SessionParams.RenderingMode.V_SCROLL,
        )

    @Test
    fun snapComposable() {
        paparazzi.context.setDisplaySize(DisplaySize.LARGER)

        paparazzi.snapshot(name = "CoffeeDrinkAppBar_Happy") {
            AppTheme {
                CoffeeDrinkAppBar()
            }
        }
    }
}

Expected behavior Tests should also run if includeAndroidResources = true

Additional information:

  • Paparazzi Version: 1.3.1
  • OS: MacOS
  • Compile SDK: 33
  • Gradle Version: 8.x
  • Android Gradle Plugin Version: 8.x

You can find a reproducible example in this repo, branch bug/robolectric+paparazzi, :lazycolumnscreen:paparazzi module, test class -“CoffeeDrinkAppBarComposableHappyPathTest”

About this issue

  • Original URL
  • State: closed
  • Created 10 months ago
  • Comments: 17 (3 by maintainers)

Most upvoted comments

Update:

> Task :lazycolumnscreen:paparazzi:testDebugUnitTest FAILED
JNIHelp F 01-13 13:20:36 17223 21345896] java.lang.NoSuchMethodError: Method 'java.lang.String android.os.SystemProperties.native_get(java.lang.String, java.lang.String)' is not declared as native
JNIHelp F 01-13 13:20:36 17223 21345896] RegisterNatives failed for 'android/os/SystemProperties'; aborting...

which indicates that RobolectricTestRunner is interfering with Paparazzi’s ability to load Bridge.init which in turns sets up SystemProperties for things like BuildConfig.

Removing:

@RunWith(RobolectricTestRunner::class)
@Config(sdk = [33])

allows the test to pass as expected:

image.

Note that all other tests (including Robolectric tests!) run fine, with the above recipe, per the following command:

./gradlew lazycolumnscreen:paparazzi:testDebug

Therefore, I’m considering the original issue as closed. Paparazzi appears to now play nicely alongside Robolectric tests, which is an improvement from before! To go even further, (i.e., allowing Paparazzi AND RobolectricTestRunner to be in the same test) is out of scope. I’d love to support it, but I’m doubtful as to whether that will bear fruit given that the two frameworks both mock bits of the Android platform and so there is bound to be conflicts.

That being said, I’m happy to accept PRs or continue the discussion if other contributors/maintainers have ideas/PRs.