๊นจ์•Œ ๊ฐœ๋… ๐Ÿ“‘/Android

[Android] Unit Testing - ๊ธฐ์ดˆ

interfacer_han 2024. 7. 8. 11:25

#1 ์ด์ „ ๊ธ€

#1-1 Unit Testing ๊ฐœ์š”

 

[Android] Unit Testing - ๊ฐœ์š”์™€ ํ™˜๊ฒฝ ์„ค์ •

#1 ์•ˆ๋“œ๋กœ์ด๋“œ ์•ฑ ํ…Œ์ŠคํŠธ#1-1 ์•ˆ๋“œ๋กœ์ด๋“œ ์•ฑ ํ…Œ์ŠคํŠธ์˜ ์ข…๋ฅ˜๋จผ์ €, ์—ฌ๊ธฐ์— ์žˆ๋Š” ๊ตฌ๊ธ€ ๊ณต์‹ ๋ฌธ์„œ์—์„œ ์•ˆ๋“œ๋กœ์ด๋“œ ์•ฑ ํ…Œ์ŠคํŠธ์— ๋Œ€ํ•œ ๊ฐœ์š”๋ฅผ ์ฝ์œผ๋ฉด ์ข‹๋‹ค. ํ•ด๋‹น ๊ตฌ๊ธ€ ๊ณต์‹ ๋ฌธ์„œ์—์„œ ๋ณต์‚ฌํ•ด์˜จ ์œ„์˜ ๊ทธ๋ฆผ

kenel.tistory.com

์œ„ ๋งํฌ์— ์žˆ๋Š” ์ด์ „ ๊ฒŒ์‹œ๊ธ€์— ์ด์–ด์„œ, ์‹ค์ œ ์•ˆ๋“œ๋กœ์ด๋“œ ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ค์–ด ๊ธฐ์ดˆ์ ์ธ ์•ˆ๋“œ๋กœ์ด๋“œ Unit Testing์„ ์ˆ˜ํ–‰ํ•ด๋ณธ๋‹ค.

 

#1-2 ํ™˜๊ฒฝ ์„ค์ • (build.gradle ๋“ฑ)

์ด์ „ ๊ฒŒ์‹œ๊ธ€์˜ #3์„ ํ† ๋Œ€๋กœ ๋ณธ ๊ฒŒ์‹œ๊ธ€์— ๋‚˜์˜ค๋Š” ์•ˆ๋“œ๋กœ์ด๋“œ ํ”„๋กœ์ ํŠธ์˜ Gradle, AGP, JDK์˜ ๋ฒ„์ „ ์„ค์ • ๋ฐ build.gradle ์„ค์ •์„ ์ง„ํ–‰ํ•œ๋‹ค. ์ด์ „ ๊ฒŒ์‹œ๊ธ€์˜ build.gradle๊ณผ ๋‹ฌ๋ฆฌ, ๋ณธ ๊ฒŒ์‹œ๊ธ€์—์„œ๋Š” Unit Testing์— ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” build.gradle์˜ plugins { ... }, buildFeatures { ... }, dependencies { ... }์˜ ์ผ๋ถ€ ์š”์†Œ๋ฅผ ์ œ๊ฑฐํ–ˆ๋‹ค. ์ด๋Š”  ์ฝ”๋“œ ๋‹ค์ด์–ดํŠธ๋ฅผ ์œ„ํ•œ ๊ฐœ์ธ์ ์ธ ์ œ๊ฑฐ์ด๊ธฐ ๋•Œ๋ฌธ์—, ์ด ๊ธ€์€ ๋ณด๋Š” ์‚ฌ๋žŒ์€ ์ œ๊ฑฐ ์—†์ด ๊ทธ๋ƒฅ ๋ณต์‚ฌ ๋ฐ ๋ถ™์—ฌ๋„ฃ๊ธฐํ•ด๋„ ๋œ๋‹ค.

 

#2 Unit Testing์„ ์ ์šฉํ•  ์ƒ˜ํ”Œ ์•ฑ

