Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Robolectric 4.6.1 does not work with ActivityScenario from androidx.test.monitor 1.3.0 #6781

Closed
nborodikhin opened this issue Oct 20, 2021 · 6 comments · Fixed by #6787
Closed

Comments

@nborodikhin
Copy link

Description

Hello,

I am using ActivityScenario as outlined in the AndroidX test guide. After upgrading Robolectric to 4.6.1 I got two issues - one reported as #6593 and the other one:

    java.lang.IllegalStateException: No instrumentation registered! Must run under a registering instrumentation.
        at androidx.test.InstrumentationRegistry.getInstrumentation(InstrumentationRegistry.java:50)
        at androidx.test.InstrumentationRegistry.getTargetContext(InstrumentationRegistry.java:101)
        at org.robolectric.android.internal.LocalActivityInvoker.getIntentForActivity(LocalActivityInvoker.java:142)
        at androidx.test.core.app.ActivityScenario.<init>(ActivityScenario.java:175)
        at androidx.test.core.app.ActivityScenario.launch(ActivityScenario.java:194)
        at ...MyTest.<init>(...MyTest.kt:73)

The root cause of this issue is that LocalActivityInvoker is getting target context from now-deprecated InstrumentationRegistry here but in this particular combination of frameworks it is never set.

The change that broke compatibility it the reimplementation RoboMonitoringInstrumentation: daa9d1a

Why combination Robolectric 4.5 + androidx.test 1.3 works

  • androidx.test has two independent InstrumentationRegistry classes: androidx.test.InstrumentationRegistry and androidx.test.platform.app.InstrumentationRegistry
  • RoboMonitoringInstrumentation descends from androidx.test.runner.MonitoringInstrumentation
  • androidx.test.runner.MonitoringInstrumentation configures both instrumentation registries: link
  • LocalActivityInvoker accesses deprecated instrumentation registry which is explicitly set up

Why combination Robolectric 4.6 + androidx.test 1.4 works

  • androidx.test has has one main InstrumentationRegistry implementation: androidx.test.platform.app.InstrumentationRegistry
  • Deprecated androidx.test.InstrumentationRegistry forwards all calls to the main one: link
  • Robolectric uses its own implementation of RoboMonitoringInstrumentation which installs itself into only one instrumentation registry: link
  • LocalActivityInvoker accesses configured instrumentation registry via the forwarding provided by the deprecated one

Why combination Robolectric 4.5 + androidx.test 1.3 does not work

  • androidx.test has two independent InstrumentationRegistry classes: androidx.test.InstrumentationRegistry and androidx.test.platform.app.InstrumentationRegistry
  • Robolectric uses its own implementation of RoboMonitoringInstrumentation which installs itself into one registry: link
  • LocalActivityInvoker is trying to get target context from now-deprecated InstrumentationRegistry which is not configured

Steps to Reproduce

package foo.bar

import android.app.Activity
import androidx.test.core.app.ActivityScenario
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
class MyTest {
    @Test
    fun foo() {
        val scenario = ActivityScenario.launch(Activity::class.java)
    }

Robolectric & Android Version

Robolectric: 4.6.1
androidx.test: 1.3.0

Link to a public git repo demonstrating the problem:

Proposed solution

Robolectric does not use deprecated InstrumentationRegistry with the exception of LocalActivityInvoker. I think the appropriate solution would be to migrate deprecated registry access in LocalActivityInvoker to use main registry androidx.test.platform.app.InstrumentationRegistry.

@brettchabot
Copy link
Contributor

Is your gradle file forcing a androidx.test:monitor:1.3.0 version? org.robolectric:robolectric:4.61 has a dependency on androidx.test:monitor:1.4.0 +. IMO its working as expected that it isn't backwards compatible with older monitor versions.

@nborodikhin
Copy link
Author

Is your gradle file forcing a androidx.test:monitor:1.3.0 version?

@brettchabot unfortunately so. The project uses LeakCanary which works with some androidx.test internals and is not compatible to 1.4.0 yet.

@brettchabot
Copy link
Contributor

This sounds like a LeakCanary bug then

@nborodikhin
Copy link
Author

This sounds like a LeakCanary bug then

Of course, there is an issue reported to LeakCanary and it will eventually be fixed.

Anyway, third-party projects and the question of whether Robolectric should be compatible to older versions of androidx.test aside, using deprecated registry getters without setting anything there looks like a logical error and should be fixed sooner or later. I obviously would prefer to have it fixed as soon as 4.6.2 to help my case, but I am fine if it fixed in the next release cycle.

@nborodikhin
Copy link
Author

As a temporary workaround, I was able to configure the registry manually:

fun installHack() {
  val instrumentation = androidx.test.platform.app.InstrumentationRegistry.getInstrumentation()
  val arguments = androidx.test.platform.app.InstrumentationRegistry.getArguments()
  androidx.test.InstrumentationRegistry.registerInstance(instrumentation, arguments)
}

class MyTest {
  init {
    installHack()
  }
  
  ...
}

@utzcoz
Copy link
Member

utzcoz commented Nov 8, 2021

Hi @nborodikhin , the PR that migrated registry API for LocalActivityInvoker has been merged, you can try SNAPSHOT(https://github.com/robolectric/robolectric/wiki/Running-Robolectric-SNAPSHOT) to test it or wait next alpha release. If you have any question about it, feel free to reopen this issue. Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants