複数の一致するアイテムが見つかった場合でも、エスプレッソが私の関数に従って見つけた最初の要素と一致するようにエスプレッソ関数を記述しようとしています。
例:アイテムの価格を含むセルを含むリストビューがあります。通貨をカナダドルに切り替えて、アイテムの価格がCADであることを確認したい。
私はこの関数を使用しています:
onView(anyOf(withId(R.id.product_price), withText(endsWith("CAD"))))
.check(matches(
isDisplayed()));
これにより、AmbiguousViewMatcherExceptionがスローされます。
この場合、CADを表示するセルの数がいくつあっても問題ありません。表示されていることを確認したいだけです。エスプレッソがパラメーターを満たすオブジェクトに遭遇したらすぐにこのテストに合格する方法はありますか?
次のコードを使用して、最初のアイテムのみと一致するカスタムマッチャーを作成できるはずです。
private <T> Matcher<T> first(final Matcher<T> matcher) {
return new BaseMatcher<T>() {
boolean isFirst = true;
@Override
public boolean matches(final Object item) {
if (isFirst && matcher.matches(item)) {
isFirst = false;
return true;
}
return false;
}
@Override
public void describeTo(final Description description) {
description.appendText("should return first matching item");
}
};
}
同じidのような同じ特性を持つ要素が多く、最初の要素だけではなくが必要な場合に特定の要素が必要な場合に備えて、このマッチャーを作成しました。お役に立てれば:
private static Matcher<View> getElementFromMatchAtPosition(final Matcher<View> matcher, final int position) {
return new BaseMatcher<View>() {
int counter = 0;
@Override
public boolean matches(final Object item) {
if (matcher.matches(item)) {
if(counter == position) {
counter++;
return true;
}
counter++;
}
return false;
}
@Override
public void describeTo(final Description description) {
description.appendText("Element at hierarchy position "+position);
}
};
}
例:
使用しているライブラリから与えられた同じIDのボタンがたくさんあるので、2番目のボタンを選択します。
ViewInteraction colorButton = onView(
allOf(
getElementFromMatchAtPosition(allOf(withId(R.id.color)), 2),
isDisplayed()));
colorButton.perform(click());
私が理解していることから、あなたのシナリオでは、通貨を切り替えた後、すべての価格はCAD=)になるはずです。したがって、最初のアイテムを取得して確認するだけで問題も解決するはずです。
onData(anything())
.atPosition(0)
.onChildView(allOf(withId(R.id.product_price), withText(endsWith("CAD"))))
.check(matches(isDisplayed()));
私がちょうど同じ問題を抱えている人にとっては、1つのViewActionを実行するために共有されたMatcher @appmattusを使用している場合は問題ありませんが、Perform内に複数のViewActionsがある場合、それはできません:
onView(first(allOf(matcher1(), matcher2()))
.perform(viewAction1(), viewAction2())
viewAction1
が実行されますが、実行前にvewAction2
、マッチャーが再度評価され、isFirst
は常にfalseを返します。一致するビューがないことを示すエラーが表示されます。
したがって、ここでは複数のViewActionsを使用するバージョンで、最初の1つだけでなく、2番目または3番目(または...)を返す可能性があります。
class CountViewMatcher(val count: Int) : BaseMatcher<View>() {
private var matchingCount = 0
private var matchingViewId: Int? = null
override fun matches(o: Any): Boolean {
if (o is View) {
if (matchingViewId != null) {
// A view already matched the count
return matchingViewId == o.id
} else {
matchingCount++
if (count == matchingCount) {
matchingViewId = o.id
return true
} else {
return false
}
}
} else {
// o is not a view.
return false
}
}
}