2016-07-08 19 views
1

iOS XcodeのNSPredicateに類似した述語を達成する方法はありますか?Android Espressoの特定のイベントを待つ方法はありますか?自動テストのAndroid Espressoの述語ですか?

iOSの場合はexpectationForPredicatewaitForExpectationsWithTimeoutXCTestの一部として呼び出すことができます。

私はiOSとAndroid用の2つの同様のアプリをテストしています。 iOS版では、私は次の操作を行うことができますアンドロイドで

let app = XCUIApplication(); 
    let condition = app.staticTexts["Text That Displays After Event"] 
    let exists = NSPredicate(format: "exists == true") 
    expectationForPredicate(exists, evaluatedWithObject: condition, handler: nil) 
    waitForExpectationsWithTimeout(5, handler: nil) 

    XCTAssert(app.staticTexts["Text That Displays After Event"].exists) 

私ができる最善のは、アイドリングリソースを登録し、イベントを手動で起こったかどうかをチェック数秒間待っています。

long waitingTime = 3 * DateUtils.SECOND_IN_MILLIS; 
    IdlingPolicies.setMasterPolicyTimeout(waitingTime * 2, TimeUnit.MILLISECONDS); 
    IdlingPolicies.setIdlingResourceTimeout(waitingTime * 2, TimeUnit.MILLISECONDS); 
    IdlingResource idlingResource = new ElapsedTimeIdlingResource(waitingTime); 
    Espresso.registerIdlingResources(idlingResource); 

    onView(withId(R.id.id_in_next_event)).check(matches(isDisplayed())); 

    Espresso.unregisterIdlingResources(idlingResource); 

これを行うにはより良い方法が必要です。

答えて

1

ほとんどのことはInstrumentation#waitForIdleSync()メソッドで行うことができます。これにより、すべてのUIイベントが処理されてから続行されるのを待ちます。つまり、ID buttonIdのボタンがあると、押したときにID hiddenViewのビューが表示されます。

あなたはこのような何か場合:hiddenViewView#setVisibility()を呼ぶだろう「クリック」を行う、この過程でそう

private final Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); 

@Test 
public void checkViewIsRevealed() { 
    onView(withId(R.id.buttonId)).perform(click()); 

    instrumentation.waitForIdleSync(); 

    onView(withId(R.id.hiddenView)).check(matches(isDisplayed()); 
} 

を。次に、アイドル状態を待って、すべてのUIアクションが確実に行われるようにします。次に、新しいビューが表示されていることを確認します。

+0

おかげで、これは素晴らしい作品。それは、私が必要としていたボレーのリクエストを待っています。 – Jack

+0

@ジャック:私はそれに疲れているだろう。これは、すべてのUI操作が完了するのを待つだけです。 Volleyは、完全に別個の非同期ライブラリです。私はあなたがダウンロード操作はちょうど本当に高速です(これは良いですが、それは後で爆破するつもりだと思います)。 – DeeV

+0

@DeeV 'waitForIdleSync()'の呼び出しは絶対に必要ありません。エスプレッソはアプリがアイドル状態になるのを待っている。 – thaussma

0

Matcher<View>がtrueになるのを待つカスタムViewActionを書くことができます。 それは、エスプレッソがそれ自身で待っていない場合にのみ必要です。エスプレッソは、例えば待っている。アプリケーションのメインスレッドが動作している場合、またはAsyncTaskが実行中の場合

待機ビューのアクションは次のように実装することができます。

public class WaitForCondition implements ViewAction { 
    private static final long IDLING_INTERVAL = 50; 
    private final Matcher<View> mCondition; 
    private final long mTimeout; 

    public WaitForCondition(final Matcher<View> condition, final long timeout) { 
     mCondition = condition; 
     mTimeout = timeout; 
    } 

    @Override 
    public Matcher<View> getConstraints() { 
     return isAssignableFrom(View.class); 
    } 

    @Override 
    public String getDescription() { 
     return String.format(Locale.US, "Waiting until the condition '%s' will become true (timeout %d ms)", getConditionDescription(), mTimeout); 
    } 

    private String getConditionDescription() { 
     StringDescription description = new StringDescription(); 
     mCondition.describeTo(description); 
     return description.toString(); 
    } 

    @Override 
    public void perform(final UiController uiController, final View view) { 

     if (mCondition.matches(view)) { 
      return; 
     } 
     final long timeOut = System.currentTimeMillis() + mTimeout; 

     // Wait for the condition to become true 
     while (System.currentTimeMillis() <= timeOut) { 
      uiController.loopMainThreadForAtLeast(IDLING_INTERVAL); 
      if (mCondition.matches(view)) { 
       return; 
      } 
     } 
     throw new PerformException.Builder() 
       .withActionDescription(this.getDescription()) 
       .withViewDescription(HumanReadables.describe(view)) 
       .withCause(new RuntimeException(String.format(Locale.US, 
         "Condition '%s' did not become true after %d ms of waiting.", getConditionDescription(), mTimeout))) 
       .build(); 
    } 
} 

し、それを使用します。

onView(withId(R.id.id_in_next_event)).perform(new WaitForCondition(matches(isDisplayed()), 3000)); 
関連する問題