일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- appbar
- Navigation
- binding
- scroll
- activity
- DART
- 앱바
- Button
- textfield
- Kotlin
- tabbar
- LifeCycle
- 테스트
- intent
- android
- livedata
- TEST
- 안드로이드
- Compose
- Dialog
- data
- textview
- CustomScrollView
- drift
- 앱
- viewmodel
- Coroutines
- 계측
- ScrollView
- Flutter
- Today
- Total
Study Record
[안드로이드] 간단한 계측 테스트 실행해보기 본문
😶 계측 테스트?
Android 개발에서 앱을 만들고 실행 테스트를 할 때 직접 사람이 수동으로 앱을 설치하여 테스트할 수 있지만 개발자가 특정 코드가 적절하게 작동하는지 코드로 자동화된 테스트를 할 수 있다.
자동화된 테스트를 하는 2가지 유형이 있는데 바로, 단위 테스트와 계측 테스트이다. 이 중에서 계측 테스트는 사용자 인터페이스(UI, 화면 테스트) 테스트를 하며 수명주기 및 플랫폼 API 와 서비스에 종속된 앱 일부를 테스트할 수 있다. 직접 테스트할 기기가 필요 없는 단위 테스트와 달리 계측 테스트는 기기가 필요하다.
Android 에서 계측 테스트를 실행하면 실제 테스트 코드는 일반 Android 앱과 마찬가지로 자체 테스트 APK 에 빌드된다.
😶 계측 테스트 디렉터리 만들기
계측 테스트는 위 그림과 같이 (androidTest) 디렉터리에서 진행한다. 만약 이 디렉터리가 존재하지 않는다면 다음과 같은 과정으로 새로 생성할 수 있다.
먼저, 프로젝트 단위를 Android 에서 Project 로 변경한 뒤 app/src 경로에 새로운 디렉터리를 만든다.
새로운 디렉터리 이름을 androidTest\java 로 선택하고 디렉터리를 만든다.
java 디렉터리를 만들고 Package 를 생성한다.
Package 이름은 각 프로젝트의 최상위 Package 이름으로 하는데 예를 들어, 밑의 예시처럼 com.example.tiptime 이라는 Package 구조를 가지고 있다면 똑같이 android\java 디렉터리의 패키지도 com.example.tiptime 로 한다.
프로젝트 단위를 Project 에서 Android 로 변경하면 (androidTest) 디렉터리가 보인다.
😶 계측 테스트 시 필요한 것
계측 테스트는 사용자 인터페이스(UI 화면)를 테스트하며 실제 기기가 있어야 한다.
개발자가 코드로 계측 테스트를 작성하기 위해서는 사람이 수동으로 사용자 인터페이스를 클릭하는 것이 아니기 때문에 테스트를 실행해 주는 '계측 실행기'와 테스트가 실행된 시점에 UI 구성요소들과 상호작용할 수 있도록 도와주는 'Espresso' 라이브러리가 필요하다.
Gradle 에 종속 항목에 추가한다.
dependencies {
...
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
...
}
😶 계측 테스트를 위한 간단한 앱 소개
EditText 에 사용자가 글을 입력하고 Calculate 버튼을 누르면 입력한 글이 몇 글자인지 표시해 주는 간단한 앱이다.
<EditText
android:id="@+id/count_edit_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:inputType="text"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<Button
android:id="@+id/count_button"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/calculate"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/count_edit_text" />
<TextView
android:id="@+id/count_result_text"
style="@style/Widget.test2.TextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/count_button" />
😶 계측 테스트 코드 작성하기
* 테스트 시나리오는 랜덤 길이의 텍스트를 editText 에 입력 후 Calculate 버튼을 눌렀을 때 텍스트 길이를 보여주는 TextView 에서 잘 보여주는지 확인하는 과정을 5번 정도 반복하여 테스트한다.
먼저 계측 테스트를 작성을 위한 클래스를 androidTest 디렉터리 아래에 CalculateTest 클래스를 만들었다.
1. 계측 테스트는 기기나 애뮬레이터에서 테스트를 실행하는 테스트 실행기가 필요한데 여러가지 실행기 중 AndroidJUnit4 를 사용해보려 한다. 간단하게 클래스에 다음과 같은 어노테이션을 단다.
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class CalculateTest {
}
2. 테스트를 진행하기 전 먼저 해당 Activity 가 실행되어야 한다. 따라서,
ActivityScenarioRule 함수로 실행할 액티비티를 입력하고 @get:Rule 어노테이션을 단다. @get:Rule 는 해당 클래스의 모든 테스트 전에 실행되어야 한다고 알리는 역할을 한다.
import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Rule
import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class CalculateTest {
@get:Rule()
val activity = ActivityScenarioRule(MainActivity::class.java)
}
3. Espresso 라이브러리를 사용하면 UI 구성요소와 상호작용할 수 있다. 현재 테스트 시나리오에 필요한 Espresso 라이브러리의 함수들을 소개하면 다음과 같다.
먼저, UI 구성요소를 가져오려면 onView() 함수를 사용한다. onView() 함수의 매개변수로 ViewMatcher 를 받는데 이는 withId() 함수를 사용하여 UI 의 id 값을 사용하여 가져올 수 있다.
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.matcher.ViewMatchers.withId
onView(withId(R.id.count_edit_text))
onView() 는 객체로 받은 UI 구성요소의 ViewInteraction 을 반환한다. ViewInteraction 은 perform() 함수를 사용하여 여러하지 상호작용을 할 수 있다.
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.action.ViewActions.typeText
import androidx.test.espresso.matcher.ViewMatchers.withId
// 텍스트 입력하고 키보드 내리기
onView(withId(R.id.count_edit_text))
.perform(typeText(randomText))
.perform(ViewActions.closeSoftKeyboard())
// 클릭하기
onView(withId(R.id.count_button))
.perform(click())
EditText 에는 typeText() 로 텍스트를 입력할 수 있고 closeSoftkeyboard() 로 키보드를 내릴 수 있다. click() 함수는 버튼을 클릭하는 효과를 준다.
EditText 에 입력된 텍스트의 길이를 알려주는 TextView 의 값과 예상값이 같은지 확인하는 과정이 필요하다. 이때 check() 함수를 사용한다.
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
onView(withId(R.id.count_result_text))
.check(matches(withText("매치할 텍스트")))
4. 테스트를 실행할 함수에는 @Test 어노테이션을 달아준다.
완성된 코드는 다음과 같다.
package com.example.test2
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.action.ViewActions.typeText
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class CalculateTest {
@get:Rule()
val activity = ActivityScenarioRule(MainActivity::class.java)
@Test
fun random_length_text() {
// 랜덤 텍스트 생성
val randomText = "A".repeat((1..10).random())
// EditText 에 텍스트 입력
onView(withId(R.id.count_edit_text))
.perform(typeText(randomText))
.perform(ViewActions.closeSoftKeyboard())
// Calculate 버튼 클릭
onView(withId(R.id.count_button))
.perform(click())
// 예상 값과 테스트 값 비교
onView(withId(R.id.count_result_text))
.check(matches(withText(randomText.length.toString())))
}
}
5. 이제 테스트 클래스를 실행해주면 자동으로 앱을 실행하여 EditText 에 입력하고 버튼을 클릭하는 과정까지 볼 수 있다. 이렇게 사람이 수동으로 앱을 클릭하고 실행하지 않고 개발자가 코드로 자동으로 기기를 실행하고 결과를 볼 수 있다.
클래스 옆의 플레이 아이콘을 클릭하면 해당 클래스를 실행시킬 수 있다.
테스트 결과
'안드로이드' 카테고리의 다른 글
[안드로이드] 어노테이션 (0) | 2023.07.18 |
---|---|
[안드로이드] RecyclerView 살펴보기 (0) | 2023.07.18 |
[안드로이드] 아이콘, 적응형 앱 아이콘 (0) | 2023.07.12 |
[안드로이드] RadioButton, RadioGroup 살펴보기 (0) | 2023.07.11 |
[안드로이드] 문자열 따로 저장하고 불러오기(strings.xml) (0) | 2023.07.03 |