반응형
안드로이드 개발에서 테스트는 애플리케이션의 품질을 보장하고 오류를 줄이는 데 중요한 역할을 합니다. 이 가이드에서는 Test-Driven Development(TDD)의 개념과 함께 Unit 테스트와 UI 테스트를 설정하고 실행하는 방법, 의존성 추가, 테스트 작성 시 주의사항 등을 단계별로 소개합니다.
1. 테스트와 TDD 개요
테스트 종류
Unit 테스트
- 정의: 개별 함수나 클래스의 논리를 테스트하는 데 중점을 둡니다.
- 목적: 빠르고 독립적인 테스트를 통해 비즈니스 로직을 검증합니다.
UI 테스트
- 정의: 사용자 인터페이스와 애플리케이션의 상호작용을 테스트합니다.
- 목적: 사용자가 애플리케이션과 상호작용할 때의 흐름을 확인하고 오류를 방지합니다.
TDD란?
- Test-Driven Development(테스트 주도 개발): 테스트 코드를 먼저 작성한 후, 이를 통과하는 최소한의 코드를 작성하는 개발 방식입니다.
- 장점:
- 높은 코드 품질 유지
- 디버깅 시간 단축
- 명확한 요구 사항 반영
2. 의존성 추가
Gradle 파일에 의존성 추가하기
Unit 테스트와 UI 테스트를 실행하려면 적절한 라이브러리를 추가해야 합니다.
build.gradle (모듈 레벨):
dependencies {
// Unit 테스트
testImplementation 'junit:junit:4.13.2'
testImplementation 'org.mockito:mockito-core:4.11.0'
// AndroidX Unit 테스트
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test:core:1.5.0'
// UI 테스트
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
androidTestImplementation 'androidx.test.espresso:espresso-intents:3.5.1'
}
3. TDD로 Unit 테스트 작성하기
TDD에서는 다음의 단계를 반복합니다:
- 실패하는 테스트 작성
- 테스트를 통과시키는 최소한의 코드 작성
- 코드 리팩토링
예제: Calculator 클래스 테스트
Calculator 클래스:
class Calculator {
fun add(a: Int, b: Int): Int {
return a + b
}
fun subtract(a: Int, b: Int): Int {
return a - b
}
}
테스트 코드:
import org.junit.Assert.assertEquals
import org.junit.Test
class CalculatorTest {
private val calculator = Calculator()
@Test
fun `add should return correct sum`() {
val result = calculator.add(2, 3)
assertEquals(5, result)
}
@Test
fun `subtract should return correct difference`() {
val result = calculator.subtract(5, 3)
assertEquals(2, result)
}
}
4. TDD로 UI 테스트 작성하기
UI 테스트는 src/androidTest/java 디렉토리에 작성하며, TDD 프로세스를 따릅니다.
예제: Login 화면 테스트
LoginActivity:
class LoginActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_login)
val button = findViewById<Button>(R.id.login_button)
val input = findViewById<EditText>(R.id.username_input)
button.setOnClickListener {
val username = input.text.toString()
Toast.makeText(this, "Welcome $username", Toast.LENGTH_SHORT).show()
}
}
}
테스트 코드:
import androidx.test.ext.junit.rules.ActivityScenarioRule
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.action.ViewActions.typeText
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
import org.junit.Rule
import org.junit.Test
class LoginActivityTest {
@get:Rule
val activityRule = ActivityScenarioRule(LoginActivity::class.java)
@Test
fun `login button should show welcome message`() {
onView(withId(R.id.username_input))
.perform(typeText("John"))
onView(withId(R.id.login_button))
.perform(click())
onView(withText("Welcome John"))
.check(matches(isDisplayed()))
}
}
5. 테스트 실행하기
Android Studio에서 실행
- Unit 테스트: src/test/java 디렉토리에서 테스트 클래스를 선택하고 실행.
- UI 테스트: src/androidTest/java 디렉토리에서 테스트 클래스를 선택하고 실행.
명령어로 실행
Gradle 명령어를 사용해 테스트를 실행할 수도 있습니다:
- Unit 테스트: ./gradlew test
- UI 테스트: ./gradlew connectedAndroidTest
6. 테스트 작성 시 주의사항
- 단일 책임 원칙 준수: 각 테스트는 하나의 기능만 검증해야 합니다.
- 독립성 유지: 테스트는 서로 독립적으로 실행 가능해야 합니다.
- 의존성 최소화: 테스트에서 네트워크 호출, 데이터베이스 접근 등 외부 의존성을 Mocking으로 대체하세요.
- 명확한 네이밍: 테스트 이름은 검증하려는 동작을 명확히 설명해야 합니다.
- 실제 시나리오 테스트: UI 테스트에서는 사용자가 실제로 수행할 작업을 기반으로 작성하세요.
반응형
'어질어질 개발노트 > Android' 카테고리의 다른 글
[Android] 프로세스, 스레드, 코루틴의 차이점 완벽 정리 (0) | 2025.01.15 |
---|---|
[Android] 안드로이드 개발에서 Private 함수 테스트: 실전 팁과 예제 (0) | 2025.01.15 |
[Android] Abstract Class vs Interface: 무엇을 선택해야 할까? (0) | 2025.01.14 |
[Android] 클린 아키텍처 (Clean Architecture): 소프트웨어 설계의 정수 (0) | 2025.01.11 |
[Android] Sealed Class와 Enum의 차이점과 적절한 사용법 - Kotlin 개발자를 위한 가이드 (0) | 2025.01.10 |
[Android] ListAdapter vs RecyclerViewAdapter: 무엇을 선택해야 할까? (0) | 2025.01.10 |
[Android] RxJava: flatMap vs switchMap - 차이를 명확히 이해하기 (0) | 2025.01.10 |
[Android] [Kotlin] Compose 기초 - 시작하기 (0) | 2024.08.27 |