Espresso Idling Resource 使用

来源:互联网 发布:淘宝上正品篮球店铺 编辑:程序博客网 时间:2024/05/24 00:52

Espresso Idling Resources 简介

Espresso 的核心是在测试应用时同步所有的测试操作,Espresso默认等待当前消息队列的UI事件被处理和AsyncTasks完成才进行下一步测试操作。

但是有时候应用的后台操作(如与web services 通信)使用自定义Threadde 的非标准方法,在这种情况下就需要使用 Idling Resources 去通知Espresso App正在后台进行长操作。

创建并注册 Idling Resources

可以implement IdlingResource interface 接口自定义实现,也可以使用现有的实现如CountingIdlingResource

自定义Idling Resources

第一步:定义SimpleIdlingResource implements IdlingResource

public class SimpleIdlingResource implements IdlingResource {    @Nullable     private volatile ResourceCallback mCallback;    // Idleness is controlled with this boolean.    private AtomicBoolean mIsIdleNow = new AtomicBoolean(true);    @Override    public String getName() {        return this.getClass().getName();    }    @Override    public boolean isIdleNow() {        return mIsIdleNow.get();    }    @Override    public void registerIdleTransitionCallback(ResourceCallback callback) {        mCallback = callback;    }    /**     * Sets the new idle state, if isIdleNow is true, it pings the {@link ResourceCallback}.     * @param isIdleNow false if there are pending operations, true if idle.     */    public void setIdleState(boolean isIdleNow) {        mIsIdleNow.set(isIdleNow);        if (isIdleNow && mCallback != null) {            mCallback.onTransitionToIdle();        }    }}

setIdleState(true) : 调用ResourceCallback.onTransitionToIdle(),此时后台任务执行完成
setIdleState(false) : 后台任务正在执行

第二步: 在后台任务执行之前之前调用idlingResource.setIdleState(false),通知Espresso任务正在执行,在后台任务执行完成时调用idlingResource.setIdleState(true)使应用状态变为闲置(Idle),通知Espresso任务完成

static void processMessage(final String message, final DelayerCallback callback,            @Nullable final SimpleIdlingResource idlingResource) {        // The IdlingResource is null in production.        if (idlingResource != null) {            idlingResource.setIdleState(false);        }        // Delay the execution, return message via callback.        Handler handler = new Handler();        handler.postDelayed(new Runnable() {            @Override            public void run() {                if (callback != null) {                    callback.onDone(message);                    if (idlingResource != null) {                        idlingResource.setIdleState(true);                    }                }            }        }, DELAY_MILLIS);    }

第三步: 在android test中测试异步任务部分,定义IdlingResource引用在Activity中创建的对象,在测试开始前注册,

Espresso.registerIdlingResources(mIdlingResource);

test完成后注销

Espresso.unregisterIdlingResources(mIdlingResource);
@RunWith(AndroidJUnit4.class)@LargeTestpublic class ChangeTextBehaviorTest {    private static final String STRING_TO_BE_TYPED = "Espresso";    @Rule    public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(            MainActivity.class);    private IdlingResource mIdlingResource;    @Before    public void registerIdlingResource() {        mIdlingResource = mActivityRule.getActivity().getIdlingResource();        // To prove that the test fails, omit this call:        Espresso.registerIdlingResources(mIdlingResource);    }    @Test    public void changeText_sameActivity() {        // Type text and then press the button.        onView(withId(R.id.editTextUserInput))                .perform(typeText(STRING_TO_BE_TYPED), closeSoftKeyboard());        onView(withId(R.id.changeTextBt)).perform(click());        // Check that the text was changed.        onView(withId(R.id.textToBeChanged)).check(matches(withText(STRING_TO_BE_TYPED)));    }    @After    public void unregisterIdlingResource() {        if (mIdlingResource != null) {            Espresso.unregisterIdlingResources(mIdlingResource);        }    }}

注: mIdlingResource 只有在进行Android测试时才会被初始化

    /**     * Only called from test, creates and returns a new {@link SimpleIdlingResource}.     */    @VisibleForTesting    @NonNull    public IdlingResource getIdlingResource() {        if (mIdlingResource == null) {            mIdlingResource = new SimpleIdlingResource();        }        return mIdlingResource;    }

Google Sample 地址

Check out the Espresso Idling Resource sample.

SimpleCountingIdlingResource 代码 使用AtomicInteger

public class SimpleCountingIdlingResource implements IdlingResource {    private final String mResourceName;    private final AtomicInteger counter = new AtomicInteger(0);    private volatile ResourceCallback resourceCallback;    public SimpleCountingIdlingResource(String resourceName){        mResourceName = checkNotNull(resourceName);    }    @Override    public String getName() {        return mResourceName;    }    @Override    public boolean isIdleNow() {        return counter.get() == 0;    }    @Override    public void registerIdleTransitionCallback(ResourceCallback callback) {        this.resourceCallback = callback;    }    public void increment(){        counter.getAndIncrement();    }    public void decrement(){        int counterVal = counter.decrementAndGet();        if(counterVal == 0){            if(null != resourceCallback){                resourceCallback.onTransitionToIdle();            }        }        if (counterVal < 0) {            throw new IllegalArgumentException("Counter has been corrupted!");        }    }}

创建一个代理类EspressoIdlingResource, SimpleCountingIdlingResource 作为其静态成员。异步任务执行之前调用increment(),异步任务完成调用decrement(),在此处判断,若SimpleCountingIdlingResource 中的counter为0则应用变为idle状态,继续执行UI测试

public class EspressoIdlingResource {    private static final String RESOURCE = "GLOBAL";    private static SimpleCountingIdlingResource mCountingIdlingResource =            new SimpleCountingIdlingResource(RESOURCE);    public static void increment(){        mCountingIdlingResource.increment();    }    public static void decrement(){        mCountingIdlingResource.decrement();    }    public static IdlingResource getIdlingResource(){        return mCountingIdlingResource;    }}
原创粉丝点击