๐์๋ก
์ด์ ์ค์ ์ผ๋ก ๋ค์ด๊ฐ๋ณด์. ์์ ๋ก Unit Test๋ฅผ ํด๋ณด๋ ค๊ณ ํ๋ค.
@testable
ํ ์คํธ ๋ฉ์๋๋ฅผ ์์ฑํ๊ธฐ ์ ์ @testable import [ํ์ผ ๋ช ] ๋ผ๋ ์ฝ๋๋ฅผ ์์ฑํด์ค์ผ ํ๋ค.
@testable์ Unit Test์์ ์ค์ ์ฑ ํ๊น์ ์๋ ์ฝ๋๋ค์ ์ ๊ทผํ๊ธฐ ์ํ ํค์๋์ด๋ค.
๋ณดํต ์ฑ ์ฝ๋ ๋ด๋ถ์์๋ internal ์์ค์ ์ ๊ทผ ์ ํ์ผ๋ก ํ์ ์ ๋ง๋ค์ด์ฃผ๋ ๊ฒ์ด ์ผ๋ฐ์ ์ด๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ์ฑ ํ๊น์ ํ์ ๋ค์ ์ธ๋ถ ํ๊น์์ ์ ๊ทผํ๋ ๊ฒ์ด ๋ถ๊ฐ๋ฅํ๋ฐ, @testable์ ํ ์คํธ ํ๋ ๋์์๋ ๋ค๋ฅธ ํ๊น์ ์ฝ๋์ ์ ๊ทผํ ์ ์๋๋ก ํด์ฃผ๋ ๊ฒ์ด๋ค.
SUT (System Under Test)
Test ํด๋์ค์ ์ฒซ ์ค์ testํ ํ์ ์ ๋ฃ์ ํ๋กํผํฐ๋ฅผ ๋ง๋ ๋ค.
setUpWithError๊ฐ ๋จผ์ ํธ์ถ๋๋๊น ์ฌ๊ธฐ์ ํ๋กํผํฐ๋ฅผ ์ด๊ธฐํ ํด์ค๋ค.
tearDownWithError๊ฐ ๋ง์ง๋ง์ ํธ์ถ๋๋ฉฐ ํ๋กํผํฐ๋ฅผ nil๋ก ๋ฐ๊ฟ์ค๋ค.
๋ง์ง๋ง์ nil๋ก ๋ง๋ค๊ธฐ ๋๋ฌธ์ ์ด ํ๋กํผํฐ๋ ์ต์ ๋๋ก ๋ง๋ค์ด์ ธ์ผ ํ๋ค.
setUpWithError์ tearDownWithError ๊ฐ ๋ด๋ถ์์ super๋ฅผ ํธ์ถํด์ฃผ๋๋ฐ ํด๋น ํ ์คํธ ํด๋์ค๊ฐ XCTestCase๋ฅผ ์์ ๋ฐ์๊ณ ๋ฉ์๋๋ค์ override ํ๊ธฐ ๋๋ฌธ์ด๋ค.
Test ํจ์
- XCTAssertEqual : ํ ์คํธ ๊ฒฐ๊ณผ ๋น๊ต
- XCTAssertGreaterThan : ๋์ ๋น๊ต
- XCTAssertNil : nil ํ๋ณ
- XCTAssertThrowsError : ๋ฌด์์ throwํ๋์ง
- XCTAssertTure : Bool ๋ฐํ ํ๋ณ
- ….
Code Coverage
Code Coverage๋ ํ ์คํธ์ ๊ฐ์น๋ฅผ ์ธก์ ํด์ฃผ๋ ํด์ด๋ค.
์ค์ ์ฑ ์ฝ๋์์ ์ด๋ ์ ๋์ ํ ์คํธ๊ฐ ์งํ๋์๋์ง ์ ์ ์๋ ํด์ด๋ค.
์์ธํ ๋ด์ฉ์…
https://zeddios.tistory.com/1141
ํ ์คํธ ๋๋ธ
ํ ์คํธ ๋๋ธ์ด๋ ํ ์คํธ๋ฅผ ์งํํ๊ธฐ ์ด๋ ค์ด ๊ฒฝ์ฐ ์ด๋ฅผ ๋์ ํ์ฌ ํ ์คํธ๋ฅผ ์งํํ ์ ์๋๋ก ๋ง๋ค์ด์ฃผ๋ ๊ฐ์ฒด๋ฅผ ๋งํ๋ค. ํ ์คํธํ๋ ๋์์๋ ํ ์คํธ ๋๋ธ๊ณผ ์ค์ ๊ฐ์ฒด๋ฅผ ์ ๊น ๋ฐ๊ฟ์น๊ธฐํด์ ํ ์คํธ๋ฅผ ์งํํ๋ ๊ฒ์ด๋ค.
1. Dummy (๋ชจ์กฐ์, ๊ฐ์ง์)
Dummy๋ ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ ํ ์คํธ ๋๋ธ์ ๋๋ค. ์ด๋ค ๊ธฐ๋ฅ์ด ๊ตฌํ๋์ด ์์ง ์์, ๋จ์ง ์ธ์คํด์คํ๋ ๊ฐ์ฒด๋ก ์ฌ์ฉ๋๊ธฐ ๋๋ฌธ์ Dummy์ ๋ฉ์๋๋ ์ ์์ ์ผ๋ก ๋์ํ์ง ์์ต๋๋ค. ๊ฐ์ฒด๋ฅผ ์ ๋ฌํ๊ธฐ ์ํ ๋ชฉ์ ์ผ๋ก ์ฃผ๋ก ์ฌ์ฉ๋ฉ๋๋ค.
2. Stub (์ฐ๋ค ๋จ์ ๋ฌผ๊ฑด์ ํ ๋ง, ๋จ์ ๋ถ๋ถ)
Stub์ Dummy๊ฐ ์ค์ ๋ก ๋์ํ๋ ๊ฒ์ฒ๋ผ ๋ง๋ค์ด ์ค์ ์ฝ๋๋ฅผ ๋์ ํด์ ๋์ํด ์ฃผ๋ ๊ฐ์ฒด์ ๋๋ค. ํ ์คํธ๊ฐ ๊ณค๋ํ ๋ถ๋ถ์ ๊ฐ์ฒด๋ฅผ ๋๋ ค๋ด์ด ๊ทธ ์ญํ ์ ์ต์ํ์ผ๋ก ๋์ ํด ์ค ๋งํผ๋ง ๊ฐ๋จํ๊ฒ ๊ตฌํ๋์ด ์์ต๋๋ค.
3. Fake
Fake๋ Stub๋ณด๋ค ๊ตฌ์ฒด์ ์ผ๋ก ๋์ํด์ ์ค์ ๋ก์ง์ฒ๋ผ ๋ณด์ด์ง๋ง ์ค์ ์ฑ์ ๋์์์๋ ์ ํฉํ์ง ์์ ๊ฐ์ฒด๋ฅผ ๋งํฉ๋๋ค. ๋ก์ง ์์ฒด๋ ์ค์ ์ฑ์ ์ฝ๋์ ๋น์ทํ์ง๋ง ๊ทธ ๋์์ ๋จ์ํํ์ฌ ๊ตฌํํ ๊ฐ์ฒด๋ฅผ Fake ๊ฐ์ฒด๋ผ๊ณ ํฉ๋๋ค.
4. Spy
Spy๋ Stub์ ์ญํ ์ ๊ฐ์ง๋ฉด์ ํธ์ถ๋ ๋ด์ฉ์ ๋ํ ๋ฐฉ๋ฒ ํน์ ๊ณผ์ ๋ฑ ์ฝ๊ฐ์ ์ ๋ณด๋ฅผ ๊ธฐ๋กํ๋ ๊ฐ์ฒด์ ๋๋ค. ์๋ฅผ ๋ค์ด, ํธ์ถ๋์๋์ง, ๋ช ๋ฒ ํธ์ถ๋์๋์ง ๋ฑ์ ๋ํ ์ ๋ณด๋ฅผ ๊ธฐ๋กํ ์ ์์ต๋๋ค.
5. Mock
์ค์ ๊ฐ์ฒด์ ๊ฐ์ฅ ๋น์ทํ๊ฒ ๊ตฌํ๋ ์์ค์ ๊ฐ์ฒด๋ผ๊ณ ํ ์ ์์ต๋๋ค.
Stub์ด ์ํ ๊ธฐ๋ฐ ํ ์คํธ(State Base Test)๋ผ๋ฉด Mock์ ํ์ ๊ธฐ๋ฐ ํ ์คํธ(Behavior Base Test)๋ผ๊ณ ์ด์ผ๊ธฐํ๊ธฐ๋ ํฉ๋๋ค.
์ํ ๊ธฐ๋ฐ ํ ์คํธ๋ ๋ฉ์๋๋ฅผ ํธ์ถํ๊ณ ๊ทธ ๊ฒฐ๊ณผ ๊ฐ๊ณผ ์์ ๊ฐ์ ๋น๊ตํ๋ ์์ผ๋ก ๋์ํ๋ ํ ์คํธ์ด๋ค.
ํ์ ๊ธฐ๋ฐ ํ ์คํธ๋ ์์๋๋ ํ์๋ค์ ๋ํ ์๋๋ฆฌ์ค๋ฅผ ๋ง๋ค์ด ๋๊ณ , ์๋๋ฆฌ์ค๋๋ก ๋์ํ๋์ง์ ๋ํ ์ฌ๋ถ๋ฅผ ํ์ธํ๋ค.
์์กด์ฑ ์ฃผ์ (D.I , Dependency Injection)
์์กด์ฑ ์ฃผ์ ์ ํ๋์ ๊ฐ์ฒด๊ฐ ๋ค๋ฅธ ๊ฐ์ฒด์ ์์กด์ฑ์ ์ ๊ณตํ๋ ๊ธฐ์ ๋ก ์ค์ฌ์ D.I(Dependency Injection)์ด๋ผ ํ๋ค.
์์กด์ฑ์ด๋?
class Car {
var wheel: Wheel = Wheel()
}
class Wheel {
var weight = 10
}
์ด๋ค ๊ฐ์ฒด๊ฐ ๋ด๋ถ์์ ๊ฐ์ฒด๋ฅผ ์์ฑํด ๊ฐ์ง๊ณ ์๋ ๊ฒ์ ์์กด์ฑ(Dependency)์ด๋ค.
Car๋ผ๋ ํด๋์ค๋ Wheel์ด๋ผ๋ ํด๋์ค์ ์์กดํ๊ณ ์๋ ๊ฒ์ด ๋ฉ๋๋ค.
์์กด์ฑ ์ฃผ์ ์ด๋?
class Car {
var wheel: Wheel
init(wheel: Wheel) {
self.wheel = wheel
}
}
class Wheel {
var weight = 10
}
let myWheel = Wheel()
let myCar = Car(wheel: myWheel)
๋ด๋ถ์์ ์ด๊ธฐํ๊ฐ ์ด๋ฃจ์ด์ง๋ ๊ฒ์ด ์๋๋ผ ์ธ๋ถ์์ ๊ฐ์ฒด๋ฅผ ์์ฑํ์ฌ ๋ด๋ถ์ ์ฃผ์ ํด์ฃผ๋ ๊ฒ์ด๋ค.
์ ์ฝ๋์์๋ myWheel์ ์ธ๋ถ์์ ์์ฑํ์ฌ Car๋ฅผ ์ด๊ธฐํํ ๋ myWheel์ ์ฃผ์ ์์ผ์ฃผ๊ณ ์๋ค.
์์กด์ฑ ์ฃผ์ ์ ์ ์ฌ์ฉํ๋์?
์์กด์ฑ ์ฃผ์ ์ ์ฌ์ฉํ๋ ์ด์ ๋ ๊ฐ์ฒด๊ฐ์ ๊ฒฐํฉ๋๋ฅผ ๋ฎ์ถ๊ธฐ ์ํด์์ด๋ค.
๊ฐ์ฒด ๊ฐ์ ๊ฒฐํฉ๋๊ฐ ๋ฎ์ผ๋ฉด ๋ฆฌํฉํ ๋ง์ด ์ฝ๊ณ , ํ ์คํธ ์ฝ๋ ์์ฑ์ด ์ฌ์์ง๋ค๋ ์ฅ์ ์ด ์๋ค.
ํ ์คํธ๋ฅผ ์ํ ๊ฐ์ฒด๋ฅผ ์ด์ฉํด์ ํ ์คํธ ์์ฑํ๊ธฐ
์ด๋ป๊ฒ ํ๋ฉด ๋คํธ์ํฌ๊ฐ ์๋ ํ๊ฒฝ์์ URL Session์ ๋์์ํฌ ์ ์์๊น?
URL Session ํ๋ฆ
URLSession → datatask → URLSession DataTask → resume → Networking → completion Handler
URLSession์ URLSessionDataTask๋ฅผ ๋ง๋ค์ด์ ๋คํธ์ํน์ ํตํด ์ป๊ณ ์ ํ๋ ๊ฐ์ ์ป์ด์์completionHandler๋ฅผ ์คํํด ์ฃผ๊ณ ์์ต๋๋ค. ์ฌ๊ธฐ์ Test Double์ ์ด๋ป๊ฒ ๋ง๋ค์ด์ ๋คํธ์ํน ์์ด completionHandler๋ฅผ ์คํ์ํฌ ์ ์์๊น?
ํด๊ฒฐ ๋ฐฉ์ ์์
Dummy Data → Stub URLSession → datatask → Stub URLSession DataTask → resume → completion Handler
- Networking์ผ๋ก ๋ฐ์์ค๋ ๋์ ์ง์ Data๋ฅผ ๋ง๋ค์ด์ CompletionHandler๊น์ง ์ ๋ฌํ๊ธฐ
- ๊ธฐ์กด์ URLSession๊ณผ URLSessionDataTask ์๋ฆฌ์ DummyData๋ฅผ ์ ๋ฌํ ์ ์๋ Stub ๊ฐ์ฒด ๋ง๋ค์ด์ ๋ฐ๊ฟ์น๊ธฐ
Dummy์ Stub ๋ฑ์ Test Double์ ํ์ฉํ์ฌ ๋ฏธ๋ฆฌ request์ ๋ํ ๋ต์ ์ค์ ํด๋๊ณ ์ด๋ฅผ ์ ๋ฌํ๋ ์์ผ๋ก ํ ์คํธ๋ฅผ ์งํํด๋ณผ ์ ์์ต๋๋ค. ์ฆ, ์ค์ ๋ก ํ ์คํธ์์๋ ๋คํธ์ํฌ ํต์ ์ ํ์ง ์๊ณ ํ๋ค๋ ๊ฐ์ ํ์ ํ ์คํธ๋ฅผ ์งํํด๋ณผ ์ ์์ต๋๋ค. ์ด๋ ๊ฒ ์์ฑํ ์ ์๋ค๋ฉด ๋ชจ๋ ์ํฉ์ ํต์ ํ ์ ์์ผ๋ ์ด๋ค ๋คํธ์ํฌ ํ๊ฒฝ์ด์ด๋ ์คํ์ด ๊ฐ๋ฅํ ํ ์คํธ๊ฐ ๋ ๊ฒ์ ๋๋ค.
Stub
์ฆ ,stub์ ์ค์ ์ฝ๋๋ ์์ง ์ค๋น๋์ง ๋ชปํ ์ฝ๋๋ฅผ ๋ฏธ๋ฆฌ ์ ํด์ง ๋ต๋ณ์ผ๋ก ๊ฐ์ฅํ๋ ๋งค์ปค๋์ฆ์ ๋๋ค.
Stub ํน์ง
- dummy๊ฐ์ฒด๊ฐ ์ค์ ๋ก ๋์ํ๋ ๊ฒ์ฒ๋ผ ๋ณด์ด๊ฒ ๋ง๋ค์ด ๋์ ๊ฐ์ฒด
- ์ค์ ์ฝ๋๋ ์์ง ์ค๋น๋์ง ๋ชปํ ์ฝ๋์ ํ๋์ ๊ฐ์ฅํ๋ ํ์
- ํธ์ถ์๋ฅผ ์ค์ ๊ตฌํ๋ฌผ๋ก ๋ถํฐ ๊ฒฉ๋ฆฌ์ํค๋ ๋ชฉ์ ์ผ๋ก ์ฌ์ฉ๊ฐ๋ฅ
- ์ธํฐํ์ด์ค or ๊ธฐ๋ณธํด๋์ค๊ฐ ์ต์ํ์ผ๋ก ๊ตฌํ๋ ์ํ
- ํ ์คํธ์์ ํธ์ถ๋ ์์ฒญ์ ๋ํด ๋ฏธ๋ฆฌ ์ค๋นํด๋ ๊ฒฐ๊ณผ๋ฅผ ์ ๊ณตํฉ๋๋ค.
Stub์ด ์ฃผ๋ก ์ฌ์ฉ๋๋ ๊ฒฝ์ฐ
- ๊ตฌํ์ด ๋์ง์์ ํจ์๋, ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ์ ๊ณตํ๋ ํจ์๋ฅผ ์ฌ์ฉํ๊ณ ์ ํ ๋
- ํจ์๊ฐ ๋ฐํํ๋ ๊ฐ์ ์์๋ก ์์ฑํ๊ณ ์ถ์ ๋
- ๋ณต์กํ ๋ ผ๋ฆฌ ํ๋ฆ์ ๊ฐ์ง๋ ๊ฒฝ์ฐ, ํ ์คํธ๋ฅผ ๋จ์ํ ํ๊ณ ์ถ์ ๋
- ์์กด์ฑ์ ๊ฐ์ง๋ ์ ๋์ ์๋ต์ ๋ชจ์ฌํ์ฌ ๋ ๋ฆฝ์ ์ธ ์ํ ์ํ์ ํ๊ณ ์ ํ ๋
Test Stub์ ์ฌ์ฉํ์ฌ ์ป์ ์ ์๋ ์ด์
- ์์กดํ๋๊ฒ์ ๋ํ์ฌ ๋
๋ฆฝ์ ์ผ๋ก ๊ฐ๋ฐ/ํ
์คํธ๊ฐ ๊ฐ๋ฅํฉ๋๋ค.
- interface๋ง ์กด์ฌํ๋ ๊ฒ์ stub์ผ๋ก ๊ฐ๋ฐํ๊ณ ํ ์คํธ ํ ์ ์์ต๋๋ค.
- ์ด์ดํ ํ
์คํธ๊ฐ ๊ฐ๋ฅํฉ๋๋ค.
- stub์ผ๋ก ๋ค์ํ ์๋ต๊ฒฐ๊ณผ(canned anwser) ์ผ์ด์ค๋ฅผ ๋ง๋ค์ด ํ ์คํธ ํ ์ ์์ต๋๋ค.
๐๐ป Ref
https://zeddios.tistory.com/1141