Espresso-Intents 是 Espresso 的扩展程序,支持验证和 对由 Android 应用发出的 intent 进行存根 正在测试的应用其格式类似于 <ph type="x-smartling-placeholder"></ph> Mockito,但适用于 Android Intent。
如果您的应用将功能委托给其他应用或平台,您可以使用 Espresso-Intents 可以专注于您自己的应用的逻辑,同时假定其他应用 否则平台会正常运行借助 Espresso-Intents,您可以 并验证您的传出 intent,甚至可以提供桩响应来代替 实际意图响应。
在项目中添加 Espresso-Intents
在应用的 app/build.gradle
文件中,将以下代码行添加到
dependencies
:
androidTestImplementation 'androidx.test.espresso:espresso-intents:3.6.1'
androidTestImplementation('androidx.test.espresso:espresso-intents:3.6.1')
Espresso-Intents 仅与 Espresso 2.1+ 和 0.3+ Android 测试库,因此请务必也更新以下代码行:
androidTestImplementation 'androidx.test:runner:1.6.1'
androidTestImplementation 'androidx.test:rules:1.6.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'
androidTestImplementation('androidx.test:runner:1.6.1')
androidTestImplementation('androidx.test:rules:1.6.1')
androidTestImplementation('androidx.test.espresso:espresso-core:3.6.1')
编写测试规则
在编写 Espresso-Intents 测试之前,先设置 IntentsTestRule
。这是一个
是 ActivityTestRule
类的扩展,可让您轻松使用
功能界面测试中的 Espresso-Intents API。IntentsTestRule
会初始化
在每个带有 @Test
注解的测试和发布之前运行 Espresso-Intents
Espresso-Intents。
以下代码段是 IntentsTestRule
的一个示例:
@get:Rule
val intentsTestRule = IntentsTestRule(MyActivity::class.java)
@Rule
public IntentsTestRule<MyActivity> intentsTestRule =
new IntentsTestRule<>(MyActivity.class);
匹配
Espresso-Intents 能够根据以下结果拦截传出 intent 特定匹配条件,这些条件是使用 Hamcrest 匹配器定义的。哈姆克雷斯特 您可以:
- 使用现有的 intent 匹配器:这是最简单的选项,应该几乎总是处于此状态 资源。
- 实现您自己的 intent 匹配器:这是最灵活的选项。更多详情请参阅 详见“编写自定义匹配器”部分内 Hamcrest 教程。
Espresso-Intents 提供 intended()
和 intending()
方法,用于 intent 验证和
和打桩。两者都以 Hamcrest Matcher<Intent>
对象作为
参数。
以下代码段展示了使用现有 intent 的 intent 验证 匹配启动浏览器的传出 intent 的匹配器:
assertThat(intent).hasAction(Intent.ACTION_VIEW)
assertThat(intent).categories().containsExactly(Intent.CATEGORY_BROWSABLE)
assertThat(intent).hasData(Uri.parse("www.google.com"))
assertThat(intent).extras().containsKey("key1")
assertThat(intent).extras().string("key1").isEqualTo("value1")
assertThat(intent).extras().containsKey("key2")
assertThat(intent).extras().string("key2").isEqualTo("value2")
assertThat(intent).hasAction(Intent.ACTION_VIEW);
assertThat(intent).categories().containsExactly(Intent.CATEGORY_BROWSABLE);
assertThat(intent).hasData(Uri.parse("www.google.com"));
assertThat(intent).extras().containsKey("key1");
assertThat(intent).extras().string("key1").isEqualTo("value1");
assertThat(intent).extras().containsKey("key2");
assertThat(intent).extras().string("key2").isEqualTo("value2");
验证 intent
Espresso-Intents 会记录尝试从
正在测试的应用使用 intended()
方法,该方法类似于
Mockito.verify()
,您可以断言已看到给定的 intent。不过,
除非您明确配置,否则 Espresso-Intents 不会对 intent 的响应打桩
实现这一目的。
以下代码段是一个示例测试,可进行验证,但不进行打桩 响应,即启动外部“手机”的传出 intent活动:
@Test fun validateIntentSentToPackage() {
// User action that results in an external "phone" activity being launched.
user.clickOnView(system.getView(R.id.callButton))
// Using a canned RecordedIntentMatcher to validate that an intent resolving
// to the "phone" activity has been sent.
intended(toPackage("com.android.phone"))
}
@Test
public void validateIntentSentToPackage() {
// User action that results in an external "phone" activity being launched.
user.clickOnView(system.getView(R.id.callButton));
// Using a canned RecordedIntentMatcher to validate that an intent resolving
// to the "phone" activity has been sent.
intended(toPackage("com.android.phone"));
}
打桩
使用 intending()
方法(类似于 Mockito.when()
),您可以
为使用其应用启动的 activity 提供桩响应
startActivityForResult()
。这对于外部活动
因为你既不能操纵外部 activity 的界面,
控制返回到被测 activity 的 ActivityResult
。
以下代码段实现了一个示例
activityResult_DisplaysContactsPhoneNumber()
测试,用于验证
用户发起“联系人”操作被测应用中的 activity,联系电话
编号:
构建要在启动特定 Activity 时返回的结果。通过 示例测试会拦截发送到“contacts”的所有 intent并把它们 使用结果代码返回有效
ActivityResult
的响应RESULT_OK
val resultData = Intent()
val phoneNumber = "123-345-6789"
resultData.putExtra("phone", phoneNumber)
val result = Instrumentation.ActivityResult(Activity.RESULT_OK, resultData)Intent resultData = new Intent();
String phoneNumber = "123-345-6789";
resultData.putExtra("phone", phoneNumber);
ActivityResult result =
new ActivityResult(Activity.RESULT_OK, resultData);指示 Espresso 提供桩结果对象来响应所有 调用“contacts”intent:
验证用于启动 activity 的操作是否产生了预期的 桩结果。在本示例中,示例测试会检查电话号码 返回 "123-345-6789", “联系人活动”:
下面是完整的 activityResult_DisplaysContactsPhoneNumber()
测试:
@Test fun activityResult_DisplaysContactsPhoneNumber() {
// Build the result to return when the activity is launched.
val resultData = Intent()
val phoneNumber = "123-345-6789"
resultData.putExtra("phone", phoneNumber)
val result = Instrumentation.ActivityResult(Activity.RESULT_OK, resultData)
// Set up result stubbing when an intent sent to "contacts" is seen.
intending(toPackage("com.android.contacts")).respondWith(result)
// User action that results in "contacts" activity being launched.
// Launching activity expects phoneNumber to be returned and displayed.
onView(withId(R.id.pickButton)).perform(click())
// Assert that the data we set up above is shown.
onView(withId(R.id.phoneNumber)).check(matches(withText(phoneNumber)))
}
@Test
public void activityResult_DisplaysContactsPhoneNumber() {
// Build the result to return when the activity is launched.
Intent resultData = new Intent();
String phoneNumber = "123-345-6789";
resultData.putExtra("phone", phoneNumber);
ActivityResult result =
new ActivityResult(Activity.RESULT_OK, resultData);
// Set up result stubbing when an intent sent to "contacts" is seen.
intending(toPackage("com.android.contacts")).respondWith(result);
// User action that results in "contacts" activity being launched.
// Launching activity expects phoneNumber to be returned and displayed.
onView(withId(R.id.pickButton)).perform(click());
// Assert that the data we set up above is shown.
onView(withId(R.id.phoneNumber)).check(matches(withText(phoneNumber)));
}
其他资源
如需详细了解如何在 Android 测试中使用 Espresso-Intents,请查阅 以下资源。
示例
- IntentsBasicSample:
intended()
和intending()
的基本用法。 - IntentsAdvancedSample 实例获取数据: 模拟用户使用相机获取位图。