web-dev-qa-db-ja.com

Espressoはどのようにして(1時間)待つのですか?

私のテストケースでは、1時間記録する必要があります。robotiumでsolo.sleep(600000)が私の作業を完了しましたが、エスプレッソではIdlingResourceの概念と混同されています。記録を開始し、しばらく待つ必要があります(テストの種類によって異なります)15分、60分など。

Robotiumの同等のコード

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

エスプレッソでこんな風に使ってみました

@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());

   }
}

アイドリングリソース

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;
}
}

例外:

Android.support.test.espresso.IdlingResourceTimeoutException: Wait for [com.adbs.recorder.IntentServiceIdlingResource] to become idle timed out
17
Shivaraj Patil

特定の時間が経過した場合にのみIdlingResourceを返すisIdleNow()とともにtrueが必要です。これを実現するには、開始時間を保存して現在の時間と比較します。

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;
  }
}

このアイドリングリソースを作成してテストに登録します。

@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);
}

Espressoがタイムアウトのためにテストを終了しないようにするには、setMasterPolicyTimeoutおよびsetIdlingResourceTimeoutの呼び出しが必要です。

完全な例: https://github.com/chiuki/espresso-samples/tree/master/idling-resource-elapsed-time

37
chiuki

Espressoが登録されたすべてのリソースがアイドルになるのを待機するデフォルトのタイムアウトは1分です。

IdlingPolicies クラスを使用してこれを変更し、明示的なタイムアウトを設定できます。

IdlingPolicies.setIdlingResourceTimeout(1, TimeUnit.HOURS);
15
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);
}

私は自分のプロジェクトでテストしましたが、うまくいきます。アイドリングリソースを登録する前にセットアップするだけです。チェックしてください:

https://github.com/googlesamples/Android-testing/tree/master/ui/espresso/IdlingResourceSample および

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

1
Norman