闲置资源的力量在于不必等待某些应用程序的处理(联网,计算,动画等)完成sleep(),这会带来脆弱性和/或延长测试的运行时间。官方文档可以在这里找到。
实施IdlingResource接口时,需要做三件事:
getName() -返回空闲资源的名称。
isIdleNow() -检查您的xyz对象,操作等当前是否处于空闲状态。
registerIdleTransitionCallback(IdlingResource.ResourceCallbackcallback)-提供一个回调,当对象转换为空闲状态时应调用该回调。
现在,您应该创建自己的逻辑,并确定您的应用何时处于空闲状态以及何时不处于空闲状态,因为这取决于应用程序。在下面,您将找到一个简单的示例,仅用于演示其工作原理。在线上还有其他示例,但是特定的应用程序实现带来了特定的空闲资源实现。
在Google的一些示例中,他们将IdlingResources应用程序代码放入其中。不要这样做。他们大概把它放在那里只是为了展示他们的工作方式。
保持代码整洁并保持单一责任原则取决于您!
假设您有一个活动,它做的事情很奇怪,并且需要很长的时间才能加载片段,从而使Espresso测试失败,因为无法从片段中找到资源(您应该更改活动的创建方式和时间加快速度)。但是为了简单起见,下面的示例显示了它的外观。
我们的示例空闲资源将获得两个对象:
您需要查找并等待连接到活动的片段的标签。
一个FragmentManager对象,用于查找片段。
/**
* FragmentIdlingResource - idling resource which waits while Fragment has not been loaded.
*/
public class FragmentIdlingResource implements IdlingResource {
private final FragmentManager mFragmentManager;
private final String mTag;
//活动转换为空闲时使用的资源回调
private volatile ResourceCallback resourceCallback;
public FragmentIdlingResource(FragmentManager fragmentManager, String tag) {
mFragmentManager = fragmentManager;
mTag = tag;
}
@Override
public String getName() {
return FragmentIdlingResource.class.getName() + ":" + mTag;
}
@Override
public boolean isIdleNow() {
//简单检查,如果添加了片段,则您的应用程序变得空闲
boolean idle = (mFragmentManager.findFragmentByTag(mTag) != null);
if (idle) {
//重要说明:确保您调用onTransitionToIdle
resourceCallback.onTransitionToIdle();
}
return idle;
}
@Override
public void registerIdleTransitionCallback(ResourceCallback resourceCallback) {
this.resourceCallback= resourceCallback;
}
}现在您已经IdlingResource写了,您需要在正确的地方使用它吗?
让我们跳过整个测试类的设置,只看一下测试用例的外观:
@Test
public void testSomeFragmentText() {
mActivityTestRule.launchActivity(null);
//创建空闲资源
IdlingResource fragmentLoadedIdlingResource = new FragmentIdlingResource(mActivityTestRule.getActivity().getSupportFragmentManager(), SomeFragmentText.TAG);
//注册空闲资源,以便意式浓缩咖啡等待它
Espresso.registerIdlingResources(idlingResource1);
onView(withId(R.id.txtHelloWorld)).check(matches(withText(helloWorldText)));
//让我们自己清理
Espresso.unregisterIdlingResources(fragmentLoadedIdlingResource);
}这并不难;您还可以以JUnit测试规则的形式应用空闲资源。例如,假设您有一些包含Volley的SDK,并且希望Espresso等待它。您可以创建一个JUnit规则,而无需编写每个测试用例或将其应用到设置中,而只需编写:
@Rule public final SDKIdlingRule mSdkIdlingRule = new SDKIdlingRule(SDKInstanceHolder.getInstance());
现在,因为这是一个示例,所以不要将其视为理所当然;这里的所有代码都是虚构的,仅用于演示目的:
public class SDKIdlingRule implements TestRule {
//您编写要检查的空闲资源是否凌空空闲
private VolleyIdlingResource mVolleyIdlingResource;
//从排球请求您需要的队列以将其分配给空闲资源
private RequestQueue mRequestQueue;
//使用规则时,从SDK中提取请求队列
public SDKIdlingRule(SDKClass sdkClass) {
mRequestQueue = getVolleyRequestQueue(sdkClass);
}
private RequestQueue getVolleyRequestQueue(SDKClass sdkClass) {
return sdkClass.getVolleyRequestQueue();
}
@Override
public Statement apply(final Statement base, Description description) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
//注册空闲资源
mVolleyIdlingResource = new VolleyIdlingResource(mRequestQueue);
Espresso.registerIdlingResources(mVolleyIdlingResource);
try {
base.evaluate();
} finally {
if (mVolleyIdlingResource != null) {
//测试完成后注销资源
Espresso.unregisterIdlingResources(mVolleyIdlingResource);
}
}
}
};
}
}