cordovaで開発したiPhoneアプリをappiumでテスト(2/2)

cordovaで開発したiPhoneアプリをAppiumでテストしたので、まとめました。

cordovaで開発したiPhoneアプリをappiumでテスト(1/2)
1.目標
2.simulator用appをビルド
3.appium他のインストール
4.Appiumデスクトップのインストール
5.Appiumデクトップを起動、Inspectorウィンドウで操作の記録

cordovaで開発したiPhoneアプリをappiumでテスト(2/2)
6.nodeでテストケース作成(アプリ起動のみ)
7.テストケースの実行
8.テストケース作成(座標をタップ、スクリーンショット保存)

6.nodeでテストケース作成

githubにappium公式サンプルソースがあります。
https://github.com/appium/sample-code

sample-code/examples/node/helpers/*.js
sample-code/examples/node/ios-simple.js
sample-code/examples/node/package.json
をダウンロードして、ios-simple.jsを改造します。

/Users/taro/projects/hello/platforms/ios/appium-testcaseの下に
helpers/*.js
ios-simple.js
package.json
を保存しました。

必要なnodeモジュールをインストールします。

$ cd /Users/taro/projects/hello/platforms/ios/appium-testcase
$ npm install

beforeメソッドのdesired変数は、「4.Appiumデクトップを起動、Inspectorウィンドウで操作の記録」のdesired capbilitiesの各項目を参考に設定してください。

テストケースの内容は、アプリを起動して、1秒間表示して、終了するだけです。

ios-simple.jsを編集します。

"use strict";

require("./helpers/setup");

var wd = require("wd"),
    _ = require('underscore'),
    Q = require('q'),
    serverConfigs = require('./helpers/appium-servers');

describe("ios simple", function () {
  this.timeout(300000);
  var driver;
  var allPassed = true;

  before(function () {
    var serverConfig = process.env.npm_package_config_sauce ?
      serverConfigs.sauce : serverConfigs.local;
    driver = wd.promiseChainRemote(serverConfig);
    require("./helpers/logging").configure(driver);

    var desired = {
      "appium-version": "1.4",
      platformName: "iOS",
      deviceName: "iPhone 7",
      platformVersion: "11.0",
      automationName: "XCUITest",
      app: "/Users/taro/projects/hello/app/Applications/HelloWorld.app",
    }; 

    return driver.init(desired);
  });

  after(function () {
    return driver
      .quit()
      .finally(function () {
        if (process.env.npm_package_config_sauce) {
          return driver.sauceJobStatus(allPassed);
        }
      });
  });

  afterEach(function () {
    allPassed = allPassed && this.currentTest.state === 'passed';
  });

  it ("test_1", function () {
    return driver
      .sleep(1000)
  });

});

7.テストケースの実行

appiumサーバの起動

Appiumデスクトップで[Start Server]しておくか、または、ターミナルで

appiumサーバの起動
$ appium &

appiumサーバの停止
$ pkill -f appium

テストケースの実行

$ cd /Users/taro/projects/hello/platforms/ios/appium-testcase
$ npm run ios-simple

iPhone simulatorの終了

$ pkill -f CoreSimulator

8.テストケース作成(座標をタップ、スクリーンショット保存)

Inspectorウィンドウで、xy座標をメモしてはクリックを繰り返して、テストケースを作りました。
次のように、座標指定のタップ、スクリーンショット保存処理、AlertダイアログのOKを追加しました。

"use strict";

require("./helpers/setup");

var wd = require("wd"),
    _ = require('underscore'),
    Q = require('q'),
    serverConfigs = require('./helpers/appium-servers'),
    fs = require('fs');

describe("ios simple", function () {
  this.timeout(300000);
  var driver;
  var allPassed = true;

  before(function () {
    var serverConfig = process.env.npm_package_config_sauce ?
      serverConfigs.sauce : serverConfigs.local;
    driver = wd.promiseChainRemote(serverConfig);
    //require("./helpers/logging").configure(driver);

    var desired = {
      "appium-version": "1.4",
      platformName: "iOS",
      deviceName: "iPhone 7",
      platformVersion: "11.0",
      automationName: "XCUITest",
      app: "/Users/taro/projects/hello/app/Applications/HelloWorld.app",
    }; 

    driver.saveScreenshot = function (path) {
      return driver.takeScreenshot().then(function(data) {
        fs.writeFile(path, data, "base64", function(err) {
          if (err) {
           throw err;
          }
        });
      });
    };

    return driver.init(desired);
  });

  after(function () {
    return driver
      .quit()
      .finally(function () {
        if (process.env.npm_package_config_sauce) {
          return driver.sauceJobStatus(allPassed);
        }
      });
  });

  afterEach(function () {
    allPassed = allPassed && this.currentTest.state === 'passed';
  });

  var tap_at = function (x, y) {
    var action = new wd.TouchAction();
    return action
      .press({"x": x, "y": y})
      .wait(100)
      .release();
  }

  it ("test_1", function () {
    return driver
      .sleep(1000)
      .saveScreenshot("/Users/taro/projects/hello/platforms/ios/appium-testcase/screenshots/01.png")

      .performTouchAction(tap_at(161, 464))
      .sleep(1000)
      .saveScreenshot("/Users/taro/projects/hello/platforms/ios/appium-testcase/screenshots/02.png")

      .acceptAlert()
      .sleep(1000)
      .saveScreenshot("/Users/taro/projects/hello/platforms/ios/appium-testcase/screenshots/03.png")
  });

});

最終的に、desired変数のdeviceName、platformVersion、appやスクリーンショット保存パスは、環境変数で渡すようにしました。
また、シミュレータでの実行が思ったより遅かったので、sleepで調整しています。