asc*_*sco 10 android ui-testing android-jetpack-compose
我想对使用Jetpack Compose 的Activity 进行 UI 测试。该文档提供了有关如何使用两种变体测试此类屏幕的一些信息:
@get:Rule val composeTestRule = createComposeRule()
Run Code Online (Sandbox Code Playgroud)
如果我不需要活动本身运行并且只想测试我的可组合项或
@get:Rule val composeTestRule = createAndroidComposeRule<MyActivity>()
Run Code Online (Sandbox Code Playgroud)
如果我确实需要这项活动。
在第二种情况下,我如何将带有 Extras 的 Intent 传递给活动?
我试过了:
@Before
fun setUp() {
composeTestRule.activity.intent = Intent().apply {
putExtra(
"someKey",
123
)
}
}
Run Code Online (Sandbox Code Playgroud)
但活动中的意图额外内容仍然为空。
composeTestRule.activity.intent设置的问题setUp()是活动已经在此时创建并且活动OnCreate已经被调用。因此,您正在设置的意图属性setUp()正在被设置,但为时已晚,无法在Activity.OnCreate.
不幸的是,Google 还没有创建像 那样的辅助方法createAndroidComposeRule<MyActivity>()。不过,可以编写一个辅助方法来解决:
class MyActivityTest {
@get:Rule
val composeRule = createEmptyComposeRule()
@Test
fun firstTimeLogIn() = composeRule.launch<MyActivity>(
onBefore = {
// Set up things before the intent
},
intentFactory = {
Intent(it, MyActivity::class.java).apply {
putExtra("someKey", 123)
}
},
onAfterLaunched = {
// Assertions on the view
onNodeWithText("Username").assertIsDisplayed()
})
}
Run Code Online (Sandbox Code Playgroud)
import android.app.Activity
import android.content.Context
import android.content.Intent
import androidx.compose.ui.test.junit4.ComposeTestRule
import androidx.compose.ui.test.junit4.createEmptyComposeRule
import androidx.test.core.app.ActivityScenario
import androidx.test.core.app.ApplicationProvider
/**
* Uses a [ComposeTestRule] created via [createEmptyComposeRule] that allows setup before the activity
* is launched via [onBefore]. Assertions on the view can be made in [onAfterLaunched].
*/
inline fun <reified A: Activity> ComposeTestRule.launch(
onBefore: () -> Unit = {},
intentFactory: (Context) -> Intent = { Intent(ApplicationProvider.getApplicationContext(), A::class.java) },
onAfterLaunched: ComposeTestRule.() -> Unit
) {
onBefore()
val context = ApplicationProvider.getApplicationContext<Context>()
ActivityScenario.launch<A>(intentFactory(context))
onAfterLaunched()
}
Run Code Online (Sandbox Code Playgroud)
@RunWith(AndroidJUnit4::class)
class MyActivityTest {
@get:Rule
val composeTestRule = createAndroidIntentComposeRule<MyActivity> {
Intent(it, MyActivity::class.java).apply {
putExtra("someKey", 123)
}
}
@Test
fun Test1() {
}
}
Run Code Online (Sandbox Code Playgroud)
import android.content.Context
import android.content.Intent
import androidx.activity.ComponentActivity
import androidx.compose.ui.test.junit4.AndroidComposeTestRule
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.rules.ActivityScenarioRule
/**
* Factory method to provide Android specific implementation of createComposeRule, for a given
* activity class type A that needs to be launched via an intent.
*
* @param intentFactory A lambda that provides a Context that can used to create an intent. A intent needs to be returned.
*/
inline fun <A: ComponentActivity> createAndroidIntentComposeRule(intentFactory: (context: Context) -> Intent) : AndroidComposeTestRule<ActivityScenarioRule<A>, A> {
val context = ApplicationProvider.getApplicationContext<Context>()
val intent = intentFactory(context)
return AndroidComposeTestRule(
activityRule = ActivityScenarioRule(intent),
activityProvider = { scenarioRule -> scenarioRule.getActivity() }
)
}
/**
* Gets the activity from a scenarioRule.
*
* https://androidx.tech/artifacts/compose.ui/ui-test-junit4/1.0.0-alpha11-source/androidx/compose/ui/test/junit4/AndroidComposeTestRule.kt.html
*/
fun <A : ComponentActivity> ActivityScenarioRule<A>.getActivity(): A {
var activity: A? = null
scenario.onActivity { activity = it }
return activity ?: throw IllegalStateException("Activity was not set in the ActivityScenarioRule!")
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3437 次 |
| 最近记录: |