π‘ TDDλ₯Ό νμ©ν κ°λ°μ μ₯μ μ μκ³ , 리ν©ν λ§νλ κ³Όμ μ νμ΅νμμ΅λλ€.
TDD
- ν μ€νΈ μ£Όλ κ°λ°λ‘ μ½λλ₯Ό μμ±νκΈ° μ μ ν μ€νΈλ₯Ό λ¨Όμ μμ±νλ κ°λ° λ°©λ²λ‘ μ λλ€.
- μλμ κ°μ μμ
μ, λ§€μ° μ§§μ μ¬μ΄ν΄λ‘ λ°λ³΅νλ€λ νΉμ§μ΄ μμ΅λλ€.
- [λΉ¨κ°] μ€ν¨νλ μμ ν μ€νΈ μμ±
- [μ΄λ‘] μ΅λν λΉ λ₯Έ ν μ€νΈ ν΅κ³Ό
- [νλ] 리ν©ν°λ§ κ³Όμ μ ν΅ν΄μ μ€λ³΅ & μ½λ κ°μ
- TDDμ λͺ©μ μ μ½λκ° ν μ€νΈμ μ§μ ν μꡬ μ¬νμ μΆ©μ‘±νλμ§ νμΈνκ³ , μ½λλ₯Ό 리ν©ν λ§νκΈ° μ½κ² μμ νλ κ²μ λλ€.
TDD μμΉ
- μ€ν¨νλ λ¨μ ν μ€νΈλ₯Ό μμ±ν λκΉμ§ ꡬν μ½λλ₯Ό μμ±νμ§ μμ΅λλ€.
- μ»΄νμΌμ μ€ν¨νμ§ μμ§λ§, μ€νμ΄ μ€ν¨νλ μ λλ‘λ§ μ½λλ₯Ό μμ±ν©λλ€.
- νμ¬ μ€ν¨νλ ν μ€νΈλ₯Ό ν΅κ³Όν μ λλ‘λ§ μ€μ μ½λλ₯Ό μμ±ν©λλ€.
Kotlinμμμ TDD
- Kotlinμ Javaλ₯Ό ν¬ν¨ν λ€λ₯Έ μΈμ΄μ λΉν΄ λ§€μ° κ°κ²°ν μΈμ΄λ‘, μ μ μ½λλ₯Ό ν΅ν΄ κΈ°λ₯μ ꡬνν μ μμ΅λλ€.
- μ½λ μκ° μ μμλ‘ ν μ€νΈλ₯Ό μμ±νλ μκ°μ΄ κ°μνλ―λ‘ Kotlinμ TDDμ μ ν©ν μΈμ΄λΌκ³ λ ν μ μμ΅λλ€.
TDD ꡬμ±νκΈ°
- BankAccount(μν κ³μ’)λΌλ λλ©μΈ ν΄λμ€λ₯Ό ꡬμ±νλ€κ³ ν λ, TDDλ₯Ό ꡬνν΄λ³΄κ² μ΅λλ€.
ν μ€νΈ μμ±
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
class BankAccountTest {
private lateinit var account: BankAccount
@BeforeEach
fun setUp() {
account = BankAccount()
}
@Test
fun testInitialBalance() {
assertEquals(0, account.getBalance())
}
@Test
fun testDeposit() {
account.deposit(100)
assertEquals(100, account.getBalance())
}
}
- μ°μ ν μ€νΈλ₯Ό μμ±νμμ΅λλ€.
- accountμλ μλμ κ°μ λκ°μ§ λ©μλλ₯Ό κ°μ§κ³ μμ΅λλ€.
- μ κΈμ μ§ννλ deposit()
- μμ‘ νμΈμ μ§ννλ getBalance()
λλ©μΈ ν΄λμ€ μμ±
class BankAccount {
private var balance: Int = 0
fun getBalance(): Int {
return balance
}
fun deposit(amount: Int) {
balance += amount
}
}
- μ΄ ν μνλ λλ©μΈ ν΄λμ€λ₯Ό μμ±νμμ΅λλ€.
- ν μ€νΈ μ½λ μμ± μ κΈ°λνλ κ°μΌλ‘ λ°ννλλ‘ λ©μλλ₯Ό ꡬννμμ΅λλ€.
리ν©ν λ§ μ§ν
- λλ©μΈ ν΄λμ€λ₯Ό μμ±νμλ€λ©΄, 리ν©ν λ§μ μ§νν μ μμ΅λλ€.
- κΈ°λ₯μ΄ μ μ ν΄λμ€μ΄λ―λ‘, λ³μ μ΄λ¦ κ°μ κ³Ό μ΄κΈ°ν λ‘μ§μ λΆλ¦¬νλ κ°λ¨ν 리ν©ν λ§μ μ§ννμμ΅λλ€.
- λν μμΈ μ²λ¦¬λ₯Ό μΆκ°νμ¬ μ ν¨νμ§ μμ μ λ ₯μ λ°©μ§νκ³ μ νμμ΅λλ€.
class BankAccount {
private var currentBalance: Int = 0
init {
initialize()
}
private fun initialize() {
currentBalance = 0
}
fun getBalance(): Int = currentBalance
fun deposit(amount: Int) {
require(amount > 0)
currentBalance += amount
}
}
λ°λ³΅νκΈ°
- ν μ€νΈ μ½λ μμ± → λλ©μΈ λ‘μ§ κ΅¬ν → 리ν©ν λ§ λ¨κ³λ₯Ό κ±°μ³€μΌλ―λ‘, λ€μ ν μ€νΈ μ½λλ₯Ό μμ ν΄μΌ ν©λλ€.
- deposit() λ©μλλ₯Ό νΈμΆν λ μ ν¨μ±μ κ²μ¬νλ―λ‘, μ€ν¨νλ ν μ€νΈλ₯Ό μμ±νμ¬ μ ν¨μ± κ²μ¦μ΄ μ λλ‘ μ΄λ£¨μ΄μ§λμ§ νμΈν μ μμ΅λλ€.
@Test
fun testDepositNegativeAmount() {
val exception = assertThrows<IllegalArgumentException> {
account.deposit(-100)
}
assertEquals("Deposit amount must be positive", exception.message)
}
- μ΄μ κ°μ΄ 리ν©ν λ§ κ³Όμ μ ν΅ν΄ μ μ§μ μΌλ‘ κΈ°λ₯μ κ°μ νλ©΄μ λλ©μΈμ TDDλ‘ κ΅¬νν μ μμ΅λλ€.
κ²°λ‘
- TDDλ₯Ό νμ©νλ€λ©΄ μ’μ μ€κ³λ₯Ό ν μ μλ λ°λ°νμ΄ λλ©°, CI/CDμ μ μ©νμ¬ ν μ€νΈλ₯Ό μλνν μ μμ΅λλ€.
- λ€μν μΌμ΄μ€λ₯Ό λ¨Όμ μκ°νκ³ κ°λ°νλ©΄ μ½λ μμ± μ κ°κ²°νκ³ μ’μ μ½λλ₯Ό μμ±ν μ μμ΅λλ€.
- μΆμ λ ν μ€νΈ μ½λλ λμμ§ ν μ€νΈ 컀λ²λ¦¬μ§λ‘ λ²κ·Έ μμ λ° λ¦¬ν©ν λ§μ΄ μμ ν΄, μ μ§λ³΄μκ° λμμ§λ€λ ν° μ₯μ μ κ°μ§κ³ μμ΅λλ€.
- λ°λ©΄μ ν
μ€νΈ μ½λλ₯Ό μμ±νκΈ° μν λ¬λ컀λΈκ° μ‘΄μ¬ν©λλ€.
- Junit, Espresso λ±μ APIλ₯Ό νμ΅ν΄μΌ ν¨
- κΈ°ν λ³κ²½μ λ°λ₯Έ μ½λκ° μμ λλ€λ©΄, μ§μμ μΈ ν μ€νΈ μ½λ μμ μμ λΆκ°νΌν μ μμ΅λλ€.