branch10480’s blog

Topics that I've learned.

iOSアプリ開発自動テストの教科書 を読んでいく 〜 26 〜

Page Object Pattern - アプリのUI変更に対応する

Page Object Patternというデザインパターンを使うとUI改修が起こることを含めた運用について改善することができる。

import XCTest
import UIKit

class LoginPage {
    // UI要素
    private let emailTxtF: XCUIElement
    private let passwordTxtF: XCUIElement
    private let loginButton: XCUIElement
    
    init(_ app: XCUIApplication) {
        emailTxtF = app.textFields["email"]
        passwordTxtF = app.textFields["password"]
        loginButton = app.buttons["login_button"]
    }
    
    /// ログイン
    func login(email: String, password: String) {
        emailTxtF.tap()
        emailTxtF.typeText(email)
        
        passwordTxtF.tap()
        passwordTxtF.typeText(password)
        
        loginButton.tap()
    }
}

Page Object Pattern では ページ1つにつきクラスを1つ用意。 各UI要素のプロパティは private にして外部から直接参照できないようにする。

また、そのページに対して行う操作をメソッドにまとめて外部から呼び出せるようにする。

ただ、 必ずしもすべてのUI要素のプロパティを用意しておかなくてもよい。テストコード側で必要になったときに必要分だけ定義し、影響を最小限に留めるのが大切。

今回のサンプルコードではメソッドで遷移先を返していないが、返すか返さないかはどちらかを選ぶ。

Page Object Pattern のメリット

Accessibility Identifierが変更になったり部品が追加されたりした時に、Page Object Pattern を採用していると ページクラスの変更のみで対応ができ、テストケース側は修正する必要がない

UI要素に対する複数の操作をまとめる

extensionで機能拡張を行い、よく使うメソッドをまとめるという手法も有効。

ただし、作る分学習コストが増えていくことは認識しておく必要がある。

import XCTest
import UIKit

class SampleTestCases: XCTestCase {
    func testInputText() {
        let app = XCUIApplication()
        let nicknameTxtF: XCUIElement = app.textFields["nickname"]
        nicknameTxtF.inputText("hoge")
    }
}

extension XCUIElement {
    func inputText(_ text: String) {
        tap()
        typeText(text)
    }
}

> 次回に続く