闲置资源的力量在于不必等待某些应用程序的处理(联网,计算,动画等)完成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); } } } }; } }