如何断言 next started activity 用于可组合测试?
How to assert next started activity for a composable test?
我有一个带有按钮的可组合项,可以启动其中一个本机活动(Google 设置)。
要在撰写之前对此进行测试(使用 Robolectric),我会做这样的事情:
我的测试:
@Test
fun `MyFragment - when button clicked - starts activity`() {
// ...
val shadowActivity: ShadowActivity = Shadow.extract(activity)
val nextStartedActivity = shadowActivity.nextStartedActivity
assertNotNull(nextStartedActivity)
assertEquals(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, nextStartedActivity.action)
}
使用组合测试(不使用 activity 场景)是不同的。没有 activity 句柄,只有 composeTestRule:
我的测试:
// ...
private val buttonNode get() = composeTestRule.onNodeWithContentDescription("Button")
@Test
fun `MyComposableToTest - when button clicked - starts activity`() {
composeTestRule.setContent {
MyComposableToTest()
}
buttonNode.assertExists().assertHasClickAction().assertIsEnabled().performClick()
// No possibility to get current activity
}
如何断言在测试可组合项时启动了一个新的 activity?
一些上下文:
- Android Gradle 插件 7.0.3
- Robolectric 4.7.3
- 编写 1.1.0-beta04
您可以像这样从 ComposeContentTestRule 获取上下文:
lateinit var context : Context
composeTestRule.setContent {
context = LocalContext.current
MyComposableToTest()
}
然后断言下一个开始activity
val shadowActivity: ShadowActivity = Shadow.extract(context as ComponentActivity)
val nextStartedActivity = shadowActivity.nextStartedActivity
assertEquals(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, nextStartedActivity.action)
这就是我为仪器测试所做的(不使用 Robolectric)。
build.gradle[.kts]:
androidTestImplementation("androidx.test.espresso:espresso-intents:3.4.0")
测试class(在src/androidTest/...目录下):
import androidx.test.espresso.intent.Intents
import androidx.test.espresso.intent.Intents.intended
import androidx.test.espresso.intent.matcher.IntentMatchers.hasComponent
// ...
@RunWith(AndroidJUnit4::class)
class MainActivityInstrumentedTest {
@get:Rule val composeTestRule = createAndroidComposeRule<MainActivity>()
@Test fun testTheIntent() {
Intents.init() // IMPORTANT (to be able to use "intended" function)
composeTestRule.setContent {
MyAppTheme {
MainScreen()
}
}
composeTestRule.onNodeWithText("My Button").performClick()
intended(hasComponent(MySecondActivity::class.java.name))
Intents.release()
}
}
我有一个带有按钮的可组合项,可以启动其中一个本机活动(Google 设置)。 要在撰写之前对此进行测试(使用 Robolectric),我会做这样的事情:
我的测试:
@Test
fun `MyFragment - when button clicked - starts activity`() {
// ...
val shadowActivity: ShadowActivity = Shadow.extract(activity)
val nextStartedActivity = shadowActivity.nextStartedActivity
assertNotNull(nextStartedActivity)
assertEquals(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, nextStartedActivity.action)
}
使用组合测试(不使用 activity 场景)是不同的。没有 activity 句柄,只有 composeTestRule:
我的测试:
// ...
private val buttonNode get() = composeTestRule.onNodeWithContentDescription("Button")
@Test
fun `MyComposableToTest - when button clicked - starts activity`() {
composeTestRule.setContent {
MyComposableToTest()
}
buttonNode.assertExists().assertHasClickAction().assertIsEnabled().performClick()
// No possibility to get current activity
}
如何断言在测试可组合项时启动了一个新的 activity?
一些上下文:
- Android Gradle 插件 7.0.3
- Robolectric 4.7.3
- 编写 1.1.0-beta04
您可以像这样从 ComposeContentTestRule 获取上下文:
lateinit var context : Context
composeTestRule.setContent {
context = LocalContext.current
MyComposableToTest()
}
然后断言下一个开始activity
val shadowActivity: ShadowActivity = Shadow.extract(context as ComponentActivity)
val nextStartedActivity = shadowActivity.nextStartedActivity
assertEquals(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, nextStartedActivity.action)
这就是我为仪器测试所做的(不使用 Robolectric)。
build.gradle[.kts]:
androidTestImplementation("androidx.test.espresso:espresso-intents:3.4.0")
测试class(在src/androidTest/...目录下):
import androidx.test.espresso.intent.Intents
import androidx.test.espresso.intent.Intents.intended
import androidx.test.espresso.intent.matcher.IntentMatchers.hasComponent
// ...
@RunWith(AndroidJUnit4::class)
class MainActivityInstrumentedTest {
@get:Rule val composeTestRule = createAndroidComposeRule<MainActivity>()
@Test fun testTheIntent() {
Intents.init() // IMPORTANT (to be able to use "intended" function)
composeTestRule.setContent {
MyAppTheme {
MainScreen()
}
}
composeTestRule.onNodeWithText("My Button").performClick()
intended(hasComponent(MySecondActivity::class.java.name))
Intents.release()
}
}