Durch die Automatisierung von Fokusnavigationstests wird sichergestellt, dass Ihre App eine einheitliche und vorhersehbare Nutzererfahrung auf Hardwaretastaturen, D-Pads und Barrierefreiheitstools bietet. Compose bietet integrierte Test-APIs, mit denen sich die Eingabe von Tasten simulieren und Fokusstatus prüfen lassen.
Fokustests einrichten
Verwenden Sie zum Schreiben von Fokus-Tests createComposeRule() aus der Compose-Testbibliothek:
@RunWith(AndroidJUnit4::class) class FocusNavigationTest { @get:Rule val composeTestRule = createComposeRule()
Fokusziele überprüfen
Sie können prüfen, ob ein UI-Element den Fokus erhalten kann, indem Sie darauf klicken oder den Fokus anfordern und dann seinen Status mit assertIsFocused() und assertIsNotFocused() bestätigen.
@Test fun interactiveElement_isFocusTarget() { composeTestRule.setContent { AppTheme { CardListScreen() } } val firstCard = composeTestRule.onNodeWithTag("card_1") val secondCard = composeTestRule.onNodeWithTag("card_2") // Focus the first element firstCard.performClick() firstCard.assertIsFocused() secondCard.assertIsNotFocused() }
Eindimensionale Fokusbewegung testen
Simulieren Sie das Drücken der Tabulatortaste und der Umschalttaste + Tabulatortaste mit performKeyInput, um zu prüfen, ob der Fokus in der Reihenfolge des Erscheinens durch die Benutzeroberfläche bewegt wird. Als Best Practice sollten Sie sowohl die Vorwärtsnavigation (Key.Tab) als auch die Rückwärtsnavigation (Key.Tab mit gedrückter Key.ShiftLeft) prüfen, um die Integrität der bidirektionalen Navigation sicherzustellen:
@Test fun tabKey_navigatesInAppearanceOrder() { composeTestRule.setContent { AppTheme { CardListScreen() } } val firstCard = composeTestRule.onNodeWithTag("card_1") val secondCard = composeTestRule.onNodeWithTag("card_2") val thirdCard = composeTestRule.onNodeWithTag("card_3") firstCard.performClick() firstCard.assertIsFocused() // Press Tab -> Moves to second card firstCard.performKeyInput { pressKey(Key.Tab) } secondCard.assertIsFocused() firstCard.assertIsNotFocused() // Press Tab -> Moves to third card secondCard.performKeyInput { pressKey(Key.Tab) } thirdCard.assertIsFocused() // Press Shift + Tab -> Moves backward to second card thirdCard.performKeyInput { withKeyDown(Key.ShiftLeft) { pressKey(Key.Tab) } } secondCard.assertIsFocused() }
Zweidimensionale Richtungsnavigation testen
Simulieren Sie Pfeiltasten oder Steuerkreuz-Richtungstasten mit Key.DirectionDown, Key.DirectionUp, Key.DirectionRight und Key.DirectionLeft.
@Test fun arrowKeys_moveFocusTwoDimensionallyWithoutWrap() { composeTestRule.setContent { AppTheme { GridLayoutScreen() } } val topLeftButton = composeTestRule.onNodeWithTag("btn_top_left") val bottomLeftButton = composeTestRule.onNodeWithTag("btn_bottom_left") topLeftButton.performClick() topLeftButton.assertIsFocused() // Down arrow moves focus downward to bottom-left button topLeftButton.performKeyInput { pressKey(Key.DirectionDown) } bottomLeftButton.assertIsFocused() // Directional keys do not wrap around: pressing Down on bottom element stays focused bottomLeftButton.performKeyInput { pressKey(Key.DirectionDown) } bottomLeftButton.assertIsFocused() }
Fokusverhalten von Textfeldern testen
Prüfen Sie, ob der Fokus in einzeiligen Textfeldern mit Tab weitergeleitet wird, während er in mehrzeiligen Textfeldern beibehalten wird:
@Test fun textField_handlesTabAccordingToLineLimits() { composeTestRule.setContent { AppTheme { FormScreen() } } val singleLineNode = composeTestRule.onNodeWithTag("single_line_field") val multiLineNode = composeTestRule.onNodeWithTag("multi_line_field") val submitButtonNode = composeTestRule.onNodeWithTag("submit_button") // Single-line field advances focus on Tab singleLineNode.performClick() singleLineNode.assertIsFocused() singleLineNode.performKeyInput { pressKey(Key.Tab) } multiLineNode.assertIsFocused() // Multi-line field keeps focus and inserts '\t' multiLineNode.performKeyInput { pressKey(Key.Tab) } multiLineNode.assertIsFocused() submitButtonNode.assertIsNotFocused() // Shift + Tab escapes multi-line field to previous target multiLineNode.performKeyInput { withKeyDown(Key.ShiftLeft) { pressKey(Key.Tab) } } singleLineNode.assertIsFocused() }
Empfehlungen für Sie
- Hinweis: Linktext wird angezeigt, wenn JavaScript deaktiviert ist
- Fokusziele
- Reihenfolge des Fokusdurchlaufs
- Fokus in Textfeldern
- Fokusziele für Gruppen