Android

Android - 안정적인 앱 개발을 위한 단위 테스트와 UI 테스트 작성법

임베디드 친구 2024. 12. 4. 08:52
반응형

안녕하세요, '소프트웨어 공장' 블로그에 오신 것을 환영합니다! 오늘은 안드로이드 애플리케이션을 안정적으로 개발하기 위한 중요한 기술 중 하나인 단위 테스트(Unit Test)와 UI 테스트(UI Test) 작성법에 대해 이야기해 보겠습니다. 안정적인 앱 개발을 위해서는 철저한 테스트가 필수입니다. 이번 포스팅에서는 단위 테스트와 UI 테스트가 왜 중요한지, 그리고 실제로 Kotlin을 사용해 어떻게 작성할 수 있는지 알아보겠습니다.

단위 테스트란 무엇인가요?

단위 테스트(Unit Test)는 코드의 특정 모듈이나 함수와 같은 작은 단위를 테스트하는 것입니다. 이렇게 하면 코드가 예상대로 동작하는지, 각 단위가 올바른 출력을 반환하는지를 검증할 수 있습니다. 단위 테스트는 개발 주기 중에 코드 품질을 높이는 중요한 방법입니다.

단위 테스트 작성하기

안드로이드에서 단위 테스트를 작성하기 위해 주로 사용하는 라이브러리는 JUnit입니다. 여기서는 간단한 예제를 통해 단위 테스트를 작성하는 방법을 알아보겠습니다.

예제: Calculator 클래스 단위 테스트 작성하기

먼저, 기본적인 사칙연산을 수행하는 Calculator 클래스를 만들어 보겠습니다.

// Calculator.kt
class Calculator {
    fun add(a: Int, b: Int): Int {
        return a + b
    }

    fun subtract(a: Int, b: Int): Int {
        return a - b
    }

    fun multiply(a: Int, b: Int): Int {
        return a * b
    }

    fun divide(a: Int, b: Int): Int {
        if (b == 0) throw IllegalArgumentException("Divider cannot be zero")
        return a / b
    }
}

이제 Calculator 클래스에 대한 단위 테스트를 작성해 보겠습니다.

// CalculatorTest.kt
import org.junit.Test
import org.junit.Assert.*

class CalculatorTest {
    private val calculator = Calculator()

    @Test
    fun addition_isCorrect() {
        assertEquals(4, calculator.add(2, 2))
    }

    @Test
    fun subtraction_isCorrect() {
        assertEquals(0, calculator.subtract(2, 2))
    }

    @Test
    fun multiplication_isCorrect() {
        assertEquals(9, calculator.multiply(3, 3))
    }

    @Test(expected = IllegalArgumentException::class)
    fun division_byZero_throwsException() {
        calculator.divide(4, 0)
    }
}

위 코드에서는 JUnit을 사용하여 Calculator 클래스의 각 메서드에 대한 테스트를 작성했습니다. 각 테스트는 특정 입력에 대해 올바른 출력이 나오는지 검증합니다.

UI 테스트란 무엇인가요?

UI 테스트(UI Test)는 사용자 인터페이스가 올바르게 동작하는지 확인하는 테스트입니다. 사용자 흐름을 자동화하여 버튼 클릭, 화면 전환, 텍스트 입력 등이 예상대로 동작하는지를 검증합니다. 안드로이드에서는 주로 Espresso 라이브러리를 사용하여 UI 테스트를 작성합니다.

UI 테스트 작성하기

UI 테스트는 사용자가 앱을 사용하는 것처럼 시뮬레이션합니다. 여기서는 간단한 화면을 테스트하는 예제를 통해 UI 테스트 작성 방법을 살펴보겠습니다.

예제: LoginActivity UI 테스트 작성하기

먼저 간단한 로그인 화면을 만들어 보겠습니다.

// LoginActivity.kt
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_login.*

class LoginActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_login)

        loginButton.setOnClickListener {
            val username = usernameEditText.text.toString()
            val password = passwordEditText.text.toString()
            if (username == "admin" && password == "password") {
                loginResultTextView.text = "Login Successful"
            } else {
                loginResultTextView.text = "Login Failed"
            }
        }
    }
}

이제 Espresso를 사용해 LoginActivity에 대한 UI 테스트를 작성해 보겠습니다.

// LoginActivityTest.kt
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 androidx.test.ext.junit.rules.ActivityScenarioRule
import org.junit.Rule
import org.junit.Test

class LoginActivityTest {
    @get:Rule
    val activityRule = ActivityScenarioRule(LoginActivity::class.java)

    @Test
    fun login_successful() {
        onView(withId(R.id.usernameEditText)).perform(typeText("admin"))
        onView(withId(R.id.passwordEditText)).perform(typeText("password"))
        onView(withId(R.id.loginButton)).perform(click())
        onView(withId(R.id.loginResultTextView)).check(matches(withText("Login Successful")))
    }

    @Test
    fun login_failed() {
        onView(withId(R.id.usernameEditText)).perform(typeText("user"))
        onView(withId(R.id.passwordEditText)).perform(typeText("1234"))
        onView(withId(R.id.loginButton)).perform(click())
        onView(withId(R.id.loginResultTextView)).check(matches(withText("Login Failed")))
    }
}

위 코드는 Espresso를 사용하여 로그인 화면의 UI 테스트를 작성한 것입니다. 첫 번째 테스트는 올바른 자격 증명으로 로그인하는 경우를, 두 번째 테스트는 잘못된 자격 증명으로 로그인하는 경우를 검증합니다.

테스트를 통한 안정성 향상

안드로이드 앱 개발에서 단위 테스트와 UI 테스트는 각기 다른 목적을 가지고 있지만, 모두 앱의 안정성을 높이는 데 중요한 역할을 합니다. 단위 테스트는 각 기능이 올바르게 동작하는지를 보장하고, UI 테스트는 사용자가 앱을 사용하는 동안 발생할 수 있는 문제를 미리 발견하도록 도와줍니다.

테스트를 작성함으로써 발생할 수 있는 버그를 조기에 발견할 수 있고, 코드의 변경이 기존 기능에 미치는 영향을 빠르게 파악할 수 있습니다. 또한, 리팩토링이나 기능 추가 시에 이전 기능이 깨지지 않도록 보장할 수 있습니다.

마무리

이번 포스팅에서는 안드로이드 애플리케이션의 안정성을 높이기 위한 단위 테스트와 UI 테스트 작성법에 대해 알아보았습니다. Kotlin을 사용하여 Calculator 클래스에 대한 단위 테스트와 LoginActivity에 대한 UI 테스트를 작성하는 방법을 살펴보았는데요, 이러한 테스트 기법들을 활용하여 여러분의 앱이 더욱 견고하고 안정적으로 동작할 수 있기를 바랍니다.

테스트를 처음 작성해보는 것이 어렵게 느껴질 수 있지만, 점차 익숙해지면 테스트가 주는 많은 이점을 느낄 수 있을 것입니다. 다음 포스팅에서는 더욱 심화된 테스트 기법과 다양한 도구들을 활용하는 방법에 대해 알아보도록 하겠습니다.

반응형