Xcode 7における
UIテストとカバレジ計測
2015.07.11 #yidev 第20回勉強会
@nowsprinting / Koji Hasegawa
自己紹介
• id: @nowsprinting
• フリーランス

(iOS/Androidアプリ受託開発)
• アプリ『山吹色の茸疾走』『フットサル ルールと雑学』

『電エースQuiz - 河崎実監督と特撮映画の世界』
• コミュニティ:

テスト自動化研究会、Androidテスト部、VR部
• エバンジェリスト
著書
アジェンダ
• UIテストの位置づけ
• UI Testing API
• UI recording
• Code coverage
• Test Reports
UIテストの位置づけ
テストレベル
テストレベル
テスト工程
テストレベル
テスト工程
結合度
テストレベル
開発者
QA
顧客
誰が実施するか、という区切り方
テストレベル
システムテスト(1/2)
• アプリ(.ipa)を端末にインストールし、UIを操作す
る(リリースビルド、proguard)
• サーバと通信する場合、ステージングもしくはプロ
ダクション環境を使用する(End to End)
• 一般に、独立したテストチーム(QA)が行なう
(ISTQBにおける定義)
システムテスト(2/2)
• 自動化ツール:

UI Automation, MonkeyTalk, Calabash, Appium
• E2Eなので、日時、天気、株価、為替、乱数など、
自動テストで成否判定が困難となる要因が多い
• バックエンドが のようなMBaaS
の場合、自動テスト専用のサーバインスタンスを準備
して実現できることも(ncmbでは追加費用なし)
テストレベル
ユニットテスト(1/2)
• XCTestを使用する(Xcode 5より導入)

Edit -> Add Target -> iOS Unit Testing Bundle
を選択してテストターゲットを追加する
• MVCのM(Model)を中心に、原則自動化すべき。

ただし無理にカバレッジを追わない。
ViewControllerやAppDelegateのテストは困難。
ユニットテスト(2/2)
• OCMock, OCHamcrest, Kiwiなどの補助ツール
• バックエンドが のような
MBaaSの場合、SDKをMock化してテスト
• バックエンドのAPIを直接呼び出す場合は、スタブ
サーバを利用する

NLTHTTPStubServer, OHHTTPStubs, Nocilla
テストレベル
統合テスト
• iOSアプリ開発ではユニットテストとの明確な境目
はないが、『UIを操作すること』を境界と仮定。
• XCTestを使用することで、カバレジ計測、CIまで、
まとめて実行できる
• 自動化ツール:

- これまでは、KIF(Keep It Functional)

- Xcode 7からは、iOS UI Testing Bundle
参考: Hermetic Servers
• End to Endでなく、ユニットテストのようにDIや
Mock/Stubを使うでもなく、Hermetic Serverと呼
ぶモックサーバを使用してテストを自動化する。
Hermetic==気密
• 統合テストレベルの機能テスト自動化と相性が良い
• 出典はGoogle testing blog

http://googletesting.blogspot.jp/2012/10/
hermetic-servers.html
参考: テストタイプ
• テスト活動をまとめたもの
• たとえば、機能テスト、使用性テスト、回帰テスト
など、特定のテスト目的に焦点を当てたもの
• 一つ又は複数のテストレベルで行なわれる
『ISTQB ソフトウェアテスト標準用語集 日本語版』より引用
結局、UIテストはどこで?
• システムテストレベルでの自動化はスモークテスト
にとどめる。もしくはBDD。
• UI操作を伴なう機能テストは統合テストレベル中心
に行なうのがよさそう

(iOS UI Testing Bundle + Hermetic Servers)
• それでも限界はある。あきらめ、割り切りは必要。
UI Testing API
UI Testing API
• XCTestに追加された、UI操作を行なうクラス
• XCUIApplication
• XCUIElement
• XCUIElementQuery
• Editor -> Add Target -> iOS UI Testing Bundle
でテストターゲットを追加
XCUIApplication
• XCUIElementのサブクラス
• let app = XCUIApplication()

app.launch()

で、テスト対象アプリを起動
• app.terminate() で停止
• launchArguments, launchEnvironmentを設定で
きる(未確認)
XCUIElement
• let addButton = app.buttons[ Add ]

//ヒエラルキからAddボタンを探して取得

//指定はAccessibility identifier, label, title, etc..
• addButton.tap()

//Addボタンをタップ
• XCAssertEqual(app.tables.cells.count, 1)

//UITableCellの数を取得、1個であればok
XCUIElementQuery(1/2)
• let allButtons =

app.descendantsMatchingType(.Button)

//すべてのButtonのサブクラス
• let tomCells = app.cells.containingType(

.StaticText, identifier: Tom )

//ラベル Tom を持つすべてのUITableViewCell
• XCAssertEqual(tomCells.count, 2)

//Cellの数が2であればok
XCUIElementQuery(2/2)
• XCUIElementを取り出すには、例えば、

tomCells.elementAtIndex(0)
• ヒエラルキのパスを正しく指定する必要はない(チェ
インを って検索してくれる)
• wait/sleepを考慮する必要がない。適宜waitしてUI
エレメントを探してくれる
UI recording
UI recording(1/2)
• テストメソッドにカーソルが置かれた状態で、エディ
タ下の赤丸(Record UI Test)をクリック
• iOSシミュレータでアプリが起動し、アプリに対す
る操作がテストコードに反映される
UI recording(2/2)
Record UI Test
UI Testing in Xcode (WWDC 2015 Video) より
Code coverage
Code coverage
New Features in Xcode 7 より
• スキーム設定でチェックをonにするだけで、以降のテスト実行で
コードカバレジが採取できる
• 結果はReport Navigatorで確認できる。ファイル出力について
は未調査
Test Reports
Test Reports(1/3)
• Report Navigatorを選択すると、テストの結果、
カバレジ、ログが参照できる
UI Testing in Xcode (WWDC 2015 Video) より
Report Navigator
Test Reports(2/3)
• UI Testの場合、操作ステップごとの詳細まで確認できる
UI Testing in Xcode (WWDC 2015 Video) より
Test Reports(3/3)
• ステップごとにスクリーンショットが撮影・保管さ
れており、目のマークをクリックすると表示される
UI Testing in Xcode (WWDC 2015 Video) より
まとめ
まとめ
• UI Testing APIは、統合レベルのUIテスト自動化フ
レームワークとして、KIFの代わりになりうる
• UI Testing APIとUI recordingにより、統合テスト
レベルのUIテスト自動化コストが低減されそう
• ただし、UIテストの自動化は、実行時間がかかる、
メンテコストもかかる点を忘れない。

iOS 8.x以下での回帰テストをどうするかも考慮。
参考
• UI Testing in Xcode (WWDC 2015 Video)
• Testing with Xcode
• New Features in Xcode 7

Xcode 7におけるUIテストとカバレジ計測 #yidev 第20回勉強会