はじめに
こんにちは、suzukiです。
最近XCUITestを利用して既存のテスト内容の自動化したいと要望をいただきました。
XCUITestはあまり触れたことがないため調査の備忘もかねて、こちらで投稿させていただきます。
今回はテスト項目の最初にチュートリアルについてスワイプの動作のテストがあったため、そちらを自動化するつもりです。
XCUITestとは
XCodeが提供している、純正のUITestです。
導入方法はXCodeから簡単に可能です。
導入方法
新規作成のプロジェクトにXCUITestを追加する方法
新規プロジェクト作成時に表示される、プロジェクト名をつけるダイアログでInclude UI Testにチェックを入れましょう。
既存のプロジェクトにXCUITestを追加する方法
File>New>Targetを選択し表示されるダイアログから下記の二つのテストを追加
・iOS Unit Testing Bundle
・iOS UI Testing Bundle
オブジェクトの配置
オブジェクトの配置について
今回テストする項目
・ScrollView上のラベルが画面上に表示されているか
・Scrollが最後まで表示された画面で閉じるボタンが表示されているか
画面構成
・SCrollView
Paging ON
・BaseView
|-View * 4
|-ラベル
|-ボタン(最後のViewだけ)
UISCrollView
最初はScrollViewからテストの要素を取得予定でした。
Xcode-Version9.2ではAccessibilityの項目がないためScrollViewはStoryBoardでオートレイアウトの設定だけしています。
・UIScrollView
親のViewに対して上下左右0スペース
親のViewに対して縦・横の長さが等しい
・BaseView
SCrollViewの要素に対して上下左右0スペース
・子のView
BaseViewに対して上下を0スペース
UIScrollViewに対して縦・横の長さが等しい
隣の要素orBaseViewに対して左右0スペース
今回チュートリアルの設定を行うためPagingを忘れず設定してください。
ラベルとボタン
ラベル
・Accessibility Identifierを設定 *テストのための設定を参照
TutorialText0 ~ TutorialText3
・それぞれの画面中央に配置
ボタン
・Accessibility Identifierを設定
CloseButton
・ラベルの下の画面に配置
テストのための設定
XCUITestを利用するには目的のオブジェクトに対してAccessibility Identifierを設定する必要があります。
StoryBoardから設定するには
・オブジェクトを選択
・Identifier Inspectorを選択
・Accessibilityの項目のIdentifierに目的の名前を設定
ラベル
ラベルでは下記のような形です
こちらに設定した内容をもとにXCUITestから参照を行います。
テストコード
いよいよテスト用のコードを記述して行きます。
まずはセットアップのコードです。
SetUp
continueAfterFailure
テストで想定しないことが起きたときにテストを中断するか、続けて行うか設定できます。
XCUIApplication().launch()
テストを行うためにアプリケーションを起動します。
1 2 3 4 5 6 7 8 | override func setUp() { super.setUp() //例外が発生した場合の処理 self.continueAfterFailure = false // アプリケーションを起動 XCUIApplication().launch() // Put setup code here. This method is called before the invocation of each test method in the class. } |
オブジェクトの取得
テスト対象のインスタンスAccessibility Identifierから取得します。
ラベルのインスタンス
1 2 | //Accessibility Identifierからラベルの要素を取得 let label = XCUIApplication().staticTexts["TutorialText0"] |
ボタンのインスタンス
1 2 | //Accessibility Identifierからラベルの要素を取得 let button = XCUIApplication().buttons["CloseButton"] |
画面上に表示されているかの確認
ラベルやボタンなど現在の画面に表示されているかを確認します。
isHittableを利用し確認可能です。
今回のスクロールViewでは1ページ目に表示されているオブジェクトはtrueを返し
その他のオブジェクトはFalseを返却します。
1 2 3 4 5 6 | func testCheckLabel(){ //Accessibility Identifierからラベルの要素を取得 let label = XCUIApplication().staticTexts["TutorialText0"] //画面上に配置され表示されているかの確認 XCTAssertTrue(label.isHittable) } |
スクロールを行う
ユーザーがスクロールを行った時の動作を設定します。
・左にスワイプ
swipeLeft()
・右にスワイプ
swipeRight()
上記を対象のオブジェクトを指定して呼び出します。
1 2 3 4 5 6 7 8 | func testCheckLabel(){ //Accessibility Identifierからラベルの要素を取得 let label = XCUIApplication().staticTexts["TutorialText0"] //画面上に配置され表示されているかの確認 XCTAssertTrue(label.isHittable) //左にスワイプ XCUIApplication().swipeLeft() } |
全体のテスト
上記をもとにそのまま作成してもいいのですが、コード量が増えてしまうので下記のようにしました。
テストコードがわかりずらいとメンテナンス性も下がります。
日本語で変数やテストの内容も記述可能なのでテストしている内容がわかりやすい名前をつけたいですね。
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 31 32 33 34 35 36 37 38 | //表示されている画面のindex var index = 0 func testスワイプ動作の確認(){ labelCheck(testIndex: index) //ボタンの確認 XCTAssertFalse(XCUIApplication().buttons["CloseButton"].isHittable) doSwipe() labelCheck(testIndex: index) doSwipe() labelCheck(testIndex: index) doSwipe() labelCheck(testIndex: index) //ボタンの確認 XCTAssertTrue(XCUIApplication().buttons["CloseButton"].isHittable) } //Swipeの動作 func doSwipe(){ index += 1 XCUIApplication().swipeLeft() } //ラベルチェック用の関数 func labelCheck(testIndex: Int){ let labelMaxCount = 3 for index in 0..<labelMaxCount { let label = XCUIApplication().staticTexts["TutorialText"+"\(index)"] if index == testIndex{ //テストしたい対象が表示されているか XCTAssertTrue(label.isHittable) }else{ //テストしたい項目以外は非表示にされているか XCTAssertFalse(label.isHittable) } } } |
最後に
最後までありがとうございます。
ScrollViewのインスタンスが取得できなかったりと少し手間取りました。
XCUITestで確認できること、できないことがあるかと思います。
XCUITestで要件を満たせるものに関しては、積極的に利用していきたいですね。
また機会があれば通信周りの確認方法などもふれてみます。
RE:ENGINESブログ「iOS記事」まとめページはこちらから
参考サイト
http://tanaponchikidun.hatenablog.com/entry/2017/05/22/210735
https://qiita.com/hanawat/items/79bc81ed87704b15f3cd