位置情報サービスを利用したアプリのテストでのTipsやハマったこと 

この記事は[トレタ Advent Calendar 2018](https://qiita.com/advent-calendar/2018/toreta)　21日目の記事です。

## はじめに
トレタでQAエンジニアをしている中村です。
今回は位置情報サービスを利用したアプリのテストでのTipsやハマったことを書いてみたいと思います。

## 環境
- Xcode10.1
- Swift4.2
- XCUTest

## 1. iOSシミュレータでの位置情報のシミュレート
知ってる方も多いと思いますが、「Debug　> Location」からプリセットされている指定の位置情報を設定できます。
<img width="716" alt="スクリーンショット 2018-12-21 0.56.36.png" src="https://qiita-image-store.s3.amazonaws.com/0/2891/c69ca07b-deb1-74c7-78e0-937cb5d02398.png">
「CustomLocation」からは緯度経度を指定して特定の位置情報を設定することも可能です。
<img width="389" alt="スクリーンショット 2018-12-21 0.56.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/2891/4fd3e52b-804d-5093-f325-5011bbfce4ea.png">

## ２. Xcodeのデバックツールバーでの位置情報のシミュレート
こちらもエンジニアの方なら当然ご存じかと思いますが、Xcode側からでも起動しているiOSシミュレータの位置情報のシミュレートが可能です。
GPXファイルを使用してのCustomLocationの追加も可能で変更も楽なのでこちらを常用している人も多いのではないでしょうか。
<img width="516" alt="スクリーンショット 2018-12-21 1.09.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/2891/037ded6f-c14e-20c1-0026-a7679628b991.png">

## 3. iOS実機でシミュレートする
QAエンジニアなので、実機でのテストはこだわりたいところです。
実機でテストを行うにあたってのシミュレート方法は@narikeiさんの記事「[iPhoneの実機で位置情報をシミュレーションする方法](https://qiita.com/narikei/items/c20d95532130e8fcdeb7)」を参考にさせて頂きました。この場を借りてお礼申し上げます:bow:

## 4. XCUITestで位置情報サービスの設定を変更する
位置情報サービスを利用したテストでは有効/無効状態での確認が必要になります。
この部分に関して大きな変更を行うことは基本的にないと思いますが、XCUITest時におけるテストの前提条件の変更するために、XCUITestの`setUp（）`で下記のようなコードを書きました。
標準アプリもbundleIdさえわかれば操作可能なのはとてもはかどりますね。

```swift
let settingsApp = XCUIApplication(bundleIdentifier: "com.apple.Preferences")
settingsApp.launch()
settingsApp.tables.cells.staticTexts["プライバシー"].tap()
settingsApp.tables.cells.staticTexts["位置情報サービス"].tap()
if (settingsApp.switches["位置情報サービス"].value == "0")  {
    settingsApp.switches["位置情報サービス"].tap()
    settingsApp.buttons["オフにする"].tap()
} else {
    settingsApp.switches["位置情報サービス"].tap()
}
// 設定画面TOPに戻すためにterminateする
settingsApp.terminate()
```

## 5. fastlane snapshotで位置情報のシミュレートができない？
XCUITestで書き上げたテストコードに対してローカルのシミュレータ、実機での動作確認も終わり、さて[fastlane snapshot](https://docs.fastlane.tools/actions/snapshot/)を使ってスクショを取るぞと意気込んでいましたが、テストが失敗してしまい、完走できません。

SnapFileで指定したschemeのTestのoptionは下記のように設定済(Run側のLocationも同様に設定)
<img width="500" alt="zIrQjAAJt01w7Wo1545290457_1545290514.png" src="https://qiita-image-store.s3.amazonaws.com/0/2891/ee21d273-0125-3458-2c2d-74e02879510f.png">

テストが失敗する箇所の手前でSnapshotを取得し、ステータスバーの位置情報アイコン確認してみると、位置情報を取得しているはずなのに白抜き表示であることがわかりました。（位置情報取得時は黒塗りつぶし表示）

<img width="500" alt="スクリーンショット 2018-12-20 17.12.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/2891/7de4f91b-2e81-c751-013a-532ce87ad5b0.png">

### 解決方法：現状特になし？:innocent:
解決策がないか探っていると古めのissueですが、下記を見つけました。

- [Test location defined in scheme settings does not work when running snapshot](https://github.com/fastlane/fastlane/issues/1678)

2015年のissueなのでXcode9以前のものであり、現状とアーキテクチャも異なることから、参考にはならないかもしれないのですが、以降類似のissueがないこととから、それほど多くのリクエストもないのかな、と諦めました。

## 6. Firebase Test Labで位置情報のシミュレートができない？
fastlane snapshotの実行が出来ず途方に暮れていたのですが、シミュレータでだめなら実機を使えるクラウドサービスならどうだろうか、というところで[Firebase Test Lab](https://firebase.google.com/products/test-lab/)を使った実行を試してみました。
Firebase Test Labで実行したテストはテスト結果としてスクリーンショットと動画が取得できるのでfastlane snapshotと同様の要件は満たせるはずです。

意気揚々と実行し結果を確認してみたところ、テストは失敗していました。
もしかしてと思い、ステータスバーの位置情報の表示を確認してみると、こちらでも白抜き表示で位置情報取得がうまくいってないことがわかりました。

<img width="500" alt="スクリーンショット 2018-12-20 16.33.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/2891/1d2275fe-bdc5-1233-aff2-ce3f434ee835.png">

テスト用にアップロードするファイルのビルド時のSchemeの設定はfastlane snapshotを試したときと同様の設定です。

### 解決方法：現状特になし？:innocent:
Firebase Test Labの情報はiOSはAndroid程多くないので検索してもなかなかヒットしてきません。
あまり情報がないということはそもそも需要がないのか、とも思いましたが、あきらめるにはまだ早いのでもう少しあがいてみたいと思います。

## 位置情報取得できない問題で今後確認していくこと
- Appiumでの実行
    - [set-geolocationのAPI](http://appium.io/docs/en/commands/session/geolocation/set-geolocation/)があるのでこれを試してみる
- 他のテスト実行クラウドサービスでの実施
    - [browserstack](https://www.browserstack.com/)の[App Automate](https://www.browserstack.com/app-automate)を試したが、Firebase Test Labと同様だった
- CircleCIで試す
- 利用しているSchemeの設定を見直す
    - 失敗している状態ではすべて同じ条件のSchemeを利用しているが、そもそもSchemeの設定内容について熟知していないので社内のiOSエンジニアにちゃんと教えてもらう
-　そもそもXcodeのバグじゃないか問題？
- Xcodeで普通にBuild＆Runした際にもたまにSimulate Locationが有効になっていないことがあった
    - [類似の事象もある模様](https://stackoverflow.com/questions/52726731/location-simulation-not-working-in-xcode-10-and-ios-12)でこれが解決しないとすべてうまくいかないかも。

## おわりに
現状うまくいっていないことは自分のスキル不足が伴って発生している可能性も多いため、だめなことを結論づけるのではなく、継続調査してうまいことXCUITestが動くように頑張りたいと思います。
こうすればうまくいきそう！という情報があればコメントいただけると幸いです。