μΌ | μ | ν | μ | λͺ© | κΈ | ν |
---|---|---|---|---|---|---|
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 |
- RxSwift
- KoreaMango
- xcode15
- swiftUI
- @Model
- 콩μΈμνλ‘μ νΈ
- Swift
- 2μ£Όμ°¨
- ν°μ€ν 리μ±λ¦°μ§
- tutorial
- 1μ£Όμ°¨
- μ€λΈμ
- test
- κ°λ°μ
- ios
- SwiftData
- νκ³
- watchapp
- νλ‘κ·Έλλ¨Έμ€
- Unit
- Apple
- 2023
- Flutter
- watchkit
- ActivityKit
- unittest
- tutorials
- λνμν
- 3μ£Όμ°¨
- WWDC
- Today
- Total
KoreaMango λ무
[iOS] Unit Test - λ¨μ ν μ€νΈ μ΄λ»κ² νλ건λ°.. (1) λ³Έλ¬Έ
[iOS] Unit Test - λ¨μ ν μ€νΈ μ΄λ»κ² νλ건λ°.. (1)
KoreaMango 2022. 7. 2. 23:57π μλ‘
μ¬λ¬ μΈμ μ΄λ μ±μ©κ³΅κ³ λ₯Ό 보면 λ¨μ ν μ€νΈμ λν μ΄μΌκΈ°λ₯Ό λ§μ΄ μ ν μ μλ€.
ν μ€νΈνλ©° μ½λ©μ νλ©΄ μ μ§λ³΄μκ° μ©μ΄νκ³ μ½λ μμ μ±μ λμ΄λ λ± λ€μν μ₯μ μ΄ μλ€.
μ¬ν ν μ€νΈμ μ€μμ±μ λν΄ μ μκ³ μμμ§λ§, λ΄ νλ‘μ νΈμλ μ μ©ν΄λ³΄μ§ λͺ»νλ€. κ·Έλμ νλ² μμΈνκ² νλ³΄κ³ μ μ 리ν΄λ³΄λ €κ³ νλ€.
βUnit Testμ λν΄
μ μ
μ»΄ν¨ν° νλ‘κ·Έλλ°μμ μμ€ μ½λμ νΉμ λͺ¨λμ΄ μλλ λλ‘ μ νν μλνλμ§ κ²μ¦νλ μ μ°¨
μ¦, λͺ¨λ ν¨μμ λ©μλμ λν ν μ€νΈ μΌμ΄μ€λ₯Ό μμ±νλ μ μ°¨λ₯Ό λ§νλ€. μ΄λ₯Ό ν΅ν΄μ μΈμ λΌλ μ½λ λ³κ²½μΌλ‘ μΈν΄ λ¬Έμ κ° λ°μν κ²½μ°, λ¨μκ° λ΄μ μ΄λ₯Ό νμ νκ³ λ°λ‘ μ‘μ μ μλλ‘ ν΄μ€λ€. μ΄μμ μΌλ‘ ν μ€νΈ μΌμ΄μ€λ λΆλ¦¬λμ΄μΌ νλ€. μ΄λ₯Ό μν΄ κ°μ§ κ°μ²΄(Mock object)λ₯Ό μμ±νλ κ²λ μ’μ λ°©λ²μ΄λ€. μ λ ν μ€νΈλ κ°λ°μ λΏλ§ μλλΌ λ³΄λ€ λ μ¬λμλ ν μ€νΈλ₯Ό μν΄ ν μ€ν°μ μν΄ μνλκΈ°λ νλ€.
- μν€ λ°±κ³Ό -
νλ μ΄μ
- ν΄λΉ λΆλΆ(ν¨μ, λ©μλ)μ λν΄μ λ 립μ μΌλ‘ ν μ€νΈλ₯Ό νκΈ° λλ¬Έμ λΉ λ₯Έ 리ν©ν λ§ λ°μκ³Ό λΉ λ₯Έ ν μ€νΈλ₯Ό μ§νν μ μλ€.
- μ½λμ νμ₯μ΄λ 리ν©ν λ§ μμλ μμ μ±μ ν보ν μ±λ‘ λΉ λ₯΄κ² λμν μ μλ€.
λ°©λ²
λμ νμ
- ν΅μ¬ κΈ°λ₯ : λͺ¨λΈ ν΄λμ€ λ° λ©μλ / 컨νΈλ‘€λ¬μμ μνΈμμ©
- κ°μ₯ μΌλ°μ μΈ UI μν¬ νλ‘
- κ²½κ³ μ‘°κ±΄
- λ²κ·Έ μμ
ν μ€νΈ κΈ°μ€ (FIRST μμΉ)
ν¨κ³Όμ μΈ λ¨μ ν μ€νΈλ₯Ό μν κ°κ²°ν κΈ°μ€ μΈνΈ
- Fast
- ν μ€νΈκ° λΉ λ₯΄κ² μ§νλμ΄μΌ νλ€.
- μλ§μ ν μ€νΈ μ½λλ₯Ό μμ±ν ν λ° ν ν μ€νΈκ° λλ¦¬κ² λμνλ©΄ λ무 μ€λκ±Έλ¦°λ€.
- Independent/Isolated
- κ°κ°μ ν
μ€νΈλ μλ‘ λ
립μ μ΄λ©° μμ‘΄ν΄μλ μλλ€.
- ν μ€νΈλ μλ‘ μνλ₯Ό 곡μ ν΄μλ μλλ€.
- μμ‘΄μ±μ΄ λμΌλ©΄ ν μ€νΈμ μμΈμ μ°ΎκΈ° μ΄λ €μμ§λ€.
- κ°κ°μ ν
μ€νΈλ μλ‘ λ
립μ μ΄λ©° μμ‘΄ν΄μλ μλλ€.
- Repeatable
- ν μ€νΈλ₯Ό μ€νν λλ§λ€ λμΌν κ²°κ³Όλ₯Ό μ»μ΄μΌ νλ€.
- ν΅μ νκΈ° μ΄λ €μ΄ λΆλΆμ ν μ€νΈλ₯Ό μν κ°μ²΄λ₯Ό λ§λ€μ΄μ£Όλ λ°©λ²λ μλ€.
- μΈλΆ λ°μ΄ν° 곡κΈμ λλ λμμ± λ¬Έμ λ‘ μΈν΄ κ°νμ μΈ μ€λ₯κ° λ°μν μ μλ€.
- Self-validating
- ν μ€νΈλ μμ μλνλμ΄μΌ νλ€.
- μΆλ ₯μ λ‘κ·ΈνμΌμ λν νλ‘κ·Έλλ¨Έμ ν΄μμ μμ‘΄νμ§ μκ³ “pass” λλ “fail’ μ¬μΌ νλ€.
- Timely
- μ΄μμ μΌλ‘λ ν
μ€νΈνλ νλ‘λμ
μ½λλ₯Ό μμ±νκΈ° μ μ ν
μ€νΈλ₯Ό μμ±ν΄μΌ νλ€. μ΄λ₯Ό ν
μ€νΈ μ£Όλ κ°λ°μ΄λΌκ³ νλ€. (TDD)
- (μ΄κ² κ·Έ μ λͺ ν TDD?…)
- μ΄μμ μΌλ‘λ ν
μ€νΈνλ νλ‘λμ
μ½λλ₯Ό μμ±νκΈ° μ μ ν
μ€νΈλ₯Ό μμ±ν΄μΌ νλ€. μ΄λ₯Ό ν
μ€νΈ μ£Όλ κ°λ°μ΄λΌκ³ νλ€. (TDD)
π€ Xcodeμμμ UnitTest
νλ‘μ νΈλ₯Ό λ§λ€ λ 보면 μ΄λ κ² includes Tests κ° μλλ° μ΄κ±Έ 체ν¬νκ³ νλ‘μ νΈλ₯Ό μμ±νλ©΄ μΆκ°λ‘ Tests ν΄λκ° λ μκΈ΄λ€.
μμ±λ κ²
- (νλ‘μ νΈ λͺ
) + Tests
- (νλ‘μ νΈ λͺ ) + Tests
- (νλ‘μ νΈ λͺ
) + UITests
- (νλ‘μ νΈ λͺ ) + UITests
- (νλ‘μ νΈ λͺ ) + LaunchTests
μ€ν
- Build - cmd + B
- Test - cmd + U
Testλ₯Ό μμνλ©΄ μ±μ΄ 2κ°κ° μ€μΉλλ€.
μ²μμλ μΌλ°μ μΈ Tests μ½λλ€λΆν° μ§νλκ³ κ·Έλ€μμλ UITestsλ₯Ό μ§ννλλ° μ΄κ±΄ μκ°μ΄ μ€λ κ±Έλ¦°λ€.
κ·Έλ¦¬κ³ UITestsκ° μ’ λ£λλ©΄ λ€ν¬ λͺ¨λλ‘ λ³νλ€ γ γ ;;
π§ ν μ€νΈ μ½λ μμ± μλ Ή
First Test μμ± λ°©λ²
- ν μ€νΈ λ©μλμ μ΄λ¦μ νμ testλ‘ μμνκ³ κ·Έ λ€μ ν μ€νΈ λμμ λν μ€λͺ μ΄ μ¨λ€.
- given, when, then μΉμ
μΌλ‘ λλλ νμμ΄ μ’λ€.
- given: νμν κ°μ μ€μ νλ€. κ·Έλ¦¬κ³ μμ κ°μ΄λ λΉκ΅ν λ μ°μΈλ€.
- when : ν μ€νΈ μ€μΈ μ½λλ₯Ό μ€ννλ μΉμ μ΄λ€.
- then : ν μ€νΈκ° μ€ν¨νλ©΄ μΈμλλ λ©μμ§μ ν¨κ» μμν κ²°κ³Όλ₯Ό μ£Όμ₯νλ μΉμ μ΄λ€.
μμ
func testScoreIsComputedWhenGuessIsHigherThanTarget() {
// given
let guess = sut.targetValue + 5
// when
sut.check(guess: guess)
// then
XCTAssertEqual(sut.scoreRound, 95, "Score computed from guess is wrong")
}
ν μ€νΈ λλ²κΉ
μ±μ λͺ©μ μ λ²κ·Έκ° μμ λ κ·Έκ²μ μ°Ύλ λ°©λ²μ μμ보μ.
μ€λ¨μ νμκΈ°μμ ν μ€νΈ μ€ν¨ μ€λ¨μ μ μΆκ°νλ€.
μ΄λ κ² νλ©΄ ν μ€νΈ λ©μλκ° μ€ν¨λ₯Ό μ°Ύμμ λ ν μ€νΈ μ€νμ΄ μ€μ§λλ€.
κ·Έλ¬λ©΄ λλ²κ·Έ μ½μμ κ²μ¬νμ λ μ΄λ€ κ°μ΄ λ¬Έμ κ° μλμ§ νμΈν μ μλ€.
XCTestExpectationμ μ¬μ©νμ¬ λΉλκΈ° μμ ν μ€νΈ
λͺ¨λΈμ ν μ€νΈνκ³ ν μ€νΈ μ€ν¨λ₯Ό λλ²κ·Έ νλ λ°©λ²μ λ°°μ μΌλ―λ‘ μ΄μ λΉλκΈ° μ½λ ν μ€νΈλ‘ λμ΄κ° μ°¨λ‘μ΄λ€.
URLSessionλ©μλλ λΉλκΈ°μμ λλ€. μ¦μ λ°νλμ§λ§ λμ€κΉμ§ μ€νμ΄ μλ£λμ§ μλλ€.
λΉλκΈ°μ λ©μλλ₯Ό ν μ€νΈνλ €λ©΄ XCTestExpectationλ₯Ό μ¬μ©ν΄μ λΉλκΈ°μ μμ μ΄ μλ£λ λκΉμ§ ν μ€νΈλ₯Ό λκΈ°μμΌμΌ νλ€.
λΉλκΈ° ν μ€νΈλ μΌλ°μ μΌλ‘ λ리λ―λ‘ λ λΉ λ₯Έ λ¨μ ν μ€νΈμ λ³λλ‘ μ μ§ν΄μΌ νλ€.
XCodeTest Method
- expectation(description:)
- XCTestExpectationμ 리ν΄νλ€.
- μμλλ κ²°κ³Ό κ°μ descriptionμ λ£λλ€.
- promise.fulfill()
- λΉλκΈ° λ©μλ μλ£ νΈλ€λ¬μ μ±κ³΅ 쑰건 ν΄λ‘μ μμ μ΄κ²μ νΈμΆνμ¬ κΈ°λκ° μΆ©μ‘±λμμμ νλκ·Έλ‘ μ§μ νλ€.
- wait(for:timeout:)
- λͺ¨λ κΈ°λκ° μΆ©μ‘±λκ±°λ timeout λμ΄μ κ°κ²©μ΄ λλ λκΉμ§ ν μ€νΈλ₯Ό κ³μ μ€ννλ€.
Failing Fast
μ€ν¨λ μνμ§λ§ μμν 걸릴 νμλ μλ€.
URLμ νλ € μΌλΆλ‘ μ€ν¨νλ ν μ€νΈ μΌμ΄μ€λ₯Ό λ§λ€μ΄μ ν μ€νΈνλ€.
κ·Έλ λ€λ©΄ μ 체 μκ° μ΄κ³Όκ° λλ κ°κ²©μ΄ ꡬν΄μ§λ€. μλνλ©΄ νμ μ±κ³΅ν κ±°λΌκ³ κ°μ νκ³ , κ±°κΈ°μ promise.fulfill()μ λΆλ κΈ° λλ¬Έμ΄λ€.
requestκ° μ€ν¨λμκΈ° λλ¬Έμ μ€μ§ μ νμκ°μ΄ λ§λ£λμμ λλ§ μ’ λ£κ° λλ€.
κ°μ μ λ³κ²½νμ¬ μ΄λ₯Ό κ°μ νκ³ ν μ€νΈκ° λ 빨리 μ€ν¨νλλ‘ ν μ μλ€.
requestκ° μ±κ³΅ν λκΉμ§ κΈ°λ€λ¦¬λ λμ λΉλκΈ° λ©μλμ μλ£ μ²λ¦¬κΈ°κ° νΈμΆλ λκΉμ§ κΈ°λ€λ €λΌ..
μ΄λ μ±μ΄ μλ²λ‘λΆν° μλ΅(OK λλ μ€λ₯)μ μμ νλ μ¦μ λ°μνλ©°, μ΄λ μμμ μΆ©μ‘±νλ€.
κ·Έλ¬λ©΄ ν μ€νΈμμ μμ²μ΄ μ±κ³΅νλμ§ μ¬λΆλ₯Ό νμΈν μ μλ€.
Failing Conditionally
μ΄λ€ μν©μμλ ν μ€νΈλ₯Ό μ€ννλ κ²μ΄ μλ―Έκ° μλ€.
μλ₯Ό λ€μ΄, testValidApiCallGetsHTTPStatusCode200() λ€νΈμν¬ μ°κ²° μμ΄ μ€ννλ©΄ μ΄λ»κ² λ κΉ?
λ¬Όλ‘ 200 μν μ½λλ₯Ό λ°μ§ λͺ»νκΈ° λλ¬Έμ ν΅κ³Όν΄μλ μ λλ€.
κ·Έλ¬λ μ무κ²λ ν μ€νΈνμ§ μμκΈ° λλ¬Έμ μ€ν¨νμ§ μμμΌ νλ€.
XCTSkipUnless(_:_:)λ₯Ό μ¬μ©ν λ λ€νΈμν¬μ μ°κ²°ν μ μμΌλ©΄ ν μ€νΈλ₯Ό 건λλ΄λ€.
λ€νΈμν¬ μ°κ²°μ λΉνμ±ννκ³ ν μ€νΈλ₯Ό μ€ννμ¬ μ΄λ₯Ό νμΈν΄λΌ.
ν μ€νΈ μμ μλ μ¬λ°±μ ν μ€νΈκ° ν΅κ³Όνκ±°λ μ€ν¨νμ§ μμμμ λνλ΄λ μ μμ΄μ½μ΄ νμλλ€.
Faking Objects and Interactions
λΉλκΈ° ν μ€νΈλ μ½λκ° λΉλκΈ° APIμ λν μ¬λ°λ₯Έ μ λ ₯μ μμ±νλ€λ νμ μ μ€λ€.
URL μΈμ μμ μ λ ₯μ λ°μ λ μ½λκ° μ¬λ°λ₯΄κ² μλνλμ§, λλ UserDefaults λ°μ΄ν°λ² μ΄μ€ λλ iCloud 컨ν μ΄λλ₯Ό μ¬λ°λ₯΄κ² μ λ°μ΄νΈνλμ§ ν μ€νΈν μλ μλ€.
λλΆλΆμ μ±μ μ¬μ©μκ° μ μ΄ν μ μλ μμ€ν λλ λΌμ΄λΈλ¬λ¦¬ κ°μ²΄μ μνΈ μμ©νλ€. μ΄λ¬ν κ°μ²΄μ μνΈ μμ©νλ ν μ€νΈλ λλ¦¬κ³ λ°λ³΅ν μ μμΌλ©° 첫 λ²μ§Έ μμΉ μ€ λ κ°μ§λ₯Ό μλ°ν μ μλ€. λμ μ€ν μμ μ λ ₯μ λ°κ±°λ λͺ¨μ κ°μ²΄λ₯Ό μ λ°μ΄νΈνμ¬ μνΈ μμ©μ μμ‘°ν μ μλ€.
μ½λκ° μμ€ν λλ λΌμ΄λΈλ¬λ¦¬ κ°μ²΄μ μ’ μλμ΄ μλ κ²½μ° κ°μ§λ₯Ό μ¬μ©νλ€. κ·Έ λΆλΆμ μ°κΈ°ν κ°μ§ κ°μ²΄λ₯Ό λ§λ€κ³ μ΄ κ°μ§λ₯Ό λΉμ μ μ½λμ μ£Όμ ν¨μΌλ‘μ¨ μ΄κ²μ μνν΄λΌ. John Reidμ Dependency Injectionμ μ΄λ₯Ό μν λͺ κ°μ§ λ°©λ²μ μ€λͺ νλ€.
Faking Input From Stub
μ΄ ν μ€νΈλ λ κ°μ§ μμ μ μννλ€.
- κ°μ§ λ°μ΄ν°μ μλ΅μ μ€μ νκ³ κ°μ§ μΈμ κ°μ²΄λ₯Ό λ§λ λ€. λ§μ§λ§μΌλ‘ κ°μ§ μΈμ μ sutμ μμ±μΌλ‘ μ±μ μ£Όμ νλ€.
- μ€ν μ΄ λΉλκΈ° λ©μλλ‘ κ°μ₯νκΈ° λλ¬Έμ μ¬μ ν λΉλκΈ° ν μ€νΈλ‘ μμ±ν΄μΌ νλ€. startNewRound(completion:)λ₯Ό νΈμΆνλ©΄ targetValueμ stubed κ°μ§ λ²νΈλ₯Ό λΉκ΅νμ¬ κ°μ§ λ°μ΄ν°λ₯Ό ꡬ문 λΆμνλμ§ νμΈνλ€.
ν μ€νΈλ₯Ό μ€νν©λλ€. κ·Έκ²μ μ€μ λ€νΈμν¬ μ°κ²°μ΄ μκΈ° λλ¬Έμ κ½€ 빨리 μ±κ³΅ν κ²μ΄λ€!
Faking an Update to Mock Object
μ΄μ ν μ€νΈμμλ μ€ν μ μ¬μ©νμ¬ κ°μ§ κ°μ²΄λ‘λΆν°μ μ λ ₯μ μ 곡νλ€.
κ·Έλ° λ€μ Mock Objectλ₯Ό μ¬μ©νμ¬ μ½λκ° μ¬μ©μ κΈ°λ³Έκ°μ μ¬λ°λ₯΄κ² μ λ°μ΄νΈνλμ§ ν μ€νΈνλ€.
UI Testing in Xcode
UI ν μ€νΈλ₯Ό ν΅ν΄ μ¬μ©μ μΈν°νμ΄μ€μμ μνΈ μμ©μ ν μ€νΈν μ μλ€.
UI ν μ€νΈλ μΏΌλ¦¬λ‘ μ±μ UI κ°μ²΄λ₯Ό μ°Ύκ³ μ΄λ²€νΈλ₯Ό ν©μ±ν λ€μ ν΄λΉ κ°μ²΄μ μ΄λ²€νΈλ₯Ό 보λ΄λ λ°©μμΌλ‘ μλνλ€.
APIλ₯Ό μ¬μ©νλ©΄ UI κ°μ²΄μ μμ± λ° μνλ₯Ό κ²μ¬νμ¬ μμ μνμ λΉκ΅ν μ μλ€.
tap() μ΄λ κ² νλ©΄ λΆν λ 컨νΈλ‘€μ κ° λ²νΌμ μ¬λ°λ₯Έ λ μ΄λΈμ΄ μλμ§ νμΈνλ€. ν μ€νΈλ₯Ό μ€ννμμμ€. λͺ¨λ μ΄μ€μ μ΄ μ±κ³΅ν΄μΌ νλ€.
Testing Performance
Apple λ¬Έμ μμ :
μ±λ₯ ν μ€νΈλ νκ°νλ €λ μ½λ λΈλ‘μ μ¬μ©νμ¬ 10λ² μ€ννμ¬ μ€νμ λν νκ· μ€ν μκ°κ³Ό νμ€ νΈμ°¨λ₯Ό μμ§ν©λλ€. μ΄λ¬ν κ°λ³ μΈ‘μ κ°μ νκ· μ ν μ€νΈ μ€νμ λν κ°μ νμ±ν λ€μ κΈ°μ€μ κ³Ό λΉκ΅νμ¬ μ±κ³΅ λλ μ€ν¨λ₯Ό νκ°ν μ μμ΅λλ€.
μ±λ₯ ν μ€νΈλ₯Ό μμ±νλ κ²μ κ°λ¨νλ€.
μΈ‘μ νλ €λ μ½λλ₯Ό measure()μ ν΄λ‘μ μ λ°°μΉνκΈ°λ§ νλ©΄ λλ€.
λν μΈ‘μ ν μ¬λ¬ λ©νΈλ¦μ μ§μ ν μ μλ€.
- XCTClockMetric
- κ²½κ³Ό μκ°μ μΈ‘μ νλ€.
- XCTCPUMetric
- CPU μκ°, μ£ΌκΈ° λ° λͺ λ Ή μλ₯Ό ν¬ν¨ν CPU νλμ μΆμ νλ€.
- XCTStorageMetric
- ν μ€νΈν μ½λκ° μ€ν 리μ§μ μ°λ λ°μ΄ν°μ μμ μλ €μ€λ€.
- XCTMemoryMetric
- μ¬μ©λ 물리μ λ©λͺ¨λ¦¬μ μμ μΆμ νλ€.
ν μ€νΈλ₯Ό μ€νν λ€μ νν ν΄λ‘μ μ μμ λΆλΆ μμ λνλλ μμ΄μ½μ ν΄λ¦νμ¬ measure() ν΅κ³λ₯Ό νμΈνλ€.
μΈ‘μ νλͺ© μμ μλ μ νν μΈ‘μ νλͺ©μ λ³κ²½ν μ μλ€.
ππ» Ref
https://www.raywenderlich.com/21020457-ios-unit-testing-and-ui-testing-tutorial#toc-anchor-011
https://yagom.net/courses/unit-test-μμ±νκΈ°/