1. 시작하기 전에
이전 Codelab에서는 활동 간 탐색에 관해 알아봤습니다. 이 Codelab에서는 계측 테스트를 사용하여 탐색을 테스트하는 다양한 접근 방식을 알아봅니다.
기본 요건
- Android 스튜디오에서 테스트 디렉터리를 만들어 보았습니다.
- Android 스튜디오에서 단위 테스트와 계측 테스트를 작성했습니다.
학습할 내용
- 계측 테스트를 사용하여 활동이나 프래그먼트 간의 물리적 탐색을 테스트하는 방법
필요한 항목
- Android 스튜디오가 설치된 컴퓨터
- Words 앱의 솔루션 코드
이 Codelab의 시작 코드 다운로드
이 Codelab에서는 Words 앱 솔루션 코드에 계측 테스트를 추가합니다.
이 Codelab의 코드를 가져와서 Android 스튜디오에서 열려면 다음을 실행합니다.
코드 가져오기
- 제공된 URL을 클릭합니다. 브라우저에서 프로젝트의 GitHub 페이지가 열립니다.
- 프로젝트의 GitHub 페이지에서 Code 버튼을 클릭하여 대화상자를 엽니다.
- 대화상자에서 Download ZIP 버튼을 클릭하여 컴퓨터에 프로젝트를 저장합니다. 다운로드가 완료될 때까지 기다립니다.
- 컴퓨터에서 파일을 찾습니다(예: Downloads 폴더).
- ZIP 파일을 더블클릭하여 압축을 해제합니다. 프로젝트 파일이 포함된 새 폴더가 만들어집니다.
Android 스튜디오에서 프로젝트 열기
- Android 스튜디오를 시작합니다.
- Welcome to Android Studio 창에서 Open an existing Android Studio project를 클릭합니다.
참고: Android 스튜디오가 이미 열려 있는 경우 File > New > Import Project 메뉴 옵션을 대신 선택합니다.
- Import Project 대화상자에서 압축 해제된 프로젝트 폴더가 있는 위치로 이동합니다(예: Downloads 폴더).
- 프로젝트 폴더를 더블클릭합니다.
- Android 스튜디오가 프로젝트를 열 때까지 기다립니다.
- Run 버튼 을 클릭하여 앱을 빌드하고 실행합니다. 예상대로 작동하는지 확인합니다.
- Project 도구 창에서 프로젝트 파일을 살펴보고 앱이 설정된 방식을 확인합니다.
2. 시작 앱 개요
Words 앱은 목록을 표시하는 홈 화면으로 구성되며 각 목록 항목은 알파벳 문자입니다. 문자를 클릭하면 클릭한 문자로 시작하는 단어 목록을 보여주는 화면으로 이동합니다.
3. 권장사항
Kotlin에서 함수 이름을 지정하는 일반적인 규칙은 함수 이름의 첫 번째 문자가 소문자이고 후속 단어의 첫 번째 문자가 대문자(예: myCamelCaseFunction()
)인 '카멜 표기법'을 사용하는 것입니다. 지금까지 작성한 테스트 메서드에서는 모두 소문자와 단어 사이에 밑줄(예: my_test_function()
)을 사용했습니다. 무엇을 테스트하는지 명시적으로 나타내기 위해 함수 이름이 상세하길 바랐기 때문입니다. 이렇게 하면 테스트에 실패할 경우 이름 자체에 실패한 항목이 명확하게 표시됩니다. Kotlin에서는 ``test function with spaces()
와 같이 메서드 이름을 백틱으로 래핑하는 경우 메서드 이름에 공백도 사용할 수 있습니다. 백틱은 작은따옴표와 다릅니다. 물결 표시(~)가 있는 키에서 확인할 수 있습니다. 이를 통해 오류가 발생할 때 식별하기 쉬운, 사람이 읽을 수 있는 함수 이름을 만들 수 있습니다.
그러나 이 접근 방식에는 주의할 점이 있습니다. 구현하려면 몇 가지 설정이 필요하다는 점입니다. 이 섹션은 선택사항입니다. 읽어보는 것이 좋지만 계측 테스트 디렉터리 만들기 섹션까지 단계를 따를 필요는 없습니다.
- 함수 이름에 공백을 사용하는 것은 Android에서 API 30을 타겟팅하는 경우에만 작동합니다. 그 외 경우에는 다음과 같은 오류가 발생합니다.
API를 변경하려면 app/build.gradle로 이동하여 minSdkVersion
및 targetSdkVersion
을 수정합니다.
이 경우 targetSdkVersion
은 요구사항인 30
으로 설정합니다. 그러나 minSdkVersion
은 19
이므로 함수 이름에 공백을 허용하려면 30
으로 변경해야 합니다. 이는 실용적이지 않을 때도 있으므로 '있으면 좋은' 기능이긴 하나 요구사항은 아닙니다.
- API 30을 타겟팅하더라도 메서드에 'Identifier not allowed in Android Projects'라는 메시지와 함께 빨간색으로 밑줄이 그어져 있는 것을 확인할 수 있습니다.
테스트는 여전히 완료될 때까지 실행되지만 밑줄을 제거하려면 Android 스튜디오 설정/환경설정으로 이동하여 Editor -> Inspections -> Kotlin Android -> Illegal Android Identifier -> Tests로 이동합니다.
그런 다음 Tests 체크박스를 선택 해제하고 Apply 또는 OK를 클릭합니다.
이제 메서드 이름을 백틱으로 묶는 한 메서드에 더 이상 빨간색 밑줄이 표시되지 않습니다.
4. 테스트 디렉터리 만들기
Words 앱의 계측 테스트 디렉터리를 만듭니다.
5. 계측 테스트 클래스 만들기
NavigationTests.kt
라는 새 클래스를 만듭니다.
6. 탐색 테스트 작성
- 테스트 실행기를 지정합니다.
@RunWith(AndroidJUnit4::class)
- 그런 다음 기본 활동을 실행합니다.
@get:Rule
val activity = ActivityScenarioRule(MainActivity::class.java)
- 이제
navigate_to_word()
라는 메서드를 만듭니다.
@Test
fun navigate_to_word() {
}
navigate_to_word()
메서드에서 선택할 목록 항목을 정해야 합니다. 선택하는 항목은 임의적이며 여러 가지 방법으로 실행할 수 있습니다. 어댑터 내의 위치에 따라 항목을 선택하거나, 포함된 텍스트(문자)에 따라 항목을 선택할 수 있습니다.RecyclerView
와 직접 상호작용하려면 다음 종속 항목이 필요합니다.
dependencies {
...
androidTestImplementation
‘com.android.support.test.espresso:espresso-contrib:3.0.2'
}
반면 텍스트로 항목을 선택하려면 이전 Codelab에서 사용한 withText()
메서드를 사용하면 됩니다. 이 접근 방식을 사용하는데 텍스트가 화면에 표시되지 않으면 테스트가 실패한다는 점에 유의해야 합니다. 이 내용은 나중에 살펴보겠습니다.
- 두 가지 방법 모두로 시도할 수 있는지 확인합니다. UI 구성요소가 검색되면 이를 클릭하는 것이 목표입니다.
문자 'C'의 항목을 예로 클릭하는 의도로 두 접근 방식이 모두 여기에 표시됩니다.
onView(withText("C")).perform(click())
onView(withId(R.id.recycler_view))
.perform(RecyclerViewActions
.actionOnItemAtPosition<RecyclerView.ViewHolder>(2, click()))
잠시 시간을 내어 이 두 가지 접근 방식을 자세히 살펴보세요. 두 가지 방법 중 하나를 실행하고 에뮬레이터나 기기를 살펴보면 두 가지 모두 작동하는 것을 확인할 수 있습니다. RecyclerViewActions
를 사용하려면 코드가 더 많이 필요하지만 추가 작업 없이 항목을 클릭할 수 있다는 뚜렷한 이점이 있습니다. 첫 번째 접근 방식을 시도하되 문자 'C'를 'Z'로 변경하고 테스트를 다시 실행합니다. 다음 오류와 함께 테스트가 실패하는 것을 확인할 수 있습니다. androidx.test.espresso.NoMatchingViewException: No views in hierarchy found matching: with text: is "Z"
'Z'가 목록의 맨 끝에 있고 앱을 실행할 때 화면 밖에 있어서 스크롤해야 하기 때문입니다. RecyclerViewAction
접근 방식은 기본적으로 이를 처리합니다. 25
를 위치 값으로 전달해 보고 에뮬레이터나 기기를 확인합니다.
- 위의 예를 실행하면 다음 활동을 성공적으로 실행했음을 확인할 수 있지만, 어설션을 사용하여 이를 확인하고자 합니다. 앱 자체를 실행하고 지정된 목록 항목을 클릭하면 앱 바의 제목이 'Words That Start With __'라고 표시됩니다. 여기서 빈 공간은 클릭한 문자입니다. 이를 사용하여 탐색이 올바르게 작동했는지 확인할 수 있습니다. 올바른 문자열 뒤에 클릭한 문자가 표시되는지 어설션하기만 하면 됩니다. 이전 Codelab에서 유사한 어설션을 만들었으므로 직접 할 수 있는지 확인해 보세요.
onView(withText("Words That Start With C")).check(matches(isDisplayed()))
7. 개념 강의 및 권장사항
테스트에 사용되는 매우 중요한 용어에는 '거짓양성'과 '거짓음성' 두 가지가 있습니다.
'거짓양성'은 문제가 발생하여 테스트가 실패해야 함에도 테스트 결과가 통과로 나오는 경우입니다. 마찬가지로 '거짓음성'은 모든 항목이 올바르고 테스트에 통과해야 할 때 테스트 결과가 실패로 나오는 경우입니다.
위에서 작성한 테스트에서 찾고 있던 문자열을 하드 코딩했습니다. 코드 관점에서는 앱에서 했던 것처럼 문자열 리소스에서 문자열을 빌드하는 것이 더 깔끔합니다. 이는 일반 앱 코드에서와 약간 다르게 작동하지만 여전히 가능합니다. 그러나 이 방식으로 문자열을 빌드하면 잠재적으로 실패할 수 있습니다. 문자열 빌드가 기술적으로 비즈니스 로직이기 때문입니다. 테스트에서 문자열을 빌드하는 것이 앱 코드에서 실패한 것과 같은 방식으로 실패하면 거짓양성이 발생할 수 있습니다. 이는 두 코드가 모두 같은 문자열을 잘못 빌드하여 테스트의 잘못된 텍스트가 앱에 표시된 잘못된 텍스트와 일치하기 때문입니다. 따라서 문자열을 예상하는 값으로 하드 코딩하는 것이 더 좋습니다.
8. 솔루션 코드
9. 축하합니다
이 Codelab에서 배운 내용은 다음과 같습니다.
- 테스트를 위한 상세한 함수 이름을 만드는 방법을 알아봤습니다.
- 활동 또는 프래그먼트로 물리적 탐색을 테스트하는 방법을 알아봤습니다.
- '거짓양성'과 '거짓음성'에 관해 알아봤습니다.