[iOS] UI Test ๊ฐ๋จํ๊ฒ ์ฌ์ฉํด๋ณด๊ธฐ
์๋ ํ์ธ์ Foma๐ ์ ๋๋ค!
์ ๋ฒ ํฌ์คํ ์ Unit Test์ ๋ํด์ ๋ค๋ค๋๋ฐ์
์ค๋์ UI๋ฅผ ํ ์คํธ ํ ์ ์๋ UI Test์ ๋ํด์ ์ ๋ฆฌ๋ฅผ ํด๋ณด๋ ค๊ณ ํฉ๋๋ค
๋ฐ๋ก ์์ํ ๊ฒ์~
UITest Bundle ๋ง๋ค๊ธฐ
Project - General ํญ์ผ๋ก ์ด๋ํ์ ์ ์ผ์ชฝ ํ๋จ ๋ถ๋ถ์ +๋ฒํผ์ ๋๋ฌ์ฃผ์ธ์.
๊ทธ๋ฆฌ๊ณค ui๋ฅผ ๊ฒ์ํ๊ณ UI Testing Bundle์ ๋ง๋ค์ด์ฃผ์ธ์.
Storyboard
์๋์ ๊ฐ์ด ํ์๊ฐ์ ํ๋ ๋ทฐ์ปจํธ๋กค๋ฌ๋ฅผ ๊ตฌ์ฑํ ๊ฑด๋ฐ์.
์ด๋ฉ์ผ ํ ์คํธํ๋,๋น๋ฐ๋ฒํธ ํ ์คํธํ๋,๋น๋ฐ๋ฒํธ ํ์ธ ํ ์คํธํ๋,ํ์๊ฐ์ ๋ฒํผ์ผ๋ก ๊ตฌ์ฑํด์ฃผ์์ต๋๋ค.
SignupViewController
IBOutlet์ ๋ชจ๋ ์ฐ๊ฒฐ์์ผ์ฃผ๊ณ
signupButton์ ๋๋ ์ ๋ ๋น๋ฐ๋ฒํธ์ ํ์ธ ๋น๋ฐ๋ฒํธ๊ฐ ๋ค๋ฅด๋ค๋ฉด ๊ฒฝ๊ณ ์ฐฝ์ ๋์ฐ๋๋ก ํ์์ต๋๋ค.
@IBOutlet weak var signupButton: UIButton!
@IBOutlet weak var repeatTF: UITextField!
@IBOutlet weak var passwordTF: UITextField!
@IBOutlet weak var emailTF: UITextField!
@IBAction func tapSignupButton(_ sender: Any) {
if passwordTF.text != repeatTF.text {
let alert = UIAlertController(title: "Error", message:"๋น๋ฐ๋ฒํธ์ ํ์ธ ๋น๋ฐ๋ฒํธ๊ฐ ๋ค๋ฆ
๋๋ค", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
DispatchQueue.main.async {
//ํ
์คํธ๋ฅผ ์ํด accessibilityIdentifier๋ฅผ ์ ํด์ค์ผํจ
alert.view.accessibilityIdentifier = "errorAlertDialog"
self.present(alert, animated: true, completion: nil)
}
}
}
UITests
UI Test Case Classs๋ฅผ ์์ฑํด์ฃผ์๊ณ
์ด๋ฆ์ SignupFlowUITests๋ก ์ง๊ฒ ์ต๋๋ค.
์์ฑ ์ ๋ฐ๋์ UITests๋ฅผ ์ฒดํฌํด์ฃผ์ธ์.
์๋์ ๊ฐ์ด ํ๋ฉด์ ์๋ ๋ชจ๋ ์์๋ค์ ์ธํ ํด์ค๋๋ค.
class SignupFlowUITests: XCTestCase {
private var app:XCUIApplication!
private var emailTF:XCUIElement!
private var passwordTF:XCUIElement!
private var repeatPasswordTF:XCUIElement!
private var signupButton:XCUIElement!
๊ทธ๋ฆฌ๊ณค setupWithError ๋ฉ์๋์ ๋ชจ๋ ์์๋ค์ ๊ฐ์ ๋ฃ์ด์ค๊ฑด๋ฐ์.
์ฌ๊ธฐ์ app.textFields[identifier] ๋ถ๋ถ์ identifier๋ฅผ ์ ํด์ค๋๋ค.
override func setUpWithError() throws {
try super.setUpWithError()
continueAfterFailure = false
app = XCUIApplication()
app.launch()
emailTF = app.textFields["emailTF"]
passwordTF = app.textFields["passwordTF"]
repeatPasswordTF = app.textFields["repeatPasswordTF"]
signupButton = app.buttons["signupButton"]
}
element์ identifier๋ฅผ ์ ํ๋ ๋ฐฉ๋ฒ์ ์ฐ์ ์คํ ๋ฆฌ๋ณด๋๋ก ์ด๋ํ์ ๋ค
์ค๋ฅธ์ชฝ 4๋ฒ์งธ ํญ์ ํด๋ฆญํ์๊ณ ์๋๋ก ๋ด๋ฆฌ๋ฉด
์๋์ ๊ฐ์ด Accessibility๊ฐ ์์๊ฑฐ์์.
์ฌ๊ธฐ์ Identifier๋ฅผ ์ ํด์ค๋๋ค.
Identifier๋ฅผ ์ ํ์ง ์๊ณ ํ๋ ค๋ฉด
UITests ํ์ผ์ ์ค๋ฅธ์ชฝ ํ๋จ์ ๋ณด๋ฉด ๋นจ๊ฐ์ ๋๊ทธ๋ผ๋ฏธ ๋ฒํผ์ด ์์๊ฑฐ์์.
์ด๊ฑธ ํด๋ฆญํ์๋ฉด ์๋ฎฌ๋ ์ดํฐ๊ฐ ๋ฐ๊ฑด๋ฐ
์ฌ๊ธฐ์ ์ํ์๋ ์๋ฆฌ๋จผํธ๋ฅผ ํด๋ฆญํ๋ฉด ์๋์ ๊ฐ์ด ํ๋ ์ด์คํ๋ ์ด๋ฆ์ผ๋ก ์์๊ฐ ํ์ดํ๋๊ณ ์ด๋ค ํ๋์ ํ์๋์ง๋ ๋ง๋ค์ด์ง๋๋ค.
XCUIApplication().textFields["email"].tap()
XCUIApplication().textFields["Password"].tap()
XCUIApplication().textFields["Repeat Password"].tap()
๋ณธ๊ฒฉ์ ์ผ๋ก ํ ์คํธ๋ฅผ ํด๋ณด๊ฒ ์ต๋๋ค.
์ ๋ ๋น๋ฐ๋ฒํธ์ ํ์ธ ๋น๋ฐ๋ฒํธ๊ฐ ๋ค๋ฅด๋ฉด ๊ฒฝ๊ณ ์ฐฝ์ ๋์ฐ๋ผ๊ณ SignupViewController์์ ๊ตฌํํด๋์์ฃ ?
๊ทธ๋์ ๋น๋ฐ๋ฒํธ์ ํ์ธ ๋น๋ฐ๋ฒํธ๊ฐ ๋ค๋ฅด๋ฉด ๊ฒฝ๊ณ ์ฐฝ์ ๋์ฐ๋์ง ํ ์คํธ ํด๋ณด๊ฒ ์ต๋๋ค.
์ด๋ ํ ํ๋์ ํ๋ผ๊ณ ๋ช ๋ น์ ๋ด๋ฆฌ๊ณ ๊ทธ์ ๋ง๋ ๊ฒฐ๊ณผ๊ณผ ๋์ค๋์ง ํ์ธํด์ค๋๋ค.
์ด๋ฉ์ผ ํ ์คํธํ๋๋ฅผ ํญํ๊ณ ์ด๋ฉ์ผ์ ์ ๋ ฅ
ํจ์ค์๋ ํ ์คํธํ๋๋ฅผ ํญํ๊ณ ํจ์ค์๋๋ฅผ ์ ๋ ฅ
ํ์ธ ํจ์ค์๋ ํ ์คํธํ๋๋ฅผ ํญํ๊ณ ํ์ธ ํจ์ค์๋ ์ ๋ ฅ
ํ์๊ฐ์ ๋ฒํผ ํญ์ ํ ๋ค ๊ฒฝ๊ณ ์ฐฝ์ด ๋จ๋์ง ํ์ธ
func testSignupViewController_DonotMatchPasswordAndRepeatPassword_PresentErrorAlertDialog() {
//Act
emailTF.tap()
emailTF.typeText("fomagran6@naver.com")
passwordTF.tap()
passwordTF.typeText("12345678")
repeatPasswordTF.tap()
repeatPasswordTF.typeText("123456")
signupButton.tap()
//Assert
XCTAssertTrue(app.alerts["errorAlertDialog"].waitForExistence(timeout: 1),"์๋ชป๋ ์ ๋ณด๋ฅผ ์
๋ ฅํ๋ฉด ๊ฒฝ๊ณ ์ฐฝ์ด ๋ ์ผํ๋๋ฐ ์๋ด์ด์")
}
cmd + u ๋ฅผ ๋๋ฌ์ ํ์ธํด๋ณด๋ฉด
์ ๊ฐ ์๋ฌด๊ฒ๋ ํ์ง ์์๋ ์๋์ผ๋ก ํ์ดํ์ ํ๊ณ ์๋์ผ๋ก ํญ์ ํ๋ฉด์ ๊ฒฝ๊ณ ์ฐฝ์ด ๋จ๋์ง ์๋จ๋์ง ํ์ธํฉ๋๋ค.
(์ง์ง ๋๋ฌด๋๋ฌด ์ ๊ธฐํ๋๋ผ๊ตฌ์...)
ํ ์คํธ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํด๋ณด๋ฉด ํจ์ค์๋์ ํ์ธ ํจ์ค์๋๊ฐ ๋ค๋ฅด๊ฒ ์ ๋ ฅ๋์ ๋ ๊ฒฝ๊ณ ์ฐฝ์ด ๋ด์ผ๋ ํต๊ณผ๊ฐ ๋๊ฑธ ๋ณผ ์ ์์ต๋๋ค.
์ค๋์ ์ด๋ ๊ฒ ๊ฐ๋จํ๊ฒ UI ํ ์คํธ๋ฅผ ํ๋ ๋ฐฉ๋ฒ์ ๋ํด์ ์์๋ณด์์ต๋๋ค.
UI ํ ์คํธ๋ ๊ฐ๋ฐ์๊ฐ ์ด๋ ํ ํ๋ฆ์ ์ ํด๋๊ณ ์ด๊ฒ์ ๋ง๊ฒ ํ๋ํ๋์ง ํ์ธํ๋ ํ ์คํธ์ธ ๊ฒ ๊ฐ์ต๋๋ค.
์ด๋ ํ ํ๋์ ์ ํด์ฃผ๊ณ ์๋์ผ๋ก ์คํํ๊ฒ ํ ๋ค ๊ฒฐ๊ณผ๋ฅผ ํ์ธํ๋ ๊ณผ์ ์ด ๋๋ฌด ์ ๊ธฐํ๊ณ ํธํ๋๋ผ๊ตฌ์.
(ํ์ง๋ง ํ ์คํธ๋ฅผ ๊ตฌํํ๊ธฐ๊น์ง๊ฐ ๋๋ฌด ๋ถํธํ์ง๋ง...ใ )
์์ผ๋ก๋ ์ด๋ ๊ฒ ํ๋ฆ์ ๋ฏธ๋ฆฌ ์ค๊ณํด๋ณด๊ณ ๋ง๊ฒ ํ๋ํ๋์ง ํ ์คํธํด๋ณธ ๋ค ์ฝ๋๋ฅผ ์์ฑํ๋ ์ต๊ด์ ๊ธธ๋ฌ์ผ๊ฒ ์ต๋๋ค.
ํน์๋ผ๋ ๊ถ๊ธํ์ ๋ถ๋ถ์ด๋ ์ง์ ํด์ฃผ์ค ๋ถ๋ถ์ด ์๋ค๋ฉด ๋๊ธ๋ก ์๋ ค์ฃผ์ธ์!