์ „์ฒด ์†Œ์Šค ์ฝ”๋“œ๋Š” ๋ณธ ๊ฒŒ์‹œ๊ธ€์˜ #5์— ์žˆ๋‹ค.

 

#2-1 interface Calculation

interface Calculation {

    fun sum(operand1: Int, operand2: Int): Int

    fun multiply(operand1: Int, operand2: Int): Int

    fun sumAndSquare(operand1: Int, operand2: Int): Int
}

Unit Test๋ฅผ ์ง„ํ–‰ํ•  ํด๋ž˜์Šค๊ฐ€ ์ƒ์†๋ฐ›์„ ์ธํ„ฐํŽ˜์ด์Šค๋‹ค.

 

#2-2 class MyCalculation : Calculation

class MyCalculation : Calculation {

    override fun sum(operand1: Int, operand2: Int): Int {
        return operand1 + operand2
    }

    override fun multiply(operand1: Int, operand2: Int): Int {
        return operand1 * operand2
    }

    override fun sumAndSquare(operand1: Int, operand2: Int): Int {
        val sum = sum(operand1, operand2)
        return multiply(sum, sum)
    }
}

Unit Test๋ฅผ ์ง„ํ–‰ํ•  ํด๋ž˜์Šค๋‹ค.

 

#3 Unit Testing

#3-1 ํ…Œ์ŠคํŠธ ํด๋ž˜์Šค ๊ฐ„ํŽธํ•˜๊ฒŒ ๋งŒ๋“ค๊ธฐ

ํด๋ž˜์Šค ์ด๋ฆ„์— ์šฐํด๋ฆญ ํ›„ [Generate...] ํด๋ฆญ

 

[Test...] ํด๋ฆญ

 

Create Test ์ฐฝ์—์„œ Destination pacakge ์„ ํƒ ๋ฒ„ํŠผ ํด๋ฆญ

 

MyCalculation ํด๋ž˜์Šค์˜ ํ•จ์ˆ˜๋“ค์€ ๋‹จ์ˆœํžˆ ์ˆ˜ํ•™์  ๊ณ„์‚ฐ๋งŒ ์ˆ˜ํ–‰ํ•˜๋ฏ€๋กœ, ์ด๋Ÿฌํ•œ ํด๋ž˜์Šค์˜ ํ…Œ์ŠคํŠธ๋ฅผ ์•ˆ๋“œ๋กœ์ด๋“œ ์—๋ฎฌ๋ ˆ์ดํ„ฐ์—์„œ ์‹คํ–‰ํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค. ๋”ฐ๋ผ์„œ Local unit test์— ์†ํ•˜๋Š” unitTest ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์„ ํƒํ•œ๋‹ค (Instrumented test๋„ Unit Test๋ผ๋Š” ๋ฒ”์ฃผ์— ์†ํ•˜์ง€๋งŒ, ์•ˆ๋“œ๋กœ์ด๋“œ ์—๋ฎฌ๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ์ ์—์„œ ์˜จ์ „ํ•œ(?) Unit Test๋Š” ์•„๋‹ˆ๊ธฐ์— ์ด๋ ‡๊ฒŒ ๋‚˜๋ˆ ๋†“์•˜๋‹ค ๋ณด๋‹ค).

 

OK ๋ฒ„ํŠผ ํด๋ฆญ

 

์ด๋ ‡๊ฒŒ ํ…Œ์ŠคํŠธ ํด๋ž˜์Šค๊ฐ€ ์ƒ์„ฑ๋œ๋‹ค. ๋ฌผ๋ก , ํŒจํ‚ค์ง€ ํด๋”์— ์šฐํด๋ฆญํ•˜์—ฌ ์ง์ ‘ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด๋„ ์ƒ๊ด€์—†๋‹ค.

 

#3-2 ํ…Œ์ŠคํŠธ ํด๋ž˜์Šค์˜ ๋‚ด์šฉ ์ž‘์„ฑ

import com.google.common.truth.Truth
import org.junit.Before
import org.junit.Test

class MyCalculationTest {
    private lateinit var myCalculation: MyCalculation

