UI 요소와 상호작용하는 방법에는 크게 세 가지가 있습니다.
- 파인더를 사용하면 요소 (또는 시맨틱 트리의 노드)를 하나 이상 선택하여 어설션을 만들거나 작업을 실행할 수 있습니다.
- 어설션은 요소가 있는지 또는 특정 속성을 보유하는지 확인하는 데 사용됩니다.
- 작업은 클릭이나 기타 동작과 같은 시뮬레이션된 사용자 이벤트를 요소에 삽입합니다.
이러한 API의 일부는 시맨틱 트리에서 노드를 하나 이상 참조하는 SemanticsMatcher
를 허용합니다.
파인더
onNode
와 onAllNodes
를 사용하여 각각 노드를 하나나 여러 개 선택할 수 있지만 onNodeWithText
, onNodeWithContentDescription
등 가장 일반적인 검색에 편의 파인더를 사용할 수도 있습니다. Compose 테스트 요약본에서 전체 목록을 찾아볼 수 있습니다.
단일 노드 선택
composeTestRule.onNode(<<SemanticsMatcher>>, useUnmergedTree = false): SemanticsNodeInteraction
// Example
composeTestRule
.onNode(hasText("Button")) // Equivalent to onNodeWithText("Button")
여러 노드 선택
composeTestRule
.onAllNodes(<<SemanticsMatcher>>): SemanticsNodeInteractionCollection
// Example
composeTestRule
.onAllNodes(hasText("Button")) // Equivalent to onAllNodesWithText("Button")
병합되지 않은 트리
일부 노드는 하위 요소의 시맨틱 정보를 병합합니다. 예를 들어 다음과 같이 텍스트 요소가 두 개 있는 버튼은 텍스트 요소 라벨을 병합합니다.
MyButton {
Text("Hello")
Text("World")
}
테스트에서 printToLog()
를 사용하여 시맨틱 트리를 표시합니다.
composeTestRule.onRoot().printToLog("TAG")
이 코드는 다음 출력을 생성합니다.
Node #1 at (...)px
|-Node #2 at (...)px
Role = 'Button'
Text = '[Hello, World]'
Actions = [OnClick, GetTextLayoutResult]
MergeDescendants = 'true'
병합되지 않은 트리가 될 요소의 노드를 일치시켜야 한다면 다음과 같이 useUnmergedTree
를 true
로 설정하면 됩니다.
composeTestRule.onRoot(useUnmergedTree = true).printToLog("TAG")
이 코드는 다음 출력을 생성합니다.
Node #1 at (...)px
|-Node #2 at (...)px
OnClick = '...'
MergeDescendants = 'true'
|-Node #3 at (...)px
| Text = '[Hello]'
|-Node #5 at (83.0, 86.0, 191.0, 135.0)px
Text = '[World]'
useUnmergedTree
매개변수는 모든 파인더에서 사용할 수 있습니다. 예를 들어 여기서는 onNodeWithText
파인더에서 사용됩니다.
composeTestRule
.onNodeWithText("World", useUnmergedTree = true).assertIsDisplayed()
어설션
하나 이상의 매처가 있는 파인더가 반환한 SemanticsNodeInteraction
에서 assert()
를 호출하여 어설션을 확인합니다.
// Single matcher:
composeTestRule
.onNode(matcher)
.assert(hasText("Button")) // hasText is a SemanticsMatcher
// Multiple matchers can use and / or
composeTestRule
.onNode(matcher).assert(hasText("Button") or hasText("Button2"))
assertExists
, assertIsDisplayed
, assertTextEquals
등 가장 일반적인 어설션에 편의 함수를 사용할 수도 있습니다.
Compose 테스트 요약본에서 전체 목록을 찾아볼 수 있습니다.
다음과 같이 노드 컬렉션에서 어설션을 확인하는 함수도 있습니다.
// Check number of matched nodes
composeTestRule
.onAllNodesWithContentDescription("Beatle").assertCountEquals(4)
// At least one matches
composeTestRule
.onAllNodesWithContentDescription("Beatle").assertAny(hasTestTag("Drummer"))
// All of them match
composeTestRule
.onAllNodesWithContentDescription("Beatle").assertAll(hasClickAction())
작업
노드에 작업을 삽입하려면 다음과 같이 perform…()
함수를 호출합니다.
composeTestRule.onNode(...).performClick()
다음은 몇 가지 작업의 예입니다.
performClick(),
performSemanticsAction(key),
performKeyPress(keyEvent),
performGesture { swipeLeft() }
Compose 테스트 요약본에서 전체 목록을 찾아볼 수 있습니다.
매처
Compose 코드를 테스트하는 데 사용할 수 있는 다양한 매처가 있습니다.
계층적 매처
계층적 매처를 사용하면 시맨틱 트리에서 위 또는 아래로 이동하고 일치를 실행할 수 있습니다.
fun hasParent(matcher: SemanticsMatcher): SemanticsMatcher
fun hasAnySibling(matcher: SemanticsMatcher): SemanticsMatcher
fun hasAnyAncestor(matcher: SemanticsMatcher): SemanticsMatcher
fun hasAnyDescendant(matcher: SemanticsMatcher): SemanticsMatcher
다음은 이러한 매처가 사용되는 몇 가지 예입니다.
composeTestRule.onNode(hasParent(hasText("Button")))
.assertIsDisplayed()
선택기
테스트를 만드는 다른 방법은 일부 테스트를 더 읽기 쉽게 만들 수 있는 선택기를 사용하는 것입니다.
composeTestRule.onNode(hasTestTag("Players"))
.onChildren()
.filter(hasClickAction())
.assertCountEquals(4)
.onFirst()
.assert(hasText("John"))
Compose 테스트 요약본에서 전체 목록을 찾아볼 수 있습니다.
추가 리소스
- Android에서 앱 테스트: 기본 Android 테스트 방문 페이지에서는 테스트 기본사항과 기법을 더 폭넓게 살펴볼 수 있습니다.
- 테스트의 기본사항: Android 앱 테스트의 핵심 개념을 자세히 알아봅니다.
- 로컬 테스트: 일부 테스트는 자체 워크스테이션에서 로컬로 실행할 수 있습니다.
- 계측 테스트: 계측 테스트도 실행하는 것이 좋습니다. 즉, 기기에서 직접 실행되는 테스트입니다.
- 지속적 통합: 지속적 통합을 사용하면 테스트를 배포 파이프라인에 통합할 수 있습니다.
- 다양한 화면 크기 테스트: 사용자가 사용할 수 있는 기기가 많으므로 다양한 화면 크기를 테스트해야 합니다.
- Espresso: 뷰 기반 UI용이지만 Espresso 지식은 Compose 테스트의 일부 측면에도 유용할 수 있습니다.