Appium on React Native

React Native で Appium を使おうとした軌跡です。動くものはこちら ( 使い物になるとは言っていない。

https://github.com/januswel/rn-appium-sample

環境は次。

- Mac OS X 10.11.6
- Xcode 8.2
- iOS 10.2
- Appium 1.6.0
- React Native 0.39.2

ちまたの検索だと React Native なのに Ruby でテストシナリオ書いてたりしてあまり参考にならなかったので公式をもとにイチから組んでみた。

Appium
------

Selenium WebDriver API 準拠のマルチプラットフォーム対応 E2E テスティングフレームワーク。

https://github.com/appium/appium

サポートプラットフォームは iOS, Android, Windows ということで React Native の守備範囲とけっこうかぶる。

すべて Appium サーバーにリクエストを出してテストする形になるが、ざっくり動作を説明すると次のようになる。

1. Appium サーバーがシミュレーター起動
1. Appium サーバーがシミュレーターに目的のアプリをインストール
1. Appium サーバーがシミュレーターに WebDriver API を解するアプリ操作用アプリをインストール
1. テストスクリプトが Appium サーバーにもろもろの操作リクエストを出すとアプリ操作用アプリが動く

iOS でしか試していないものの動作自体はけっこう安定している。テストを流すタイミングによってはシミュレーターの終了とかちあってタイムアウトあけまでしばらくおあずけを食らうこともあるが、手元で流す分には問題なかった。

公式ドキュメントは最新の情報が整備されているが、 API などについては多くの言語で叩けることもあってかちょっと参照しづらい。

環境構築
--------

### Node.js version

バージョン 6 以上が必要とのことなので 6 の最新を使うよう設定する。チームメンバーが同じものを使えるように `avn-n` などいれて `.node-version` でバージョン固定。

```conf:.node-version
6.9.1
```

### react-native init

react-native init してプロジェクトを作る。これはいつものことですね。

```sh
react-native init AppiumSample
```

yarn 0.16.0 以上が使える状態だと yarn を使ってくれるようになったので事前に <kbd>npm install -g yarn@latest</kbd> しておくと爆速開発できる。爆速開発したくない ?

http://qiita.com/janus_wel/items/72db23fbf9e44902ca97#0380

### Appium セットアップ

公式ドキュメントや動いているものの package.json を参照すると手っ取り早い。

https://github.com/appium/appium/blob/master/docs/en/appium-setup/running-on-osx.md
https://github.com/januswel/rn-appium-sample/blob/master/package.json

```sh
yarn add appium wd --dev
```

もひとつ、 appium-doctor というコマンドが前提が揃っているかを確かめてくれるのでこれを使うといい。公式だと global install しているけど依存は少ないほうがいいのでということと、メンバーのセットアップがうまくいっているかをすぐに確かめられるのでプロジェクトの devDependencies に突っ込む。

```sh
yarn add appium-doctor --dev
$(yarn bin)/appium-doctor
```

うちの場合、環境変数がいくつか足りてなかったのでそれを追加。

```sh:.zshrc
export JAVA_HOME=$(/usr/libexec/java_home)
export PATH=${PATH}:${JAVA_HOME}/bin
```

あと Xcode 8 以降だと依存管理に carthage を使っているようなのでこれもいれろと言われる。

```sh
brew update
brew install carthage
```

### iOS simulator の authorize

https://github.com/appium/appium/blob/master/docs/en/appium-setup/running-on-osx.md#authorizing-ios-on-the-computer

> You need to do this every time you install a new version of Xcode.

と書かれているのでこれもやってしまう。

```sh
yarn global add authorize-ios
sudo authorise-ios
```

テストスクリプト
----------------

大安定の mocha で書く。今回は最低限のサンプルということで Node.js 標準の `assert` を使っている。

公式のサンプルがかなりわかりやすいが、最低限ではないので参考に最低限のテストスクリプトをてろてろ書いていく。

https://github.com/appium/sample-code/blob/master/sample-code/examples/node/ios-simple.js

WebDriver client の API リファレンスはここに。

https://github.com/admc/wd/blob/master/doc/api.md

できたものがこれ。

https://github.com/januswel/rn-appium-sample/blob/master/test/simple.js

`CONFIG.DEVICE` の `app` については実行時に指定できたほうがいいと思うが最低限ということで決め打ち。

https://github.com/januswel/rn-appium-sample/blob/master/test/simple.js#L16

このパスは `react-native run-ios` すると生成される。事前に作っておこう。もしくは Xcode 開いてビルドした結果でもよし。その場合 `~/Library/Developer/Xcode/DerivedData/` 以下に生成される。

Appium Inspector
----------------

この部分、 xpath で指定する方式だと iOS と Android で違うものを指定しないといけないので class 指定とかで逃げたかったんだけど Appium Inspector が Xcode 8 に対応していないので無理だった。

https://github.com/januswel/rn-appium-sample/blob/master/test/simple.js#L41

Appium Inspector は公式提供の Appium.app をインストールすると使えるようになるらしい。

```sh
brew cask install appium
```

https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/finding-elements.md

あと iOS 9.3 以降は XCUITest というものに変わったらしく、余計に Appium Inspector 使えないとテストがまともに書けない。 xpath で地道に `//*` から辿っていった結果がこれだよ !!

https://github.com/appium/appium/blob/master/docs/en/advanced-concepts/migrating-to-xcuitest.md

間が悪すぎる。宿題ですね。

簡単なまとめ
------------

簡単にセットアップできたものの、いま現在肝心のテストスクリプトが書けない状態なので評価しようがないというのが正直なところ。テストのためにビルドツールのバージョン下げるというのも本末転倒なので。

ただ、 Appium 含め E2E テスティングフレームワークは進化が早すぎて投資するにはまだ早いかなという印象が非常に強い。

https://speakerdeck.com/twada/from-library-to-tool-power-assert-as-a-general-purpose-assertion-enhancement-tool#5

Appium は js.foundation に移管されたということ、 WebDriver API 準拠ということもあり、今後安定していくと思っているが、専門部隊でない限りまだコスパが悪すぎる。

https://js.foundation/projects/

まずは React コンポーネントのテストを書いて地道に品質あげていくのがいいかな。

http://qiita.com/janus_wel/items/9a1d1e9e93f28bb9aaad