    @Before
    fun setUp() {
        myCalculation = MyCalculation()
    }

    @Test
    fun sum_given77And777_return854() { // subjectUnderTest_actionOrInput_resultState ๊ทœ์น™์œผ๋กœ ํ•จ์ˆ˜ ๋ช…๋ช…ํ•จ
        val result = myCalculation.sum(77, 777)
        Truth.assertThat(result).isEqualTo(/* expected = */ 854)
    }

    @Test
    fun multiply_given3And4_return12() {
        val result = myCalculation.multiply(3, 4)
        Truth.assertThat(result).isEqualTo(/* expected = */ 12)
    }

    @Test
    fun sumAndSqaure_given9And5_return196() {
        val result = myCalculation.sumAndSquare(9, 5)
        Truth.assertThat(result).isEqualTo(/* expected = */ 196)
    }
}

@Before์€ init { ... }๊ณผ ๋น„์Šทํ•œ ๊ฐœ๋…์ด๋ผ๊ณ  ๋ณด๋ฉด ๋œ๋‹ค. @After๋„ ์กด์žฌํ•˜๋Š”๋ฐ, ์ด๋Š” @Before๊ณผ ๋ฐ˜๋Œ€๋กœ ํ…Œ์ŠคํŠธ ์ข…๋ฃŒ ์ง์ „์— ์ˆ˜ํ–‰๋˜๋Š” ์ฝ”๋“œ์˜ ๋ชจ์ž„์ด๋‹ค. ๊ฐ ํ…Œ์ŠคํŠธ์˜ ํ•ญ๋ชฉ์€ @Test ์–ด๋…ธํ…Œ์ด์…˜์ด ๋ถ™์€ ๋ฉ”์†Œ๋“œ์˜ ํ˜•ํƒœ๋กœ ๊ตฌํ˜„๋œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋ฉ”์†Œ๋“œ์˜ ์ด๋ฆ„์€ subjectUnderTest_actionOrInput_resultState ์ž‘๋ช… ๊ทœ์น™์œผ๋กœ ์ง“๋Š” ๊ฒƒ์ด ๊ด€๋ก€๋ผ๊ณ  ํ•œ๋‹ค. assertThat() ํ•จ์ˆ˜๋Š” ํ…Œ์ŠคํŠธ์˜ ์„ฑ๊ณต ํ˜น์€ ์‹คํŒจ๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ๋ฉ”์†Œ๋“œ๋‹ค. ์ด assertThat() ๋ฉ”์†Œ๋“œ๋Š” ์—ฌ๋Ÿฌ ํ…Œ์ŠคํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ๋™์ผํ•œ ์ด๋ฆ„์˜ ๋ฉ”์†Œ๋“œ๋กœ์„œ ์ง€๋‹ˆ๊ณ  ์žˆ๋‹ค. ๋‚˜๋Š” Truth ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ assertThat()๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค.

 

#3 ์ž‘๋™ ํ™•์ธ

๋ฉ”์†Œ๋“œ ์˜†์— ๋œจ๋Š” ์ดˆ๋ก์ƒ‰ ์žฌ์ƒ ๋ฒ„ํŠผ ํด๋ฆญ

 

[Run] ํด๋ฆญ

 

์„ฑ๊ณตํ–ˆ๋‹ค. ๋ฉ”์†Œ๋“œ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ํด๋ž˜์Šค ์ด๋ฆ„ ์˜†์—๋„ ์žฌ์ƒ๋ฒ„ํŠผ์ด ์žˆ๋‹ค. ์ด๋Š” ํด๋ž˜์Šค ๋‚ด์˜ ๋ชจ๋“  @Test ๋ฉ”์†Œ๋“œ์˜ ํ…Œ์ŠคํŠธ๋ฅผ ํ•œ ๋ฒˆ์— ์ˆ˜ํ–‰ํ•œ๋‹ค.

 

#4 ์™„์„ฑ๋œ ์•ฑ

 

android-practice/unit-test/UnitTestingBasics at master · Kanmanemone/android-practice

Contribute to Kanmanemone/android-practice development by creating an account on GitHub.

github.com