Android Espresso自动化聊天机器人:如何等待指定文本出现?
解决Espresso等待聊天机器人回复文本的问题
嘿,我太懂你为啥不想用Thread.sleep()——硬等固定时间真的太不靠谱了,要么平白浪费时间,要么异步内容还没加载完就超时,Espresso本身就有更优雅的方案来等指定文本出现!
核心思路:让Espresso基于条件等待
Espresso默认会自动等待视图可见、可交互,但如果是聊天机器人这种异步加载的内容(比如调用接口后才返回的回复),我们需要分两种情况处理:
情况1:文本所在视图已在布局中,仅内容动态更新
如果聊天消息的控件本来就在界面上,只是机器人回复后文本才变化,直接用onView()配合匹配器和断言就行,Espresso会自动等待直到条件满足(默认超时4秒,也可以自定义):
@Test public void loginAndWaitForBotReply() { // 先完成登录流程:输入账号、点击登录 onView(allOf(withId(R.id.text_edit_field), isDisplayed())) .perform(typeText("你的账号"), closeSoftKeyboard()); onView(withId(R.id.login_button)) .perform(click()); // 等待聊天窗口出现指定的机器人回复文本 onView(allOf(withId(R.id.chat_message_text), isDisplayed())) .check(matches(withText("机器人的回复内容"))); }
这里的withText("xxx")就是指定要等待的文本,check(matches(...))会让Espresso一直等,直到视图的文本符合预期,或者超时抛出异常。
情况2:异步加载场景(比如机器人需要调用接口返回回复)
如果机器人的回复是通过网络请求、后台任务这类异步操作生成的,Espresso不知道什么时候操作完成,这时候需要用IdlingResource来告诉Espresso:“嘿,异步操作完成啦,可以继续测试了”。
步骤1:自定义一个简单的IdlingResource
public class BotReplyIdlingResource implements IdlingResource { private ResourceCallback mCallback; private boolean mIsIdle = false; @Override public String getName() { return "BotReplyIdlingResource"; } @Override public boolean isIdleNow() { return mIsIdle; } @Override public void registerIdleTransitionCallback(ResourceCallback callback) { mCallback = callback; } // 在你的业务代码里,机器人回复完成后调用这个方法 public void setBotReplyReceived() { mIsIdle = true; if (mCallback != null) { mCallback.onTransitionToIdle(); } } }
步骤2:在测试中注册和使用IdlingResource
@Rule public ActivityTestRule<LoginActivity> mActivityTestRule = new ActivityTestRule<>(LoginActivity.class); private BotReplyIdlingResource mBotIdlingResource; @Before public void setUp() { // 从Activity中获取我们定义的IdlingResource(需要你在LoginActivity里提供获取方法) LoginActivity activity = mActivityTestRule.getActivity(); mBotIdlingResource = activity.getBotReplyIdlingResource(); // 注册到Espresso if (mBotIdlingResource != null) { Espresso.registerIdlingResources(mBotIdlingResource); } } @Test public void loginActivityTest() { // 执行登录操作... // 等待机器人回复,这时候Espresso会等到IdlingResource标记为空闲才继续 onView(allOf(withId(R.id.chat_message_text), isDisplayed())) .check(matches(withText("预期的机器人回复"))); } @After public void tearDown() { // 测试结束后注销IdlingResource if (mBotIdlingResource != null) { Espresso.unregisterIdlingResources(mBotIdlingResource); } }
补充:第三方库的IdlingResource
如果你的项目用了Retrofit、OkHttp或者WorkManager这类组件,其实有现成的IdlingResource可以用,比如OkHttp3IdlingResource,不用自己写,直接集成就行。
最后提醒
千万别再用Thread.sleep()啦,Espresso的条件等待机制只会等必要的时间,测试稳定性和效率都会高很多!
内容的提问来源于stack exchange,提问作者Anna Puskarjova
相关产品推荐
相关产品推荐

