Issue
I have a LoginActivity
, which uses firebase
as the back-end. When I have successfully signed in, my MainActivity
shows up successfully.
How do I write an Espresso test for this activity change?
The ordinary way, that Espresso keeps track of the current activity itself does only seems to work on activities that does not need to wait for firebase. When using it when using firebase auth, I get this error message:
android.support.test.espresso.NoMatchingViewException: No views in hierarchy found matching: with id: (my application package):id/button2
(button2 is the id of a button in the new activity, but this happens with whatever view I’m trying to reach in the new activity)
I’ve also tried to use ActivityMonitor and similar methods. They do not seem to fetch any activity change at all.
Thread.sleep()
gives the impression to do exactly the opposite of what I want to do: It seems to pause the application, not the test itself.
I’m aware that I should not test the functionality of firebase itself, but my application relies heavily on the user being signed in, and I would late on like to write other tests which tests the GUI
and functionality for users that have signed in.
How do I write an correct espresso test for an activity change when using firebaseauth
to check if I should trigger the activity?
Solution
You need to use the IdlingResource class. Espresso does not have a way to tell when your UI is waiting on an asynchronous network call such as Firebase. IdlingResource was created for this exact purpose. Here’s one way to solve your problem.
- In your code have something that keeps track of when you waiting for a network call. Maybe a boolean called isInProgress.
- create an IdlingResource class in the same folder as your test, something like this:
Example:
import android.support.test.espresso.IdlingResource
import com.myexample.MainActivity
class LoginIdlingResource constructor(
private val mainActivity: MainActivity
) : IdlingResource{
private var resourceCallback: IdlingResource.ResourceCallback? null
override fun getName(): String {
return LoginIdlingResource::class.java.name
}
override fun isIdleNow(): Boolean {
return !mainActivity.isInProgress() // <----- Important part
}
override fun registerIdleTransitionCallback(callback: IdlingResource.ResourceCallback?) {
this.resourceCallback callback
}
}
- Register the IdlingResource class in your tests @Before function like this:
Example:
@get:Rule
val mActivityTestRule: ActivityTestRule<MainActivity> ActivityTestRule(MainActivity::class.java)
@Before
fun init() { IdlingRegistry.getInstance()
.register(RegisterIdlingResource(mActivityTestRule.activity))
}
Now Espresso will wait whenever your Boolean says isInProgress.
Answered By – szaske