Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Espresso how to wait for some time(1 hour)?

In my test case I have to record for 1 hour, in robotium solo.sleep(600000) had done my work, but In espresso I am confused with IdlingResource concept. I have to start recording and wait for some time(depending on the type of test) 15mins, 60mins etc.

Equivalent code in robotium

    solo.clickOnView(solo.getView("start_record"));
    solo.sleep(duration * 60 * 1000);
    solo.clickOnView(solo.getView("stop_record"));

I tried to use it like this in espresso

@RunWith(AndroidJUnit4.class)
@SmallTest
public class AaEspressoTest {

private static final String LAUNCHER_ACTIVITY_FULL_CLASSNAME = "com.absd.rec.RecorderActivity";
private static Class<?> launcherActivityClass;
private Solo solo;
private static CoreRecordingTest skyroTestRunner;


private static Class<? extends Activity> activityClass;

static {
    try {
        activityClass = (Class<? extends Activity>) Class.forName(LAUNCHER_ACTIVITY_FULL_CLASSNAME);
    } catch (ClassNotFoundException e) {
        throw new RuntimeException(e);
    }
}

@Rule
public final ActivityTestRule<?> activityRule
        = new ActivityTestRule<>(activityClass);

private IntentServiceIdlingResource idlingResource;

@Before
public void registerIntentServiceIdlingResource() {
    Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
    idlingResource = new IntentServiceIdlingResource(instrumentation.getTargetContext());
    Espresso.registerIdlingResources(idlingResource);
}

@After
public void unregisterIntentServiceIdlingResource() {
    Espresso.unregisterIdlingResources(idlingResource);
}

@Test
public void testHello() throws Exception {

 onView(withId(AaEspressoTest.getId("recorderpage_record"))).perform(click());

    registerIntentServiceIdlingResource();

    onView(withId(AaEspressoTest.getId("recorderpage_stop"))).perform(click());

   }
}

Idling resource

public class IntentServiceIdlingResource implements IdlingResource {
private final Context context;
private ResourceCallback resourceCallback;
public static boolean status = false;

public IntentServiceIdlingResource(Context context) {
    this.context = context;
}

@Override
public String getName() {
    return IntentServiceIdlingResource.class.getName();
}

@Override
public boolean isIdleNow() {
    return getTimer();
}

@Override
public void registerIdleTransitionCallback(ResourceCallback resourceCallback) {
    this.resourceCallback = resourceCallback;

}

private static boolean getTimer() {

    new CountDownTimer(5000, 1000) {
        @Override
        public void onTick(long millisUntilFinished) {
            // Do Nothing
            status = false;
        }

        @Override
        public void onFinish() {             
            status = true;
        }
    };
    return status;
}
}

Exception:

android.support.test.espresso.IdlingResourceTimeoutException: Wait for [com.adbs.recorder.IntentServiceIdlingResource] to become idle timed out
like image 660
Shivaraj Patil Avatar asked May 10 '15 18:05

Shivaraj Patil


3 Answers

You need an IdlingResource with an isIdleNow() that returns true only if the specific amount of time has passed. To achieve that, save the start time and compare it with current time:

public class ElapsedTimeIdlingResource implements IdlingResource {
  private final long startTime;
  private final long waitingTime;
  private ResourceCallback resourceCallback;

  public ElapsedTimeIdlingResource(long waitingTime) {
    this.startTime = System.currentTimeMillis();
    this.waitingTime = waitingTime;
  }

  @Override
  public String getName() {
    return ElapsedTimeIdlingResource.class.getName() + ":" + waitingTime;
  }

  @Override
  public boolean isIdleNow() {
    long elapsed = System.currentTimeMillis() - startTime;
    boolean idle = (elapsed >= waitingTime);
    if (idle) {
      resourceCallback.onTransitionToIdle();
    }
    return idle;
  }

  @Override
  public void registerIdleTransitionCallback(
      ResourceCallback resourceCallback) {
    this.resourceCallback = resourceCallback;
  }
}

Create and register this idling resource in your test:

@Test
public static void waitForOneHour() {
  long waitingTime = DateUtils.HOUR_IN_MILLIS;

  // Start
  onView(withId(AaEspressoTest.getId("recorderpage_record")))
      .perform(click());

  // Make sure Espresso does not time out
  IdlingPolicies.setMasterPolicyTimeout(
      waitingTime * 2, TimeUnit.MILLISECONDS);
  IdlingPolicies.setIdlingResourceTimeout(
      waitingTime * 2, TimeUnit.MILLISECONDS);

  // Now we wait
  IdlingResource idlingResource = new ElapsedTimeIdlingResource(waitingTime);
  Espresso.registerIdlingResources(idlingResource);

  // Stop
  onView(withId(AaEspressoTest.getId("recorderpage_stop")))
      .perform(click());

  // Clean up
  Espresso.unregisterIdlingResources(idlingResource);
}

You need the setMasterPolicyTimeout and setIdlingResourceTimeout calls to make sure Espresso does not terminate the test due to time out.

Full example: https://github.com/chiuki/espresso-samples/tree/master/idling-resource-elapsed-time

like image 152
chiuki Avatar answered Oct 27 '22 11:10

chiuki


The default timeout that Espresso will wait for all registered resources to become idle is one minute.

You can change this using the IdlingPolicies class to set an explicit timeout:

IdlingPolicies.setIdlingResourceTimeout(1, TimeUnit.HOURS);
like image 22
ataulm Avatar answered Oct 27 '22 11:10

ataulm


@Before
public void registerIdlingResource() {
    IdlingPolicies.setMasterPolicyTimeout(60 * 1000 * 3, TimeUnit.MILLISECONDS);
    IdlingPolicies.setIdlingResourceTimeout(60 * 1000 * 3, TimeUnit.MILLISECONDS);
    mIdlingResource = BooleanIdlingResource.getIdlingResource();
    // To prove that the test fails, omit this call:
    IdlingRegistry.getInstance().register(mIdlingResource);
}

I test on my project, It works. Just setup before register idling resources. please check:

https://github.com/googlesamples/android-testing/tree/master/ui/espresso/IdlingResourceSample and

https://developer.android.com/reference/android/support/test/espresso/IdlingPolicies

like image 42
Norman Avatar answered Oct 27 '22 09:10

Norman