์๋ ํ์ธ์ Foma๐ ์ ๋๋ค!
์ค๋์ Xcode์์ ํ ์คํธ๋ฅผ ํ ์ ์๋ ์ ๋ํ ์คํธ์ ๋ํด์ ์์๋ณด๊ฒ ์ต๋๋ค.
์์ ๋ถํฐ ํ ์คํธ์ ๋ํ ์ค์์ฑ์ ์ ๋ง ๊ฐ์กฐ๋์๊ณ ์ ๋ ํด์ผ์ง...ํด์ผ์ง.. ํ๋ฉด์ ๋ฏธ๋ฃจ๋ค๊ฐ
์ด์ ์ผ ์ ๋๋ก ์ฌ์ฉํด๋ณด๊ณ ๊ณต๋ถํ ๊ฒ๋ค์ ์ ๋ฆฌํด๋ณด๋ ค๊ณ ํฉ๋๋ค.
๋ฐ๋ก ์์ํ ๊ฒ์~
Unit Test Bundle ๋ง๋ค๊ธฐ
๋จผ์ ์ ๋ํ ์คํธ๋ฅผ ๋ง๋๋ ๋ฐฉ๋ฒ์ ์๋์ ๊ฐ์ด ํ๋ก์ ํธ ์์ฑ์์ Include Tests ์ฒดํฌํด์ฃผ์๋ฉด ๋ฉ๋๋ค.
๋ง์ฝ์ ์ด๊ฑฐ ํ๋ก์ ํธ๋ฅผ ์ด๋ฏธ ๋ง๋ค์ด๋ฒ๋ ธ๋ค๋ฉด Project - General ํญ์ผ๋ก ์ด๋ํ์ ๋ค ์ผ์ชฝ ํ๋จ ๋ถ๋ถ์ + ๋ฒํผ์ ๋๋ฌ์ฃผ์ธ์.
๊ทธ ๋ค์ Unit์ ๊ฒ์ํ์๋ฉด Unit Testing Bundle์ด ์์๊ฑฐ์์ ์ด๊ฑธ ์ถ๊ฐํด์ค๋๋ค.
Unit Test ํ์ผ ๋ง๋ค๊ธฐ
UnitTest ExampleTests๊ฐ ์๊ฒผ์๊ฑฐ์์.
cmd + n ์ ๋๋ฅด์๊ณ Unit Test Case Class ํ์ผ์ ์ ํํด์ค๋๋ค.
๊ทธ๋ฆฌ๊ณ ์ด๋ฆ์ ํ ์คํธ๋ฅผ ํ๊ณ ์ถ์ ํ์ผ + Tests๋ก ์ง์ต๋๋ค.
Unit Test ์ด๊ธฐ ๋ฉ์๋
์ด๋ ๊ฒ 4๊ฐ์ง ๋ฉ์๋๊ฐ ๋ง๋ค์ด์งํ ๋ฐ์.
override func setUpWithError() throws {
// Put setup code here. This method is called before the invocation of each test method in the class.
}
override func tearDownWithError() throws {
// Put teardown code here. This method is called after the invocation of each test method in the class.
}
func testExample() throws {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct results.
}
func testPerformanceExample() throws {
// This is an example of a performance test case.
self.measure {
// Put the code you want to measure the time of here.
}
}
1. setUpWithError
ํ ์คํธ์์ ๊ฐ์ฅ ๋จผ์ ์คํ๋๋ ๋ฉ์๋๋ก ๋ณดํต ์ด๋ค ๋ชจ๋ธ์ด๋ ์์คํ ์ ์ ์ํ๋ ์ญํ ์ ํฉ๋๋ค.
2. tearDown
ํ ์คํธ์์ ๊ฐ์ฅ ๋ง์ง๋ง์ ์คํ๋๋ ๋ฉ์๋๋ก ๋ณดํต ์ ์ํ๋ ๊ฒ๋ค ํด์ ์ํค๋ ์ญํ ์ ํฉ๋๋ค.
3.testExample
ํ ์คํธ๋ฅผ ํ ์ฝ๋๋ฅผ ์์ฑํ๋ ์ญํ ์ ํฉ๋๋ค.
4. testPerformanceExample
์ฑ๋ฅ์ ํ ์คํธํ๊ณ ์ฝ๋์ ์คํ ์๋๋ฅผ ํ ์คํธํ๋ ์ญํ ์ ํฉ๋๋ค.
LoginValidator
ํ ์คํธ๋ฅผ ํ๋ ค๋ฉด ์ค์ Validator๊ฐ ์์ด์ผ๊ฒ ์ฃ ?
๊ฐ๋จํ๊ฒ ์ด๋ฉ์ผ๊ณผ ๋น๋ฐ๋ฒํธ์ ๊ธธ์ด๋ก๋ง ์ฒดํฌํด์ฃผ๋ ๋ฉ์๋๋ฅผ ์์ฑํด์ฃผ๊ฒ ์ต๋๋ค.
class LoginValidator {
func isValidEmail(email:String) -> Bool {
return email.contains("@")
}
func isValidPasword(password:String) -> Bool {
return password.count < 5
}
}
LoginValidatorTests
๊ทธ ๋ค์ LoginValidatorTests๋ก ๋์์์ ์๋์ ๊ฐ์ด ํ ์คํธ๋ฅผ ํ ํ๋ก์ ํธ๋ฅผ @testable๊ณผ import ํด์ค๋๋ค.
@testable import UnitTest_Example
ํ ์คํธ๋ฅผ ๋จผ์ ์ด๊ธฐ ์ธํ ํ๊ฒ ์ต๋๋ค.
(์ฌ๊ธฐ์ sut๋ systemUnderTest์ ์ค์๋ง๋ก ํ ์คํธ๋ฅผ ํ ํด๋์ค๋ฅผ ์ ์ํ ๋ ์ฌ์ฉ๋ฉ๋๋ค.)
class LoginValidatorTests: XCTestCase {
var sut:LoginValidator!
override func setUpWithError() throws {
sut = LoginValidator()
}
override func tearDownWithError() throws {
sut = nil
}
}
ํ ์คํธ ์ด๋ฆ ์์ฑ๋ฒ
๊ทธ๋ฆฌ๊ณค ํ ์คํธ๋ฅผ ํ ๋ฉ์๋๋ฅผ ์์ฑํด์ฃผ๋๋ฐ์.
์ฌ๊ธฐ์ ํ ์คํธ๋ฅผ ํ๋ ๋ฉ์๋์ ์ด๋ฆ์ ์์ฑํ๋ ๋ฐฉ๋ฒ์ ์๋์ ๊ฐ์ต๋๋ค.
1. ์์ test๋ฅผ ๋ถ์ด๊ณ ํ ์คํธ๋ฅผ ํ ํด๋์ค ์ด๋ฆ์ ์ ์ด์ค๋ค.
2. ํ ์คํธ๋ฅผ ํ ์ํฉ์ ๋ํด ์ค๋ช ํ๋ค.
3. ์์๋๋ ๊ฒฐ๊ณผ๋ฅผ ์ ์ด์ค๋ค.
์ฆ, ๋ก๊ทธ์ธ๋ฐธ๋ฆฌ๋ฐ์ดํฐ๋ฅผ ํ ์คํธํ ๊ฑฐ์ผ _ ์ฌ๋ฐ๋ฅธ์ด๋ฉ์ผ์ด ์ฃผ์ด์ก์๋ _ ๋ True๋ฅผ ๋ฐํํด์ผ๋ผ ๋ผ๊ณ ์ง๋ ๊ฒ์ด์ฃ .
func testLoginValidator_WhenValidEmailProvided_ShouldReturnTrue() {
}
Test ์์ฑ๋ฒ
๋จผ์ ํ ์คํธ๋ฅผ ์์ฑํ๊ธฐ ์ ์ User ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด์ฃผ๊ฒ ์ต๋๋ค.
struct User {
let email:String
let password:String
init(email:String,password:String) {
self.email = email
self.password = password
}
}
ํ ์คํธ๋ Arrange - Act - Assert ์์ผ๋ก ์์ฑํ๋๋ฐ์.
1. Arrange
ํ ์คํธ์ ํ์ํ ํด๋์ค๋ ๊ฐ์ฒด ๋ฑ์ ๋์ดํฉ๋๋ค.
2.Act
ํ ์คํธ๋ฅผ ์งํํ ์ด๋ ํ ํ๋์ ๋ํ๋ ๋๋ค.
3.Assert
Act๋ฅผ XCAssert์์ ์คํํฉ๋๋ค. (,๋ฅผ ๋ถ์ด๊ณ ๋ง์ฝ ์ํ๋ ๊ฒฐ๊ณผ๊ฐ ๋์ค์ง ์์์ ๋๋ฅผ ์๋ฌ๋ก ์๋ ค์ค ์ ์์ต๋๋ค.)
func testLoginValidator_WhenValidEmailProvided_ShouldReturnTrue() {
//Arrange
let user = User(email: "Fomagran6@naver.com", password: "1234")
//Action
let isValidEmail = sut.isValidEmail(email: user.email)
//Assert
XCTAssertTrue(isValidEmail,XCTAssertTrue(isValidEmail,"isValidEmail์ True๋ฅผ ๋ฐํํด์ผ๋๋๋ฐ False๋ฅผ ๋ฐํํ์ด @๋ฅผ ํฌํจ์์ผ์ผ ํด!"))
}
์ด๋ ๊ฒ ์์ฑํ๋ค ์ผ์ชฝ์ ๋ค์ด์๋ชฌ๋ ๋ชจ์์ผ๋ก ๋น ๋ฒํผ์ด ๋ณด์ผ๊ฑฐ์์.
๋ฒํผ์ ๋๋ฌ ์คํํด์ฃผ๋ฉด ์๋ฎฌ๋ ์ดํฐ๊ฐ ์คํ๋๋ฉด์ ํ ์คํธ๋ฅผ ์งํํ ๊ฑฐ์์. (cmd + u ๋ฅผ ๋๋ฌ๋ ์คํ๋ฉ๋๋ค.)
ํ ์คํธ๊ฐ ์์๋๋ ๊ฒฐ๊ณผ๊ฐ ์ ์์ ์ผ๋ก ๋์๋ค๋ฉด ์๋์ ๊ฐ์ด ์ด๋ก์์ผ๋ก ์ฒดํฌ๋๋ค๊ณ ๋ฐ๊ฑฐ์์.
๋ง์ฝ ์คํจํ๋ค๋ฉด ์๋์ ๊ฐ์ด ๋นจ๊ฐ์ ์์ค๋ชจ์์ผ๋ก ์คํจํ๋ค๊ณ ๋ฐ๊ฑฐ์์.
์ ์คํจํ๋์ง ์์ฑํด๋์๋ค๋ฉด ์๋์ ๊ฐ์ด ์ ์คํจํ๋์ง ์๋ ค์ค๊ฑฐ์์.
(์ฐธ๊ณ ๋ก ํ ์คํธ๊ฐ ์คํ๋๋ ์์๋ ๋์ด๋ ๋ฉ์๋์ ์์๊ฐ ์๋๋ผ ์์ฑ๋ ์ด๋ฆ์์ผ๋ก ์คํ๋ฉ๋๋ค.)
Code Coverage
์ฝ๋ ์ปค๋ฒ๋ฆฌ์ง๋ ์ค์ ๋ก ์์ฑ๋ ์ฝ๋ ์ค์์ ํ ์คํธ๋ฅผ ํ ๋น์จ์ ์๋ ค์ฃผ๋ ๊ฒ์ธ๋ฐ์.
Xcode ์ผ์ชฝํญ ์ค ๊ฐ์ฅ ๋ง์ง๋ง๋ฒ์งธ๋ฅผ ํญํ๋ฉด ์๋์ ๊ฐ์ด ๋์ฌํ ๋ฐ Coverage๋ฅผ ๋๋ฌ์ฃผ์ธ์.
์ด๋ ๊ฒ ํ๋ฉด ์๋์ ๊ฐ์ด ์ํ๋ ํด๋์ค๊ฐ ์ด๋ ์ ๋ ํ ์คํธ๊ฐ ์์ฑ๋์๋์ง ๋ณผ ์ ์์ต๋๋ค.
(์ด๋ฉ์ผ์ ํ์ธํ๋ ๊ฒ๊ณผ ํจ์ค์๋๋ฅผ ํ์ธํ๋ ๋ฉ์๋๊ฐ ์๋๋ฐ ์ ๋ ์์์ ์ด๋ฉ์ผ์ ์ฒดํฌํ๋ ํ ์คํธ๋ง ์์ฑํ์ผ๋ 50%๋ก ๋์ค๋ค์.)
์ค๋์ ์ด๋ ๊ฒ ๊ฐ๋จํ๊ฒ Unit Test๋ฅผ ํ๋ ๋ฐฉ๋ฒ์ ๋ํด์ ์์๋ณด์์ต๋๋ค.
ํ์คํ Unit Test๋ฅผ ํด์ ์ํ๋ ๋ก์ง์ด ํต๊ณผํ๋๊น ๊ทธ๋งํผ ์์ ์ ์ธ ์ฝ๋๋ฅผ ์์ฑํ๋ค๋ ๋๋์ ๋ฐ์์ต๋๋ค.
ํ์ง๋ง ์ด๋ ๊ฒ ํ๋ ํ๋ ์์ฑํ๊ณ ๊ตฌํํ๋ค๋ณด๋ ์๊ฐ์ด ๊ฝค ์ค๋๊ฑธ๋ฆฌ๊ณ ...๊ท์ฐฎ๋๋ผ๊ตฌ์...
๊ทธ๋๋ ์์ ์ ์ธ ์๋น์ค๋ฅผ ๋ง๋ค๊ธฐ ์ํด์ ํ ์คํธ๋ฅผ ์์ฑํ๋ ๊ฒ์ ๊ฝค ์ค์ํ ๋ถ๋ถ์ธ ๊ฒ ๊ฐ์ต๋๋ค.
'๐ iOS > iOS' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[iOS] TestFlight ํ ์คํธ ์ฌ์ฉ์ ์ด๋ํ๊ธฐ (0) | 2021.07.22 |
---|---|
[iOS] TestFlight ๋ฑ๋กํ๋ ๋ฐฉ๋ฒ ์์๋ณด๊ธฐ (3) | 2021.07.21 |
[iOS] ๊ฑด๊ฐ ๋ฐ์ดํฐ ์ฌ์ฉํด๋ณด๊ธฐ(feat.HealthKit) (4) | 2021.06.08 |
[iOS] ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ํ ์ด๋ธ๋ทฐ ๋ฐ์ดํฐ์์ค ๋ง๋ค๊ธฐ(Reusable TableView DataSource) (0) | 2021.06.03 |
[iOS] ๋๋ง์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ง๋ค๊ธฐ(feat. CocoaPods) (0) | 2021.05.30 |
๋๊ธ