Swift での UI テストの雑なまとめ

# まとめ

- 公式に提供されている XCUITest を使うぞ


# XCUITest でできること
## 正しさやパフォーマンスのテストが可能

|  | 単体テスト※1 | UI テスト |
|:-----------:|:-:|:-:|
| 正しさのテスト | o | o |
| パフォーマンスのテスト | o | o |


※1 この分け方には異論があるけど、公式ではこんな表になってた


## テストの各ステップでのスナップショット

取れるらしい。
すごい。

# 登場する主要なクラス

これだけは覚えておきたい主要クラス4つ:

- [`XCUIApplication`](https://developer.apple.com/reference/xctest/xcuiapplication)
	- テスト対象のアプリケーションを起動/終了するためのプロキシ
		- テスト対象のアプリケーションは別プロセスで起動される
		- 引数と環境変数を指定可能
- [`XCUIElement`](https://developer.apple.com/reference/xctest/xcuielement)
	- テスト対象の UI 要素にタップやテキストを入力するためのプロキシ
- [`XCUIElementQuery`](https://developer.apple.com/reference/xctest/xcuielementquery)
    - アプリケーションから `XCUIElement` を取得するための検索クエリ
    - プログラマ側によってインスタンス作成はしない
        - `XCUIElementTypeQueryProvider` が要求するプロパティ群の型なので、`XCUIElement` のプロパティがこの型を持っているという意味
	- 要素の検索系:
		- 子孫要素を検索:
			- [`func descendants(matching type: XCUIElementType) -> XCUIElementQuery`](https://developer.apple.com/reference/xctest/xcuielementquery/1500659-descendants)
		- 直接の子要素を検索:
			- [`func children(matching type: XCUIElementType) -> XCUIElementQuery`](https://developer.apple.com/reference/xctest/xcuielementquery/1501006-children)
		- 指定した要素を含む要素を検索:
			- [`func containing(_ elementType: XCUIElementType, identifier: String?) -> XCUIElementQuery`](https://developer.apple.com/reference/xctest/xcuielementquery/1500995-containing)
		- 条件に当てはまる要素を検索:
			- [`func matching(_ elementType: XCUIElementType, identifier: String?) -> XCUIElementQuery`](https://developer.apple.com/reference/xctest/xcuielementquery/1500881-matching)
	- 要素の指定系:
		- 添字アクセス
			- [`subscript(key: String) -> XCUIElement { get }`](https://developer.apple.com/reference/xctest/xcuielementquery/1500776-subscript)
		- 要素番号アクセス
			- [`func element(at index: UInt) -> XCUIElement`](https://developer.apple.com/reference/xctest/xcuielementquery/1500465-element)
		- 選択された要素アクセス
			- [`var element: XCUIElement { get }`](https://developer.apple.com/reference/xctest/xcuielementquery/1500515-element)
- [`XCUIElementTypeQueryProvider`](https://developer.apple.com/reference/xctest/xcuielementtypequeryprovider)
	- `XCUIElementQuery` のショートハンド関数群を提供する protocol
		- 例えば `descendants(.button)` を `buttons` と書ける
	- [実装クラスは `XCUIElement` と `XCUIElementQuery`](https://developer.apple.com/reference/xctest/xcuielementtypequeryprovider#adopted-by)

# 評価タイミング
要素が消えちゃった後で、消えた要素の `XCUIElement` を操作したりすると死ぬので、要素の選択・検索・操作の評価タイミングを把握する必要がある:

- `XCUIElement`
    - UI への入出力系メソッドの評価時
- `XCUIElementQuery`
    - `.count` や `.allElementsBundByAccessibilityElement` などの評価時


# 参考資料

- [User Interface Testing - Guide and Sample Code](https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/testing_with_xcode/chapters/09-ui_testing.html#//apple_ref/doc/uid/TP40014132-CH13-SW1)
    - UI テストのチュートリアル
- [Testing User Interface Elements - API Reference](https://developer.apple.com/reference/xctest#2030071)
    - いつもの API リファレンス
- [UI Testing in Xcode - WWDC 2015](https://developer.apple.com/videos/play/wwdc2015/406/)
    - [Presentation Slides (PDF)](http://devstreaming.apple.com/videos/wwdc/2015/406o0doszwo8r15m/406/406_ui_testing_in_xcode.pdf?dl=1)
    - Xcode を活かした UI テストのやり方が勉強になる