2026/3/5 23:44:02
网站建设
项目流程
东莞专业网站建站设计,网站制作做网站,查询网址在哪里查,香包怎么做制作方法UI Automator: 丰富 Espresso Android UI 测试
添加几行代码来测试应用对设备旋转的反应
现在我们有了一个在不同屏幕上呈现不同布局的应用, 截图测试是验证布局的一个良好而有效的选择, 但我们如何在Espresso UI测试中测试应用在旋转设备时应用正确布局的能力呢?
我们需要…UI Automator: 丰富 Espresso Android UI 测试添加几行代码来测试应用对设备旋转的反应现在我们有了一个在不同屏幕上呈现不同布局的应用, 截图测试是验证布局的一个良好而有效的选择, 但我们如何在Espresso UI测试中测试应用在旋转设备时应用正确布局的能力呢?我们需要UI Automator。什么是 UI Automator?UI Automator 是为 Android 应用创建自动化UI测试的工具. 它是 Android 测试支持库的一部分. 它使我们能够在被测应用和不同应用之间执行任务, 因此对于全面集成和端到端测试而言, 它非常有价值。UI Automator 及其与 Espresso 的关系虽然 UI Automator 为 Android 界面测试提供了出色的工具, 但人们经常讨论它与 Espresso 的关系. 正如官方文档所建议的, UI Automator 和 Espresso 有一些功能重叠, 但 Espresso 有更多的同步机制, 因此对于常见的 UI 测试, 它是首选。范围UI Automator允许我们对设备上的任何可见元素执行操作, 包括系统应用和硬件按钮. 因此, 它非常适合测试扩展到被测应用之外的用户流。Espresso仅限于在被测应用内进行交互, 可对应用组件和状态进行更精细的控制。使用案例Espresso 擅长测试应用内的复杂交互, 如输入表单, 对话框和转换。UI Automator 更适合我们必须与多个应用进行交互, 或在通知或不同网络状态等系统条件下检查应用行为的情况。性能一般来说, Espresso 比 UI Automator 更快, 因为它直接与应用交互, 而UI Automator 可能会遇到一些问题。UI Automator 可能会出现延迟, 因为它会扫描整个屏幕来执行操作。结合使用 UI Automator 和 Espresso将 UI Automator 和 Espresso 结合使用可发挥这两个框架的优势. 例如, Espresso可用于在我们的应用中进行详细测试, 而UI Automator则可以处理像权限对话框这样的情况, 这是Android操作系统的一部分, 还可以帮助改变屏幕方向。这种组合为UI测试提供了一种全面的方法, 可确保应用特定功能的稳健性以及与系统级功能的集成。设置UI自动化程序假设我们的项目已为AndroidX测试正确设置. 要在项目中引入 UI Automator, 只需要一个新的依赖项。dependencies {...androidTestImplementation(androidx.test.uiautomator:uiautomator:2.3.0)}那么, 我们如何在测试中改变屏幕方向呢?鉴于我们已经有了一些 Espresso UI 测试, 我们只需获取一个UIDevice的实例, 然后就可以开始了。import androidx.test.uiautomator.UiDevice;import androidx.test.platform.app.InstrumentationRegistry;RunWith(AndroidJUnit4::class)class MainActivityTest {get:Ruleval composeTestRule createAndroidComposeRuleMainActivity()val uiDevice UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())Afterfun tearDown() {uiDevice.setOrientationNatural()}Testfun appNavigationLayoutTest() {with(mainActivityTestRobot) {// Rotate to landscapeuiDevice.setOrientationLeft()checkNavigationLayoutIsCorrect()// Rotate to portraituiDevice.setOrientationNatural()checkNavigationLayoutIsCorrect()}}} InstrumentationRegistry.getInstrumentation()是来自androidx.test.espresso包。我们如何运行与 WindowSizeClass 匹配的测试?由于我们可以在不同的设备/模拟器上运行UI测试, 因此我们的生产代码应正确计算WindowSizeClass, 并相应地渲染预期布局. 如何确保使用正确的测试集来测试相应的屏幕尺寸/布局?我们可以在测试中使用上文提到的InstrumentationRegistry来确定设备屏幕分辨率. 使用WindowSizeClass库中的WindowSizeClass.calculateFromSize(...)方法, 我们可以计算出当前的WindowSizeClass, 并有条件地针对该屏幕尺寸运行一组测试。import androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSizeClassApiimport androidx.compose.material3.windowsizeclass.WindowSizeClassimport androidx.compose.material3.windowsizeclass.WindowWidthSizeClassOptIn(ExperimentalMaterial3WindowSizeClassApi::class)fun getWindowSizeClass(): WindowSizeClass {val metrics InstrumentationRegistry.getInstrumentation().targetContext.resources.displayMetricsval widthPx metrics.widthPixelsval heightPx metrics.heightPixelsval density metrics.densityval widthDp widthPx / densityval heightDp heightPx / densityreturn WindowSizeClass.calculateFromSize(size DpSize(width widthDp.dp, height heightDp.dp))}Testfun checkNavigationLayoutIsCorrect() {// ...val windowWidthSizeClass getWindowSizeClass().widthSizeClassif (windowWidthSizeClass WindowWidthSizeClass.Compact) {assertNavigationBarIsDisplayed()} else {assertNavigationRailIsDisplayed()}// ...} 我们在生产代码中使用的calculateWindowSizeClass()只能在可组合函数中运行, 因此我采用了这种变通方法。触发下拉刷新的另一种方法使用 Espresso, 我们可以使用.performTouchInput来触发一个swipeDown操作, 从而在我们的 Jetpack Compose UI 上模拟拉动刷新操作。例如:...onNodeWithContentDescription(label pull_to_refresh).performTouchInput {swipeDown(startY 0f,endY 500f,durationMillis 1_000,)}....这要求我们在向下滑动之前首先找到一个现有的节点。要使用 UI Automator 创建更逼真的下拉刷新测试场景, 我们可以直接在屏幕上模拟轻扫动作, 而无需先定位特定的UI元素. 这种方法可以模拟用户在屏幕上的任何位置自然地执行轻扫手势来启动拉动刷新, 而无需考虑具体的UI布局或元素位置。val device UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())// Get the screen sizeval screenWidth device.displayWidthval screenHeight device.displayHeight// Calculate start and end positions for the swipe gestureval startX screenWidth / 2 // Swipe from middle of the screen widthval startY screenHeight / 4 // Start swipe from 1/4th down the screenval endX startX // End swipe at the same X-coordinateval endY startY (screenHeight / 2) // End swipe halfway down the screen// Perform the swipe gesturedevice.swipe(startX, startY, endX, endY, 50) // 50 steps to make the swipe smooth 作为折衷, 轻扫动作需要更长的时间. 由于每一步的执行时间被控制在 5 毫秒, 因此在 100 步的情况下, 轻扫动作需要大约 1/2 秒才能完成。使用 UI Automator 测试通知如果你还在阅读, 那么让我们将 UI Automator 集成到 Espresso UI 测试中, 看看还有哪些可能的用例。处理系统通知并与之交互是 UI Automator 的另一个亮点, 因为它可以在测试应用的上下文之外进行交互。Testfun checkNotifcationMessage() {val device UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())device.openNotification()// Assuming the notification has text content New Messageval notification device.findObject(UiSelector().textContains(New Message))if (notification.exists() notification.isEnabled) {notification.click()// Espresso tests to check app behaviour after clicking the notification}}切换飞行模式--UI Automator 执行 Shell 命令的强大功能在 UI 测试中模拟实际的 UI 操作来更改某些设备设置具有挑战性, 比如切换飞行模式。为此, UI Automator 提供了executeShellCommand()方法。Testfun checkThingsShouldWorkInAirplaneMode() {val device UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())// Command to enable airplane modedevice.executeShellCommand(settings put global airplane_mode_on 1)// Command to refresh the systems airplane mode statedevice.executeShellCommand(am broadcast -a android.intent.action.AIRPLANE_MODE --ez state true)// Add a delay or wait for the state to change// Test code to verify app behavior with no network// Command to disable airplane modedevice.executeShellCommand(settings put global airplane_mode_on 0)device.executeShellCommand(am broadcast -a android.intent.action.AIRPLANE_MODE --ez state false)}注意事项和权限权限:确保我们的测试设置和环境允许执行这些操作. 修改全局设置需要WRITE_SECURE_SETTINGS权限, 非 root 设备上的普通应用无法获得该权限。已 root 设备和模拟器:在已 root 设备或模拟器上运行此类测试更为直接, 因为我们可以更好地控制设备设置。影响:请注意使用此类命令的广泛影响. 更改设备设置会影响测试中的应用, 其他应用和设备的正常运行。 对于网络测试, 在可能的情况下, 在控制的测试环境中使用网络模拟可能仍是首选, 以保持一致性并便于设置。总结将 UI Automator 与 Espresso 集成是增强 Android UI 测试的绝佳方法. 它使我们能够在测试中模拟真实世界的场景, 如设备旋转和系统通知。这种工具组合使我们能够超越应用的边界进行测试, 并确保我们的应用在各种条件下的表现符合预期。只需添加几行代码, 我们就能进行更彻底, 更全面的测试, 确保我们的应用符合现代可用性标准, 并提供卓越的用户体验。感谢每一个认真阅读我文章的人礼尚往来总是要有的虽然不是什么很值钱的东西如果你用得到的话可以直接拿走这些资料对于【软件测试】的朋友来说应该是最全面最完整的备战仓库这个仓库也陪伴上万个测试工程师们走过最艰难的路程希望也能帮助到你!有需要的小伙伴可以点击下方小卡片领取