Robolectric and SystemUI, is it possible?

162 views
Skip to first unread message

Thomas Kuhnke

unread,
Jun 28, 2022, 6:54:18 AM6/28/22
to Robolectric
We want to write tests with the Robolectric Runner for our SystemUI Overlay, but we're facing multiple issues with that. 

first issue: preshipped robolectric versions are not compatible with API Level 32

 our build is based on Android 12.1.0_r5, which leads to the first issue. We needed to create a new prebuild version of robolectric 4.8.1 in our aosp setup under `prebuilts/misc/common/robolectric/` to get robolectric working with API Level 32. 

After messing a bit with the generated blueprint from the `prebuilts/misc/common/robolectric/update-script` we have a working module.

second issue: `prebuilts/misc/common/robolectric/android-all` is missing android 12.1 depencies

- adding dependencies manually and starting the copySdks task from the update.gradle did the job

BUT: I needed to change the name from android-all-12.1-robolectric-8229987.jar to android-all-instrumented-12.1-robolectric-8229987-i4.jar, otherwise the compilation of my tests failed to find the dependency. But this seems to work as a temporary workaround

third issue:  java.lang.NoSuchMethodException: com.android.systemui.xxx.<init>()
We created a robotests project inside our overidden SystemUI with following structure

robotests
  src
    com.android.systemui.car.systembar
      CarControlCenterControllerTest
  Android.bp


blueprint file looks like following:

android_robolectric_test {
    name: "MyCustomSystemUIRobolectricTests",
    srcs: ["src/**/*.java"],

    static_libs: [
    "android-support-annotations",
    "androidx.test.core",
    "androidx.test.runner",
    "androidx.test.ext.junit",
    "androidx.test.espresso.core",
    ],

    robolectric_prebuilt_version: "4.8.1",

    java_resource_dirs: ["config", "resources"],
    instrumentation_for: "MyCustomSystemUI",
    test_options: {
        timeout: 36000,
        shards: 10,
    },
}


Executing tests with `make RunMyCustomSystemUIRobolectricTests` leads to the issue, that nearly every class from the original SystemUI cannot be instantiated by the ReflectionHelper from Robolectric due to the missing Default Contructor. 

RunMyCustomSystemUIRobolectricTests0: 2) defaultSucceed(com.android.systemui.car.systembar.CarControlCenterControllerTest)
RunMyCustomSystemUIRobolectricTests0: java.lang.RuntimeException: java.lang.NoSuchMethodException: com.android.systemui.people.widget.PeopleSpaceWidgetPinnedReceiver.<init>()
RunMyCustomSystemUIRobolectricTests0:    at org.robolectric.util.ReflectionHelpers.callConstructor(ReflectionHelpers.java:434)
RunMyCustomSystemUIRobolectricTests0:    at org.robolectric.internal.bytecode.ShadowImpl.newInstanceOf(ShadowImpl.java:18)
RunMyCustomSystemUIRobolectricTests0:    at org.robolectric.shadow.api.Shadow.newInstanceOf(Shadow.java:35)
RunMyCustomSystemUIRobolectricTests0:    at org.robolectric.android.internal.AndroidTestEnvironment.registerBroadcastReceivers(AndroidTestEnvironment.java:675)
RunMyCustomSystemUIRobolectricTests0:    at org.robolectric.android.internal.AndroidTestEnvironment.installAndCreateApplication(AndroidTestEnvironment.java:339)
RunMyCustomSystemUIRobolectricTests0:    at org.robolectric.android.internal.AndroidTestEnvironment.lambda$createApplicationSupplier$0(AndroidTestEnvironment.java:229)
RunMyCustomSystemUIRobolectricTests0:    at org.robolectric.util.PerfStatsCollector.measure(PerfStatsCollector.java:53)
RunMyCustomSystemUIRobolectricTests0:    at org.robolectric.android.internal.AndroidTestEnvironment.lambda$createApplicationSupplier$1(AndroidTestEnvironment.java:226)
RunMyCustomSystemUIRobolectricTests0:    at com.google.common.base.Suppliers$NonSerializableMemoizingSupplier.get(Suppliers.java:167)
RunMyCustomSystemUIRobolectricTests0:    at org.robolectric.RuntimeEnvironment.getApplication(RuntimeEnvironment.java:71)
RunMyCustomSystemUIRobolectricTests0:    at org.robolectric.android.internal.AndroidTestEnvironment.setUpApplicationState(AndroidTestEnvironment.java:194)
RunMyCustomSystemUIRobolectricTests0:    at org.robolectric.RobolectricTestRunner.beforeTest(RobolectricTestRunner.java:325)
RunMyCustomSystemUIRobolectricTests0:    at org.robolectric.internal.SandboxTestRunner$2.lambda$evaluate$0(SandboxTestRunner.java:265)
RunMyCustomSystemUIRobolectricTests0:    at org.robolectric.internal.bytecode.Sandbox.lambda$runOnMainThread$0(Sandbox.java:88)
RunMyCustomSystemUIRobolectricTests0:    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
RunMyCustomSystemUIRobolectricTests0:    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
RunMyCustomSystemUIRobolectricTests0:    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
RunMyCustomSystemUIRobolectricTests0:    at java.base/java.lang.Thread.run(Thread.java:844)
RunMyCustomSystemUIRobolectricTests0: Caused by: java.lang.NoSuchMethodException: com.android.systemui.people.widget.PeopleSpaceWidgetPinnedReceiver.<init>()
RunMyCustomSystemUIRobolectricTests0:    at java.base/java.lang.Class.getConstructor0(Class.java:3322)
RunMyCustomSystemUIRobolectricTests0:    at java.base/java.lang.Class.getDeclaredConstructor(Class.java:2510)
RunMyCustomSystemUIRobolectricTests0:    at org.robolectric.util.ReflectionHelpers.callConstructor(ReflectionHelpers.java:420)
RunMyCustomSystemUIRobolectricTests0:  

I tried creating some of the Shadow Classes by myself with just an empty class, but this seems not to be the right way, as I would need to create hundreds more of them.

Does anybody have any Idea or different approach to get Robolectric and SystemUI together?

thanks in advance
Reply all
Reply to author
Forward
0 new messages