Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ActivityScenario<MainActivity> hangs on perform(click())

In general, I'm here because tried-and-true ActivityTestRule<> is deprecated, and apparently I need to use ActivityScenario<> or ActivityScenarioRule<>.

But they break the rule "tests on the view should treat view objects like objects." I must "efficiently" cram all assertions into a callback, for example. I can't get ActivityScenarioRule<> working because there's no way to stuff my database and delay the call to onCreate().

So that leaves me with ActivityScenario<>, and I can get this far:

    //  stuff database
    ActivityScenario<MainActivity> scenario = ActivityScenario.launch(MainActivity.class);

    scenario.onActivity( (ma) -> {
        //  assertions on ma that pass

        onView(withId(R.id.configure_device_button)).perform(click());
        
        //  ...
    } );

The problem is the perform(click()) hangs up, deep inside of a wait().

What are we waiting for?

When I treat the view objects like objects, ma.configureDeviceButton.performClick() works. So this means I must now re-write every one of my hundreds of view tests...


It turns out I can share my MainActivity handle, ma, like this:

    activateActivity( (ma) -> {
        TestFixtures.ma = ma;
    } );

The MainActivity lives longer than its callback. (Which opens the question Why use a callback if we are not using the Execute Around Pattern?)

So I might not need to rearchitect everything. Everyone still needs an answer why my by-the-book perform(click()) hung up, though...

like image 905
Phlip Avatar asked Mar 03 '23 02:03

Phlip


1 Answers

onActivity action block is performed on UIThread and onView will wait for UIThread to idle.

You need to call onView outside the onActivity block or else it will deadlock. From your code

scenario.onActivity( (ma) -> {
   //  Do your UI setup
});
onView(...).perform(...);
like image 163
Tinh Thach Avatar answered Mar 05 '23 16:03

Tinh Thach