私のテストケースでは、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
特定の時間が経過した場合にのみ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
Espressoが登録されたすべてのリソースがアイドルになるのを待機するデフォルトのタイムアウトは1分です。
IdlingPolicies
クラスを使用してこれを変更し、明示的なタイムアウトを設定できます。
IdlingPolicies.setIdlingResourceTimeout(1, TimeUnit.HOURS);
@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