今更ながらAppium使ってiOS AppのE2Eテストしてみた


[appium](https://github.com/appium/appium)

E2E試験の自動化と、アプリ->サーバーまでの動作処理のコード化をするためにappium試してみました。


作ったサンプルコードはこちら

- https://github.com/threetreeslight/appium-sample


## Require

- node v0.10

0.12系やiojsではうまく動きませんでした。
（execute書かれてないのになぁ。。。）

管理のためにもnvm経由で入れるのがオススメです。

## Install

Appiumとmochaは直で叩きたいのでglobalにいれます。

```bash
$ npm install -g appium
$ npm install -g mocha
```

動作確認。

```bash
$ appium-doctor --ios
Running iOS Checks
✔ Xcode is installed at /Applications/Xcode.app/Contents/Developer
✔ Xcode Command Line Tools are installed.
✔ DevToolsSecurity is enabled.
✔ The Authorization DB is set up properly.
✔ Node binary found using which command at /Users/ae06710/.nvm/v0.10.37/bin/node
✔ iOS Checks were successful.

✔ All Checks were successful
```

よさそう。

他に必要なライブラリ入れます。

```js
$ vim package.json
{
  "name": "appium-sample",
  "version": "1.0.0",
  "description": "appium sample spec",
  "main": "index.js",
  "repository": {
    "url": "https://github.com/threetreeslight/appium-sample.git"
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Akira Miki",
  "devDependencies": {
    // mocha用のmatcher
    "chai": "^2.1.2",
    // wdがpromis使っているので
    "chai-as-promised": "^4.3.0",
    // logを色付け
    "colors": "^1.0.3",
    // 便利メソッド使いたい
    "underscore": "^1.8.2",
    // appiumのnode client
    "wd": "^0.3.11"
  }
}

$ npm i
```

## Make .app file

単純にxcodebuild使ってbuildします。
今回はsimulatorで使うので、sdkはsimulatorでいきます。

```bash
$ xcodebuild -project appium-sample.xcodeproj \
-target appium-sample \
-configuration Debug \
-sdk iphonesimulator8.2
```

SDKの確認や、projectに設定されているtargetとかを確認したいときは以下のコマンドをどうぞ。

```bash
# Show project information
$ xcodebuild -list -project appium-sample.xcodeproj 

# Check SDK
$ xcodebuild -showsdks
```

## Make spec

こんな感じでざっくりと。

### spec/helpers/setup.js

matcherまわりのせっていをして

```
"use strict";

var wd = require("wd"),
    chai = require("chai"),
    chaiAsPromised = require("chai-as-promised")

chai.should();
chai.use(chaiAsPromised);
chaiAsPromised.transferPromiseness = wd.transferPromiseness;
```

### spec/helpers/caps.js

driverに必要なdesierを他のファイルに切り出しておいて

```
exports.ios81 = {
  browserName: '',
  'appium-version': '1.3',
  platformName: 'iOS',
  platformVersion: '8.1',
  deviceName: 'iPhone Simulator',
  app: undefined // will be set later
};
```

### spec/helpers/logging.js

logに色付けして

```js
"use strict";

exports.configure = function (driver) {
  driver.on('status', function (info) {
    console.log(info.cyan);
  });
  driver.on('command', function (meth, path, data) {
    console.log(' > ' + meth.yellow, path.grey, data || '');
  });
  driver.on('http', function (meth, path, data) {
    console.log(' > ' + meth.magenta, path, (data || '').grey);
  });
};
```

### spec/sample_spec.js

テスト書きます

```js
"use strict";

require("./helpers/setup");

var wd = require("wd"),
    _  = require("underscore");

describe("sample-spec", function () {
  this.timeout(300000);
  var driver;
  var allPassed = true;

  // setup appium driver
  before(function () {
    driver = wd.promiseChainRemote({ host: 'localhost', port: 4723 });
    require("./helpers/logging").configure(driver);

    var desired = _.clone(require("./helpers/caps").ios81);
    desired.app = __dirname + "/../build/Debug-iphonesimulator/appium-sample.app";

    return driver.init(desired);
  });


  // finallize driver
  after(function () {
    return driver.quit();
  });


  // check all passed or not
  afterEach(function () {
    allPassed = allPassed && this.currentTest.state === 'passed';
  });

  // Touch Switch and check switch value
  it("button value should be true", function () {
    return driver
      .elementByXPath("//UIAApplication[1]/UIAWindow[1]/UIASwitch[2]")
      .click()
      .getValue()
      .should.become(1);
  });

  // Another action
  it("Go background", function () {
    return driver.backgroundApp(3);
  });
});

```

## Search XPath

XPathとかが知りたい場合はappium-inspectorを使います。

段取りはこんな感じ

1. Download appium.dmg form <https://github.com/appium/appium/releases>
1. Open appium.app
1. Click apple icon and set
  - App path to builded app (almost time under the `${project_root}/build`)
  - Force Device to `iPhone Simulator`
1. Click Launch and Inspector

## Run

appium立ち上げて

```bash
$ appium
```

spec

```bash
$ mocha spec/sample_spec.js


  sample-spec
 > undefined undefined
 > undefined /session undefined
undefined
 > undefined undefined "3424d7db-1088-457a-bbb7-a5b3a5e40f81",null
 > undefined undefined
 > undefined /session/:sessionID/element undefined
 > undefined undefined {"ELEMENT":"0"}
 > undefined undefined
 > undefined /session/:sessionID/element/0/click undefined
 > undefined undefined
 > undefined undefined
 > undefined /session/:sessionID/element/0/attribute/value undefined
 > undefined undefined 1
    ✓ button value should be true (621ms)
 > undefined undefined
 > undefined /session/:sessionID/appium/app/background undefined
 > undefined undefined
    ✓ Go background (4917ms)
 > undefined undefined
 > undefined /session/:sessionID undefined
undefined
 > undefined undefined

  2 passing (23s)
```

task

```bash
$ node tasks/automation.js
```

これは便利ですね。
夢が広がります。

## こまったときは

- [UI Automation JavaScript Reference for iOS](https://developer.apple.com/library/ios/documentation/DeveloperTools/Reference/UIAutomationRef/)
- [LET THE COMMUNITY KNOW](http://appium.io/slate/en/master/?javascript#let-the-community-know)
- [KNOWN ISSUES](http://appium.io/slate/en/master/?javascript#known-issues)

ここらへん見ておくといいかもしれません。


とにもかくにもドキュメント上から下までこれ読むのがオススメです。

- http://appium.io/slate/en/master/?javascript#about-appium