There is an auxiliary class DialogIdlingResource , thanks to which I try to run my tests, all tests pass except this activates and runs to the step of pressing the button:

 AcceptanceHelper.clickOnButtonInLayout(R.id.mainSignButton, R.string.common_signin_button_text, R.id.inputLayout) 

then everything stops, although the test is supposed to work out (namely, check the text in the isDialogRunning method):

 @Test fun signInUserWithInvalidEmail() { goToSignIn() AcceptanceHelper.updateValidationTextView(R.string.ui_data_attribute_email, "kokojambo@mail.ru") AcceptanceHelper.updateValidationTextView(R.string.ui_data_attribute_password, VALID_PASSWORD) AcceptanceHelper.clickOnButtonInLayout(R.id.mainSignButton, R.string.common_signin_button_text, R.id.inputLayout) val idlingResource = DialogIdlingResource() registerDialogIdlingResource() unregisterDialogIdlingResource() } private fun registerDialogIdlingResource() { val instrumentation = InstrumentationRegistry.getInstrumentation() idlingResource = DialogIdlingResource() Espresso.registerIdlingResources(idlingResource) } private fun unregisterDialogIdlingResource() { Espresso.unregisterIdlingResources(idlingResource) } 

I suppose that the error is due to the two methods of registration and UN registration idlingResource

But in fact, everything should work, but maybe somewhere that most likely made a mistake, the code of the auxiliary class:

 class DialogIdlingResource(private val waitTimeSeconds: Int = 5) : IdlingResource { private var resourceCallback: IdlingResource.ResourceCallback? = null private var startTime = -1L override fun getName(): String { return DialogIdlingResource::class.java.name } override fun isIdleNow(): Boolean { if (startTime < 0) { startTime = System.currentTimeMillis() } val timeOut = System.currentTimeMillis() - waitTimeSeconds * 1000 > startTime if (timeOut) throw TimeoutException("error") val idle = !isDialogRunning if (idle && resourceCallback != null) { resourceCallback!!.onTransitionToIdle() } return idle } override fun registerIdleTransitionCallback(resourceCallback: IdlingResource.ResourceCallback) { this.resourceCallback = resourceCallback } private val isDialogRunning: Boolean get() { try { onView(Matchers.allOf(withId(R.id.titleTextView), ViewMatchers.withText("Warning"))) .check(ViewAssertions.matches(isDisplayed())) } catch (e: NoMatchingViewException) { e.printStackTrace() System.out.println("some text") } return true } 

}

  • Add a label which framework you use for testing. - Eugene Krivenja
  • It looks like it is at the top of Java, and at the bottom is Kotlin. Then in the third fragment, the constructor of the DialogIdlingResource class is called. But DialogIdlingResource has no such constructor. What don't I understand? - tse
  • @tse in the third fragment I showed how I used to call the context from the java class (it was then, before replacing it with id with text). Now I need to call them exactly, from the java class as I called the earlier context - Inkognito
  • Id what and text what do you want to get? - tse
  • @tse in the constructor I have id values ​​and I want to get their text in my @ Before after instrumentation ... - Inkognito

1 answer 1

Immediately I will say you have a very complicated realization of what can be done much easier, well, it seems to me. At the moment I see two options:

The first option is described in detail by reference in this github repository. The principle of which consists in putting down the parameters you need and the place where they are located. I also advise you to pay attention to the flags of the visibility parameter.

Well, the second option will look something like this. Create a class that we inherit from IdlingResource , implement its methods, and fill in:

 class ElapsedTimeIdlingResource(private val activity: SignActivity?) : IdlingResource { private var callback: IdlingResource.ResourceCallback? = null override fun getName(): String { return "SignInScreenTest" } override fun isIdleNow(): Boolean { val idle = isIdle if (idle) callback!!.onTransitionToIdle() return idle } val isIdle: Boolean get() = activity != null && callback != null override fun registerIdleTransitionCallback(resourceCallback: IdlingResource.ResourceCallback) { this.callback = resourceCallback } } 

After that in your tests after clicking on the button we will implement the call as follows:

 val activity = mActivityTestRule.getActivity() val idlingResource = ElapsedTimeIdlingResource(activity) Espresso.registerIdlingResources(idlingResource) 

Where we "get" the components of our activism, otherwise open elements / transitions will probably lead to null your activations. As I understand it, you are trying to open a dialogue in your activity . Then we register our idlingResource from the class. After your dialogue has opened, for example, you can check the elements contained in it, or simply go back. After all operations, in the same test you need to call:

 Espresso.unregisterIdlingResources(idlingResource) 

Also, you have probably already seen that it is possible to put the registerIdlingResource/unregisterIdlingResources in the @ Before / @ After annotation in order not to always prescribe the same thing, if we say several tests.

And again for additional reading: an example of use .

  • Thank you, in general, it worked out, and when I run this test separately, everything is fine, but if I launch everything completely, the dialogue does not have time to load and, accordingly, the test drops, but if I put down on Espresso.registerIdlingResources(idlingResource) timeout is `onView ( isRoot ()). perform (AcceptanceHelper.waitFor (10000)) `then everything works correctly, but in my opinion the whole point of this implementation is lost, since it still waits 10 seconds. - Inkognito
  • Well, if you are expecting a dialogue, then you need to check it in the 'ElapsedTimeIdlingResource' class, and not the activity. Or did you do that? - Morozov