Java Espresso闲置资源,等待onCreate中启动的任务
我尝试使用EspressoJava Espresso闲置资源,等待onCreate中启动的任务,java,android,android-espresso,Java,Android,Android Espresso,我尝试使用EspressoIdlingResource等待在Activity.onCreate中启动的后台任务 我看到了类似的问题,但提议的解决方案对我不起作用 我在我的活动中添加了一个waitForIdle(long timeout)方法,我在@Before方法中调用了该方法,这种方法很有效,但在应用程序代码中有点侵入性,idlingsource就是为了达到这个目的 从给定的链接中,我了解到之前的@是在活动之后调用的。一旦创建,然后注册idlingsource就太迟了 我的idlingsour
IdlingResource
等待在Activity.onCreate
中启动的后台任务
我看到了类似的问题,但提议的解决方案对我不起作用
我在我的活动
中添加了一个waitForIdle(long timeout)
方法,我在@Before
方法中调用了该方法,这种方法很有效,但在应用程序代码中有点侵入性,idlingsource
就是为了达到这个目的
从给定的链接中,我了解到之前的@是在活动之后调用的。一旦创建,然后注册idlingsource
就太迟了
我的idlingsource
需要活动
实例来确定它是否空闲。使用ActivityTestRule.beforeActivityLaunched
只需允许我创建一个“空的”IDlingSource
(getActivity()
此时为null
)并注册它。然后在@Before
中,我将活动设置为我的IdlingResource
,但浓缩咖啡仍然没有等待它。甚至不调用isIdleNow
(我不太热衷于为此目的覆盖测试运行程序)
以下是用于测试的代码段:
main活动
:
public class MainActivity extends AppCompatActivity
{
private Object mIdleMonitor = new Object();
private boolean mIdle;
private TextView mHello;
private View mProgress;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mHello = findViewById(R.id.main_hello);
mProgress = findViewById(R.id.main_progress);
toggleWorkingState(true);
new Thread(new Runnable()
{
@Override
public void run()
{
SystemClock.sleep(5000);
runOnUiThread(new Runnable()
{
@Override
public void run()
{
mHello.setText(R.string.main_hello_label);
toggleWorkingState(false);
}
});
}
}).start();
}
@UiThread
private void toggleWorkingState(boolean working)
{
mProgress.setVisibility(working ? View.VISIBLE : View.GONE);
synchronized(mIdleMonitor)
{
mIdle = !working;
mIdleMonitor.notify();
}
}
public boolean isIdle()
{
synchronized(mIdleMonitor)
{
return mIdle;
}
}
public void waitForIdle(long timeout)
{
long end = System.currentTimeMillis() + timeout;
synchronized(mIdleMonitor)
{
while(!mIdle && System.currentTimeMillis() < end)
{
try
{
mIdleMonitor.wait(timeout);
}
catch(InterruptedException e)
{
break;
}
}
}
}
}
MainActivityTest
:
@RunWith(AndroidJUnit4.class)
public class MainActivityTest
{
private IdlingRegistry mIdlingRegistry = IdlingRegistry.getInstance();
@Rule
public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<MainActivity>(MainActivity.class)
{
@Override
protected void beforeActivityLaunched()
{
super.beforeActivityLaunched();
mIdlingResource = new MainActivityIdlingResource();
mIdlingRegistry.register(mIdlingResource);
}
@Override
protected void afterActivityFinished()
{
super.afterActivityFinished();
if (mIdlingResource != null)
{
mIdlingRegistry.unregister(mIdlingResource);
}
}
};
private MainActivity mActivity;
private MainActivityIdlingResource mIdlingResource;
/**
* Source: https://stackoverflow.com/a/37864603/2551689
*/
public static ViewAction replaceProgressBarDrawable()
{
return actionWithAssertions(new ViewAction()
{
@Override
public Matcher<View> getConstraints()
{
return isAssignableFrom(ProgressBar.class);
}
@Override
public String getDescription()
{
return "replace the ProgressBar drawable";
}
@Override
public void perform(final UiController uiController, final View view)
{
// Replace the indeterminate drawable with a static red ColorDrawable
ProgressBar progressBar = (ProgressBar) view;
progressBar.setIndeterminateDrawable(new ColorDrawable(0xffff0000));
uiController.loopMainThreadUntilIdle();
}
});
}
@Before
public void setUp()
{
mActivity = mActivityRule.getActivity();
mIdlingResource.setActivity(mActivity);
// using this watcher, UiController.loopMainThreadUntilIdle() fixes the idle issue, don't understand why nor if it's mandatory
// onView(withId(R.id.main_progress)).perform(replaceProgressBarDrawable());
// using mActivity.waitForIdle(6000); do the job but is not the expected solution
}
@Test
public void test_idle_state()
{
assertTrue(mActivity.isIdle());
onView(withId(R.id.main_progress)).check(matches(not(isDisplayed())));
onView(withText(R.string.main_hello_label)).check(matches(isDisplayed()));
}
}
@RunWith(AndroidJUnit4.class)
公共类维护活动测试
{
私有IdlingRegistry mIdlingRegistry=IdlingRegistry.getInstance();
@统治
public ActivityTestRule mActivityRule=新的ActivityTestRule(MainActivity.class)
{
@凌驾
在ActivityLaunched()之前受保护的空
{
super.beforeActivityLaunched();
mIdlingResource=新的MainActivityIdlingResource();
mIdlingRegistry.register(mIdlingResource);
}
@凌驾
受保护的无效afterActivityFinished()
{
super.afterActivityFinished();
if(mIdlingResource!=null)
{
mIdlingRegistry.unregister(mIdlingResource);
}
}
};
私人活动能力;
私人维护活动idlingresource mIdlingResource;
/**
*资料来源:https://stackoverflow.com/a/37864603/2551689
*/
公共静态ViewAction replaceProgressBarDrawable()
{
返回带有断言的操作(new ViewAction()
{
@凌驾
公共匹配器getConstraints()
{
返回isAssignableFrom(ProgressBar.class);
}
@凌驾
公共字符串getDescription()
{
返回“替换可绘制的ProgressBar”;
}
@凌驾
公共作废执行(最终UiController UiController,最终视图)
{
//用静态红色可拉伸材料替换不确定可拉伸材料
ProgressBar=(ProgressBar)视图;
progressBar.SetUndeterminatedRavable(新的彩色绘图(0xffff0000));
uiController.loopMainThreadUntilIdle();
}
});
}
@以前
公共作废设置()
{
mActivity=mActivityRule.getActivity();
mIdlingResource.setActivity(mActivity);
//使用此监视程序UiController.loopMainThreadUntilIdle()修复空闲问题,不理解为什么,也不知道它是否是必需的
//onView(带id(R.id.main_progress)).perform(replaceProgressBarDrawable());
//使用mActivity.waitForIdle(6000);完成工作,但不是预期的解决方案
}
@试验
公共无效测试\u空闲\u状态()
{
assertTrue(mActivity.isIdle());
onView(带id(R.id.main_progress))。检查(匹配项(不是(isDisplayed())));
onView(带有文本(R.string.main\u hello\u标签)).check(匹配项(isDisplayed());
}
}
由于涉及到一个ProgressBar
,我还使用了一个不确定的可绘制替换,使用了一个观察者(请参阅),并且UiController.loopMainThreadUntilIdle()
内部调用使整个事情按预期工作(在@之前的中调用)。有什么想法吗?我认为应该使用Espresso.registerIdlingResource而不是IdlingRegistry.register
@RunWith(AndroidJUnit4.class)
public class MainActivityTest
{
private IdlingRegistry mIdlingRegistry = IdlingRegistry.getInstance();
@Rule
public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<MainActivity>(MainActivity.class)
{
@Override
protected void beforeActivityLaunched()
{
super.beforeActivityLaunched();
mIdlingResource = new MainActivityIdlingResource();
mIdlingRegistry.register(mIdlingResource);
}
@Override
protected void afterActivityFinished()
{
super.afterActivityFinished();
if (mIdlingResource != null)
{
mIdlingRegistry.unregister(mIdlingResource);
}
}
};
private MainActivity mActivity;
private MainActivityIdlingResource mIdlingResource;
/**
* Source: https://stackoverflow.com/a/37864603/2551689
*/
public static ViewAction replaceProgressBarDrawable()
{
return actionWithAssertions(new ViewAction()
{
@Override
public Matcher<View> getConstraints()
{
return isAssignableFrom(ProgressBar.class);
}
@Override
public String getDescription()
{
return "replace the ProgressBar drawable";
}
@Override
public void perform(final UiController uiController, final View view)
{
// Replace the indeterminate drawable with a static red ColorDrawable
ProgressBar progressBar = (ProgressBar) view;
progressBar.setIndeterminateDrawable(new ColorDrawable(0xffff0000));
uiController.loopMainThreadUntilIdle();
}
});
}
@Before
public void setUp()
{
mActivity = mActivityRule.getActivity();
mIdlingResource.setActivity(mActivity);
// using this watcher, UiController.loopMainThreadUntilIdle() fixes the idle issue, don't understand why nor if it's mandatory
// onView(withId(R.id.main_progress)).perform(replaceProgressBarDrawable());
// using mActivity.waitForIdle(6000); do the job but is not the expected solution
}
@Test
public void test_idle_state()
{
assertTrue(mActivity.isIdle());
onView(withId(R.id.main_progress)).check(matches(not(isDisplayed())));
onView(withText(R.string.main_hello_label)).check(matches(isDisplayed()));
}
}