我正在测试ViewPager应用程序。我开始使用ViewPagerIdlingResource,然后执行swipeLeft(),但在ViewPager甚至可以开始滚动onView()之前。调用check()并且测试失败。 这是我的ViewPagerIdlingResource,我几乎从vaughandroid
复制了public class ViewPagerIdlingResource implements IdlingResource {
private final String mName;
private boolean mIdle = true; // Default to idle since we can't query the scroll state.
private ResourceCallback mResourceCallback;
private boolean anyPageScrolledHappened = false;
public ViewPagerIdlingResource(ViewPager viewPager, String name) {
Log.i("ATAG", "ViewPagerIdlingResource constructor");
viewPager.addOnPageChangeListener(new ViewPagerListener());
mName = name;
}
@Override
public String getName() {
return mName;
}
@Override
public boolean isIdleNow() {
Log.i("ATAG", "isIdleNow: "+mIdle);
return mIdle;
}
@Override
public void registerIdleTransitionCallback(ResourceCallback resourceCallback) {
Log.i("ATAG", "ViewPagerIdlingResource registerIdleTransitionCallback");
mIdle = true;
mResourceCallback = resourceCallback;
}
public void setIdle (boolean idle) {
Log.i("ATAG", "setIdle: false and anyPageScrolledHappened = "+anyPageScrolledHappened);
if (!anyPageScrolledHappened && false == idle) {
mIdle = false;
}
}
private class ViewPagerListener extends ViewPager.SimpleOnPageChangeListener {
@Override
public void onPageScrollStateChanged(int state) {
anyPageScrolledHappened = true;
Log.i("ATAG", "ViewPager OnPageScrollStateChanged: ScrollState: " + state);
mIdle = (state == ViewPager.SCROLL_STATE_IDLE
// Treat dragging as idle, or Espresso will block itself when swiping.
|| state == ViewPager.SCROLL_STATE_DRAGGING);
if (mIdle && mResourceCallback != null) {
Log.i("ATAG", "OnTransitionToIdle");
mResourceCallback.onTransitionToIdle();
}
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
Log.i("ATAG", "ViewPager OnPageScrolled: ScrollState: " + "none");
}
@Override
public void onPageSelected(int position) {
Log.i("ATAG", "ViewPager OnPageSelected: ScrollState: " + "none");
}
}
}
这是我的考验。
@RunWith(AndroidJUnit4.class)
public class StraightLineTest {
private ViewPagerIdlingResource idlingResource;
private static final String shmi_s = "Shmi Skywalker";
private static final String anakin_s = "Anakin Skywalker";
private static final String leia_o = "Leia Organa";
private static final String jacen_s = "Jacen Solo";
private static final String allana_s = "Allana Solo";
@Rule
public IntentsTestRule<MainActivity> mActivityRule =
new IntentsTestRule(MainActivity.class, true, false);
@After
public void tearDownIdlingResource () {
unregisterIdlingResources(idlingResource);
}
@Test
public void firstSwipe () {
Activity activity = startActivity();
idlingResource = new ViewPagerIdlingResource((ViewPager)activity.
findViewById(R.id.view_pager), "VPIR_0");
registerIdlingResources(idlingResource);
onView(isRoot()).perform(swipeLeft());
//idlingResource.setIdle(false);
//waitForViewPagerResponse(1000);
onView(allOf(withId(R.id.character_name),withText(anakin_s))).
check(matches(isCompletelyDisplayed()));
}
@Test
public void fifthSwipe () {
Activity activity = startActivity();
idlingResource = new ViewPagerIdlingResource((ViewPager)activity.
findViewById(R.id.view_pager), "VPIR_0");
registerIdlingResources(idlingResource);
onView(isRoot()).perform(swipeLeft());
onView(allOf(withId(R.id.character_name),withText(anakin_s))).
check(matches(isCompletelyDisplayed()));
onView(isRoot()).perform(swipeLeft());
onView(allOf(withId(R.id.character_name),withText(leia_o))).
check(matches(isCompletelyDisplayed()));
onView(isRoot()).perform(swipeLeft());
onView(allOf(withId(R.id.character_name),withText(jacen_s))).
check(matches(isCompletelyDisplayed()));
onView(isRoot()).perform(swipeLeft());
onView(allOf(withId(R.id.character_name),withText(allana_s))).
check(matches(isCompletelyDisplayed()));
}
private MainActivity startActivity() {
return mActivityRule.launchActivity(null);
}
public static void waitForViewPagerResponse(long millis) {
final long startTime = System.currentTimeMillis();
final long endTime = startTime + millis;
do {}
while (System.currentTimeMillis() < endTime);
}
}
因此,第五个Swipe()测试总是通过。
firstSwipe()测试通常会失败。当firstSwipe()失败时,不会调用ViewPageListener内部的任何Log方法。如果我在swipeLeft()调用之后调用waitForViewPagerResponse(),则调用ViewPagerListener日志方法,并且测试通过。
如果我在swipeLeft()之后通过调用setIdle(false)将IdlingResource的mIdle设置为false,那么测试就会一直存在,直到它超时并且没有ViewPagerListener日志消息。
我试图找到一些方法将mIdle设置为false,直到它第一次开始滚动,然后它会在onPageScrollStateChanged()方法中将自己设置为true。但测试只是等待,滚动永远不会发生,检查永远不会发生,它只是超时。我得出结论,当isIdleNow()返回false时,ViewPager无法开始滚动。为什么isIdleNow()会影响ViewPager?我认为这样做是因为如果我只是让时间与waitForViewPagerResponse()一起传递,那么我最终会得到回调到ViewPagerListener。
有没有人有一个对ViewPagers没有这个问题的IdlingResource?我是否错误地实施了此IdlingResource?
这是github上的项目。 https://github.com/flocela/PagerAdapter
修改 这是失败时的日志(.setIdle()和waitForViewPagerResponse()仍被注释掉的情况。)我想要做的是执行快速扫描&#39;动作发生,但在ViewPager可以滚动之前(由ViewPagerListener日志指示),检查完成并且测试失败。
I / ATAG:ViewPagerIdlingResource构造函数
I / ATAG:ViewPagerIdlingResource registerIdleTransitionCallback
I / ATAG:isIdleNow:是的
D / InputManagerEventInjectionStrategy:使用输入管理器创建注入策略
I / ATAG:isIdleNow:是的
I / ATAG:isIdleNow:是的
I / ViewInteraction:执行快速刷卡&#39;视图上的操作是根视图。 I / ATAG:isIdleNow:是的
I / ATAG:isIdleNow:true (重复一段时间)
D / LifecycleMonitor:生命周期状态变化:--- .---。MainActivity@d771792 in:PAUSED
I / TestRunner:失败:firstSwipe(--- .---。StraightLineWIRTest)
I / TestRunner:-----开始异常----- I / TestRunner:android.support.test.espresso.base.DefaultFailureHandler $ AssertionFailedWithCauseError:&#39;至少100%的视图区域显示给用户。&#39;与所选视图不匹配。
预期:至少100%的视图区域会显示给用户
得到:&#34; AppCompatTextView {id = 2131427414,res-name = character_name,visibility = VISIBLE,(很多东西),x = 0.0,y = 0.0,text = Anakin Skywalker,输入 - type = 0,ime-target = false,has-links = false}&#34;
修改 这是我在swipeLeft()之后调用idlingResource.setIdle(false)时的日志输出。 waitForViewPagerResponse()仍然被注释掉了。我的观点是因为isIdleNow()返回false,因此ViewPager不会滚动。为什么会这样?
I / ATAG:ViewPagerIdlingResource构造函数
I / ATAG:ViewPagerIdlingResource registerIdleTransitionCallback
I / ATAG:isIdleNow:是的
D / InputManagerEventInjectionStrategy:使用输入管理器创建注入策略
I / ATAG:isIdleNow:是的
I / ATAG:isIdleNow:是的
I / ViewInteraction:执行快速刷卡&#39;视图上的操作是根视图
I / ATAG:isIdleNow:是的
I / ATAG:isIdleNow:true (重复一段时间)
I / ATAG:setIdle:false和anyPageScrolledHappened = false
I / ATAG:isIdleNow:false
I / ATAG:isIdleNow:false
W / IdlingPolicy:这些资源不是空闲的:[VPIR_0] (2行重复)
I / ATAG:isIdleNow:false (2行重复)
D / LifecycleMonitor:生命周期状态变化:--- .---。MainActivity@d771792 in:PAUSED
I / TestRunner:失败:firstSwipe(flobee.pageradapterex.StraightLineWIRTest)
I / TestRunner:-----开始异常-----
I / TestRunner:android.support.test.espresso.IdlingResourceTimeoutException:等待[VPIR_0]空闲超时