agri-note inside

ウォーターセル株式会社 スマート農業システム開発部のブログです。

WebdriverIO + Appium + AWS Device FarmでCordova製iOSアプリをテストする(後編)

こんにちは、開発部の中川@Nkznです。

前回はWebdriverIO + AppiumでCordova製iOSアプリをテストする手法について解説しました。これをAWS Device Farmで動かす場合のコツを見つけたので、今回は後編として、こちらを解説します。

AWS Device Farm

AWS Device Farm(以下、Device Farm)はAmazonが管理しているAndroid/iOSデバイスを、リモートで借りて、アプリのテストに利用できるサービスです。

aws.amazon.com

iOSデバイスで自動テストを実行する場合は、次のテストフレームワークがサポートされています

  • Appium Java TestNG
  • Appium Java JUnit
  • Appium Node.js
  • Appium Python
  • Appium Ruby
  • Calabash
  • UI Automation
  • XCTest for iOS と AWS Device Farm の使用
  • XCTest UI

Node.jsでAppiumを動かすオプションがあるので、これを使えば前回のノウハウがそのまま使えそうですね。

Appiumサーバーの扱いでハマった

まずは公式ドキュメント↓のとおりに進めてみました。

docs.aws.amazon.com

Device Farmではipaファイルとテストコードのファイル(npm-bundleコマンドでまとめたtgzから作ったzip)を別々にアップロードする必要があるため、CordovaプロジェクトとWebdriverIOプロジェクトを別々に分けました。

wdio.conf.js は特に変更なしで、テスト仕様のyamlに npm test だけを追加しました。

すると、次のようなエラーが起きました。

[DeviceFarm] echo "Start Appium Node test"
Start Appium Node test
[DeviceFarm] npm test

> helloworld@1.0.0 test /private/tmp/scratchBFwg0o.scratch/test-packageRV57J1/node_modules/helloworld
> wdio wdio.conf.js


Execution of 1 spec files started at 2019-11-12T06:08:30.524Z

2019-11-12T06:08:36.017Z ERROR @wdio/appium-service: Appium exited before timeout (exit code: 2)
[35m[HTTP][39m Could not start REST http interface listener. The requested port may already be in use. Please make sure there is no other instance of this server running already.

@wdio/appium-service がAppiumの起動に失敗しているようです。

Appiumサーバーの適切な起動方法はDevice Farmのほうが詳しい

Device Farmのテスト仕様のyamlをよく見ると、Device Farm側が用意した処理の中で、Appiumコマンドを準備して、Appiumサーバーを立ち上げるところまでが済んでいます。

phases:
  install:
    commands:
      - export APPIUM_VERSION=1.9.1
      - avm $APPIUM_VERSION
      - ln -s /usr/local/avm/versions/$APPIUM_VERSION/node_modules/.bin/appium  /usr/local/avm/versions/$APPIUM_VERSION/node_modules/appium/bin/appium.js
# ...
  pre_test:
    commands:
      # We recommend starting appium server process in the background using the command below.
      # Appium server log will go to $DEVICEFARM_LOG_DIR directory.
      # The environment variables below will be auto-populated during run time.
      - echo "Start appium server"
      # The default WDA used is at DEVICEFARM_WDA_DERIVED_DATA_PATH_V1 (Supports versions iOS 12 and below), it is using commit f865d3. See (https://github.com/appium/appium-xcuitest-driver/tree/f865d32e78a5a8a15469bee30ed2f985d378575d)
      # If you need an older WDA version or need support for node modules, use the WDA at DEVICEFARM_WDA_DERIVED_DATA_PATH_V0. (This version does not suport iOS 12)
      - >-
        appium --log-timestamp --device-name $DEVICEFARM_DEVICE_NAME
        --platform-name $DEVICEFARM_DEVICE_PLATFORM_NAME --app $DEVICEFARM_APP_PATH
        --udid $DEVICEFARM_DEVICE_UDID --automation-name XCUITest
        --default-capabilities "{\"usePrebuiltWDA\": true, \"derivedDataPath\":\"$DEVICEFARM_WDA_DERIVED_DATA_PATH_V1\"}"
        >> $DEVICEFARM_LOG_DIR/appiumlog.txt 2>&1 &
# ...  

これが先に起動していたため、 @wdio/appium-service が後から起動してもポートを取れなかったという流れだったようです。

手元と同じ感覚ではダメだった

本来やりたかったのは、手元で実行したときと同じ、次の図のような流れでした。

f:id:Nkzn:20191126175059p:plain
Appium + WebdriverIOをローカル環境で実行する

しかし、どうやら @wdio/appium-service にAppiumサーバーのハンドリングを任せるのは、Device Farm環境では上手い方法ではないようです。おそらく$DEVICEFARM_****** な環境変数をwdio.conf.jsの中で呼び出す方法もありますが、デフォルトのテスト仕様yamlを大幅に書き換えることになりそうなので、避けたいところです。

また、よく考えてみると、Device Farm環境ではテストコードを実行するNode.jsと、テスト対象のデバイスが、同じホストにあるのかどうかすら、筆者は知らないことに気がつきました。ローカル環境と同じ感覚で進めても上手く行くはずがなかったのです。

Device Farmは、Device Farmに合った形で前処理・後処理を行いながら、適切なパラメータを設定してAppiumサーバーを起動してくれています。これはそのまま活かしたほうがよさそうだと判断しました。

デバイスの扱いをDevice Farmに任せる

Device FarmのAppium Node.js環境に、デフォルトで用意されているテスト仕様yamlを活かすとして、WebdriverIOの設定はどうすればよいのでしょうか。

試行錯誤の末、次のような順番で動かせばよさそうなことがわかりました。

f:id:Nkzn:20191127154757p:plain
Appium + WebdriverIOをAWS Device Farm環境で実行する

Device Farm側の動きとしては、ほとんどデフォルトのままなので、テスト仕様yamlで追加したのは npm test だけです。

# 略
# The test phase includes commands that run your test suite execution.
test:
  commands:
    - echo "Navigate to test source code"
    - cd $DEVICEFARM_TEST_PACKAGE_PATH/node_modules/*
    - echo "Start Appium Node test"
    - npm test # <= 自分で追加したのはここだけ
# 略

$ npm test で実行されるのは $ wdio wdio.conf.js なので、テストの実施はWebdriverIOに任せる形になります。

Device Farmに合わせてWebdriverIOを設定する

さて、Device Farmの環境に合わせてwdio.conf.jsを編集していくわけですが、キモとして押さえておきたいのは、次の3点です。

  • 使用するデバイスはDevice Farm側で決まる
  • Device Farm標準の方法で立ち上がったAppiumサーバーは http://0.0.0.0:4723 に配置される
  • WebdriverIOはAppiumのことをほとんど知らないまま http://0.0.0.0:4723 にWebDriver仕様のサーバーがあると信じてテストを実行する

これを踏まえて、前回作成したwdio.conf.jsを編集すると、次のような形になります。

exports.config = {
  // 略
  capabilities: [{
    platformName: 'iOS',
    bundleId: "com.example.appid",
    autoWebview: true, // $()が繋ぎにいくコンテキストをWebView優先にする
    // 使用するデバイスの指定はDevice Farm側の設定に任せる
  }],
  // services: ['appium'], // Appiumの制御はDevice Farmの標準に任せる
  port: 4723, // Appiumサーバーのデフォルトポート
  baseUrl: 'http://0.0.0.0', // Device FarmのAppiumサーバーは0.0.0.0:4723に配置される
  maxInstances: 1, // 同時に起動できるAppiumサーバーはひとつだけ
  // 略
}

デバイスの指定がなくなったため、Desired Capabilitiesがだいぶスッキリしましたね。

services の項目をなくしたので、 @wdio/appium-service は使われなくなりましたが、 baseUrlport が設定されていれば、そこにWebDriver APIがあると信じてリクエストしてくれるようです。

これで、前述の「Appium + WebdriverIOをAWS Device Farm環境で実行する」のシーケンス図の順で処理が実行されます。

余談:Appiumのバージョンをv1.15.1にしたら失敗した

本記事の執筆時点で、Appiumの最新バージョンはv1.15.1です。一方、Device Farmでデフォルトで使用されているAppiumのバージョンはv1.9.1です。

テスト仕様yamlの中では、次の場所のバージョン表記を変えることで、Appiumのバージョンを指定できます。

phases:
  install:
    commands:
      - export APPIUM_VERSION=1.9.1 # <= ここを変えるとAppiumのバージョンを変えられる
      - avm $APPIUM_VERSION
      - ln -s /usr/local/avm/versions/$APPIUM_VERSION/node_modules/.bin/appium  /usr/local/avm/versions/$APPIUM_VERSION/node_modules/appium/bin/appium.js

ローカル環境ではv1.15.1で作業していたので、Device Farmでもv1.15.1を使うことにしました。

すると、次のようなエラーが発生しました。

f:id:Nkzn:20191127175727p:plain
デバイスの検出に失敗する

どうやらデバイスが見つからなかったようです。Appiumのバージョンを戻すと元通りに動いたので、ひとまずv1.9.1で運用することにしました。

AppiumのバージョンとXcodeのバージョン(と使用可能な最新のiOSバージョン)に依存があるみたいなので、Device Farmで用意できているXcodeやiOSデバイスのバージョンが、そこまで新しくはないということかなと想像しています。

まとめ

前後編に分けて、Cordova製のiOSアプリにUIの自動テストを導入する場合のツール選択について解説しました。

WebdriverIO + Appiumの記事や、Appium + Device Farmの記事はあったのですが、すべて組み合わせた場合の記事が見つからずにだいぶ苦しみました。何とかやり方が見つかってよかったです。

WebdriverIO + AppiumでCordova製iOSアプリをテストする(前編)

こんにちは、開発部の中川@Nkznです。

Webサービスやモバイルアプリの品質保証を実施するにあたり、機種依存の不具合を見つけるために、複数のブラウザや複数のモバイルデバイスでテストを行うことがあります。弊社でも、品質管理チームが手作業で複数ブラウザ・複数デバイスへのテストに取り組んできました。

しかしながら、事業の拡大や機能の複雑化に伴い、テストにかかる時間も大きくなってきています。人を増やすという手もありますが、まずはUIテスト(主に回帰テスト)の自動化をしてみようということになりました。

そんなわけで、品質管理チームの主導で、UIテストのツールを調査しています。

Cordova製のiOSアプリをテストする

弊社ではCordova製のiOSアプリをメンテナンスしています。こちらも自動UIテストの対象になりますが、さて、どうやってWebViewにアクセスすればよいのでしょうか。

XCUITest をSwiftでゴリゴリと弄って、WebViewのインスタンスを直接触ればどうにかなりそうな気もしていますが、できれば品質管理チームの学習コストを減らしたい気持ちもあります。 Write OnceLearn Once くらいの学習コストで済みそうなソリューションが欲しいところです。

AppiumでWebViewがテストできる

いろいろ調べてみたところ、Appiumを切り口にするとよさそうなことがわかってきました。

Appiumといえば、ネイティブUI向けの自動UIテストのツールとして広く知られていますが、どうやらWebViewへの対応も進んでいるようです。まずは通常のAppiumの使い方について確認してから、WebViewの扱いについてお話ししましょう。

WebDriverの話

Appiumについて理解する上で避けて通れないのが、UI操作を自動化するための標準仕様であるWebDriverの話題です。

WebDriverは、ブラウザのUI操作を自動化するためのツールとして生まれたSeleniumの一部が標準化される形で、W3Cにより策定された仕様です。

w3c.github.io

SeleniumでのWebDriverドキュメントのひとつであるUnderstanding the components :: Documentation for Seleniumによると、いくつかの運用方法があるようですが、ここでは本記事と関係の深い Remote WebDriver についてのみ言及します。 Remote WebDriver の構成を取った場合、WebDriverの利用イメージは次の図のような形になるそうです。

f:id:Nkzn:20191122175221p:plain:w480
Remote WebDriver構成(公式ドキュメントより抜粋)

図の右下にある Remote WebDriver はWebDriver仕様を満たすREST APIを持つWebサーバーです。このWebサーバーは特定のブラウザを操作できる Driver を扱うことでブラウザの操作を実現します。

このREST APIを利用するクライアントが、図の左側にある WebDriver です(名前が紛らわしいですね)。

任意の言語や任意のテスティングフレームワークから WebDriver ライブラリを利用することで、E2Eテストを実施します。実際に利用する場合の全体図としては、次のようなイメージです。

f:id:Nkzn:20191125114916p:plain
WebDriverの世界観

XxxDriverService が前の図でいう Remote WebDriver にあたるはずです(違っていたらご指摘ください)。ChromeDriverのGetting StartedのJUnitでのサンプルを見ると、雰囲気を掴みやすいかもしれません。

各ブラウザを実際に操作する(おそらく複雑な)処理は XxxDriver が隠蔽してくれる上に、Remote WebDriver構成であれば、そこに指示を出す方法もWebDriver APIによって標準化されているため、テストコードからはブラウザの違いを意識することは少ないでしょう。最終的にWebDriver APIにアクセスできればよいので、多くの言語やライブラリが利用できるのも魅力的なところです。

また、WebDriverの仕組みが標準化され、Seleniumから切り離された結果として、WebdriverIOのようにNode.js上で動く(Selenium以外の)WebDriver向けテスティングフレームワークも登場しており、これが本記事のキモになっています。

通常のAppiumの使い方

WebDriverの話をしましたので、ようやくAppiumの話ができます。Appiumは、WebDriver API仕様のREST APIを提供するWebサーバーです*1

iOS向けのXCUITest DriverやAndroid向けのEspresso Driverを内部で扱うことで、モバイルアプリのネイティブUIに対して指示を出します。次の概要図でいうと、右半分にあたります。

f:id:Nkzn:20191125113603p:plain
Appiumの概要

指示は、外部のWebDriverクライアントからWebDriver APIに対してHTTPリクエストを行うことで実現します。

ただ、ブラウザ向けと完全に同じプロトコルというわけではなく、ブラウザ版がJSON Wire Protocolで通信するのに対して、Appiumサーバーと通信するためには、JSON Wire Protocolのモバイル向け拡張であるMobile JSON Wire Protocolでの通信をサポートする必要があります。そのため、ブラウザのUI操作の自動化とまったく同じライブラリが利用できるわけではありません。

Appiumサーバーにをサポートしているクライアントライブラリの一覧として、2019年11月現在、次のライブラリが紹介されています(ドキュメントから抜粋)。

Language/Framework Github Repo and Installation Instructions
Ruby https://github.com/appium/ruby_lib, https://github.com/appium/ruby_lib_core
Python https://github.com/appium/python-client
Java https://github.com/appium/java-client
JavaScript (Node.js) https://github.com/admc/wd
JavaScript (Node.js) https://github.com/webdriverio/webdriverio
JavaScript (Browser) https://github.com/projectxyzio/web2driver
Objective C https://github.com/appium/selenium-objective-c
PHP https://github.com/appium/php-client
C# (.NET) https://github.com/appium/appium-dotnet-driver
RobotFramework https://github.com/jollychang/robotframework-appiumlibrary

AppiumのOrganizationで管理されているものだけではなく、サードパーティー向けもいくつか存在していますね。

ここにもWebdriverIOが出てきました。

AppiumでWebViewをテストする

実は、AppiumにはWebViewのテストを行うための機能も搭載されています。

appium.io

Appiumの起動パラメータでもあるDesired Capabilitiesとして、autoWebview: true を設定しておくと、優先的にコンテキスト*2がWebViewに向いた状態でテストコードを実行できます。このモードについて、上記のサイトでは次のように言及されています。

Once the test is in a web view context the command set that is available is the full Selenium WebDriver API.

コンテキストがWebViewに向いている状態でテストを実施する場合、SeleniumのWebDriver APIがすべて使えるとのことです。ここでいうWebDriver APIは、ブラウザ向けの Remote WebDriver だと思っておけばよさそうです。

本記事での課題である、Cordova製iOSアプリ向けに使う場合には、次の図のような流れになるようです。

f:id:Nkzn:20191126111053p:plain
Appium経由でWebViewを操作する

Cordovaの中にあるWebViewに対して、ブラウザと同じAPIで操作ができそうな道筋が見えてきました。

WebdriverIOでAppiumを扱う

Appiumはどうにでもなりそうなのがわかってきたので、前述の図で左側にいた WebDriver の枠を埋めるツールを選びます。

今回は、WebdriverIOを利用することにしました。

webdriver.io

Appium側のドキュメントにも記載があったとおり、WebdriverIOはAppiumのクライアントとして利用できるライブラリです。WebdriverIOのサイトにも、Appiumのサポートが明記されています。

f:id:Nkzn:20191126114432p:plain
WebdriverIOはAppiumをサポート

構成のイメージとしては、次のような形になるでしょうか。

f:id:Nkzn:20191126115534p:plain
WebdriverIOでAppiumを操作する

概念図が具体的なツール名で埋まりました。それでは実際の使い方の話題に移っていきましょう。

利用の流れ

基本的な流れは公式のGetting StartedでChromeDriver Serviceを動かす方法と大きくは変わりません。

  1. NPMプロジェクトの devDependencies@wdio/cli をインストールする
  2. wdio.config.js を作成・整備する
  3. mochajasmineなどでテストコードを書く
  4. コマンドラインで $ npm test を実行してテストを実施する
    • $ npx wdio wdio.conf.js$ yarn wdio wdio.conf.js でも可

個別の設定の要点も見ていきましょう。

package.json

WebdriverIOからAppiumを操作する場合は、chromedriver@wdio/chromedriver-service の代わりに appium@wdio/appium-service を使用します。

// package.jsonの例
{
  // 略
  "scripts": {
    "test": "wdio wdio.conf.js"
  },
  "devDependencies": {
    "@wdio/appium-service": "^5.16.5", // <= 追加
    "@wdio/cli": "^5.16.6",
    "@wdio/local-runner": "^5.16.6",
    "@wdio/mocha-framework": "^5.16.5",
    "@wdio/spec-reporter": "^5.16.5",
    "@wdio/sync": "^5.16.5",
    "appium": "^1.15.1", // <= 追加
    // 略
  }
}

@wdio/appium-service はWebdriverIOがAppiumサーバーをハンドリングできるようにするためのプラグインです。次に出てくる wdio.conf.js でAppiumサーバーに関する設定をできるようになります。

wdio.conf.js

WebdriverIOの設定ファイルである wdio.conf.js の内容は、ブラウザ向けのそれとはかなり違った雰囲気になります。

まず、@wdio/appium-service のドキュメントにあるとおり、 servicesport を明示する必要があります。

// wdio.conf.jsの例
exports.config = {
  // 略
  // Appiumサーバー(WebDriver API)についての設定
  services: ['appium'], // @wdio/appium-serviceを利用してAppiumサーバーを立ち上げる
  port: 4723, // Appiumサーバーのデフォルトポート
  maxInstances: 1, // 同時に起動できるAppiumサーバーはひとつだけ
  // path: '/', // pathはデフォルトの挙動('/wd/hub')に任せる
  // 略
}

maxInstances: 1 は、Appiumが4723ポートに複数起動するのを防ぐために設定します。(参考: WebdriverIOでAppiumを使う勘所 - DeNA Testing Blog

次に、テスト対象についての設定であるDesired Capabilitiesを設定します。iOSシミュレータをiOS 13.2のiPhone 8で起動して、テストを実施したい場合の書き方です。

// wdio.conf.jsの例
exports.config = {
  // 略
  capabilities: [{
    // プラットフォーム設定
    platformName: 'iOS',
    automationName: 'XCUITest',
    // 使用するデバイスを指定する
    platformVersion: '13.2',
    deviceName: 'iPhone 8',
    // テスト対象のアプリの情報
    bundleId: "com.example.appid",
    app: 'path/to/MyCordovaApp/platforms/ios/build/emulator/HelloCordova.app',
    // テスト中の設定
    autoWebview: true, // コンテキストをWebView優先にする
  }],
  // 略
}

app は相対パスでも構わないため、WebdriverIOによるテストプロジェクトは、Cordovaプロジェクトと同居していても別々でも問題ありません。AWS Device Farm等でテストする場合は、別々のほうが都合がいいケースもあります。

autoWebview: true は既に解説したとおり、「アプリ内のWebViewを操作できるWebDriver API」が提供される、魔法の呪文です。

細かい調整は各々の手元で必要になるかとは思いますが、大枠としてはこのような設定があれば、WebdriverIOで実行したテストコードがAppiumを経由してCordovaアプリ内のWebViewに繋がります。

WebdriverIOの書き味が面白い

アプリ内のWebViewに繋がってしまえば、あとはChromeDriver等を使ってテストをする際と、ほとんど変わらない使用感になります。実際のテストは、次のような形になります。

const assert = require('assert');

// test/specs/button.js
describe('Button', () => {
  it('ボタンを押すとtextBoxが見えなくなる', () => {
    $('#hideButton').click();
    const textBox = $('#textBox');
    assert(textBox.isDisplayed() === false);
  });
});

jQueryのような記法でセレクタを記述すると、WebDriver上でのElementを表現できます。Elementから生えている click()を実行することでWebDriver APIに対してクリックコマンドを発行し、それを受けてAppiumがWebViewを操作する形です。

内部ではWebDriver APIをゴリゴリと叩く非同期処理になっているはずなので、本来はこういった処理を行う場合はasync/awaitを使うことになり、テストコードがawaitだらけになることでしょう(実際にAsync modeにするとそうなります)。

しかし、 @wdio/sync をインストールしておくことで、テストコードを同期的に記述できるようになっています。

{
  // ...
  "devDependencies": {
    // ...
    "@wdio/sync": "^5.16.5",
    // ...
  }
}

ドキュメントによれば、node-fibersを利用して、同期的な実行を実現しているそうです。

AndroidのEspressoのように、テストコードでやりたい操作を素直に記述できるため、とても好ましいと感じました。

To be continued...

手元のNode.jsで実行したテストコードで、Cordovaアプリ内のWebViewを操作する道筋ができました。この方法であれば、普通のWebアプリをテストする際とも共通項が多いため、学習コストを下げる効果が期待できます。

また、この方法であれば、AWS Device FarmのAppium Node.js環境でもテストが実行できます。後編の記事で話題にできればと思います。

後編の、Device Farmで利用する際のコツについて書いた記事を公開しました。

watercelldev.hatenablog.jp

サンプルコード

次のリポジトリでサンプルコードを公開しています。

github.com

参考文献

*1:公式ドキュメントのAppium Conceptsより

*2:Appiumが操作するターゲット

MOBILE CREW NIIGATA 2019にウォーターセルのエンジニアが登壇しました #mcniigata

開発部の中川@Nkznです。

2019年10月11日(金)に、MOBILE CREW NIIGATA 2019がホテルメッツ新潟で開催されました。(もう1ヶ月経ったんですね)

www.mobilecrew.jp

このイベントは、クーネルワークさん、フラー新潟支社さんと弊社の3社が共催したもので、私もスタッフとして微力ながら関わりました。

ウォーターセル社員の発表

ウォーターセルからは、モバイルエンジニアとして、渡邊と私の2名が登壇しました。スライドを簡単にご紹介します。

LiveData and DataBinding実用レポート

渡邊からは、LiveDataとDataBindingについて発表しました。もう5年近く運用されている、アグリノートのAndroidアプリに、LiveData(とViewModel)とDataBindingを組み込んだ事例の紹介です。

状態管理は多くのアプリにとって煩雑になりがちな課題です。公開から何年か経ち、十分にこなれてきた便利なライブラリたちに興味を持ってもらえれば幸いです。

地方IT企業の戦略を広げる 技術選択としてのReact Native

中川からは、アグリテックという特殊な環境におけるB2B(2B)という分野で、どんな技術選択をして戦ってきたかというお話をしました。

speakerdeck.com

発表後のパネルディスカッションでも話しましたが、モバイル運用(MobileOps)エンジニアをどうやって育てたり採用したりすればいいんだろう、というのがこの発表の先にある課題かなと思いました。

また、React Nativeだけやっていると、それはそれでスキルセットが偏りそうなので、チームメンバー全体の成長を考えると、継続的にメンテナンスするネイティブ開発のアプリも1つくらいは持っていた方がよさそう、といったことも最近は考えています。

良いイベントでした

首都圏のイベントではなかなか聞けない話題ばかりの、良いイベントになったと思います。

地方で生きているIT企業だからこそ、地方の課題を身近なものとして理解して、解決に向けて寄り添っていける。そういう企業がどんどん増えていけばいいなと思いました。

できたら来年もまたやりたいですし、そのときはまた多くの参加者の方々とお会いできるのを楽しみにしています。

Firebase App Distributionのアーリーアクセスが来ました

開発部の中川@Nkznです。

言い訳

Firebase App Distributionのアーリーアクセス権をもらえたので、触ってみた記事を書こうと思いました。しかしNDAにより中身がペラペラになりました。「App Distributionは正しくCrashlytics Betaの進化版である」に書かれた短い感想文だけが本編です。

目次

テスター向けにアプリを配布したい

モバイルアプリがある程度できてきたら、社内やベータテスターに向けて、クローズドな配布を行いたいですよね。iOSならTestFlight、AndroidならGoogle Playのクローズドトラック、といった具合に、ストアのサブ機能のような形で、公式にもテスター向けの配布がサポートされています。

ただ、TestFlightにせよ、Google Playにせよ、アップロードしてから配布が開始されるまでに時間がかかったり、審査が入ることがあったりして、内部向けに使用するにはあまり使い勝手がよくありません。Google Playの内部テスト版は配布が早いのがウリだったはずですが、なぜか審査対象になっているらしいので、やはり少し時間がかかるケースが出てきます。

私たちには、審査も変換もなく、内部向けにシュッとテスト用アプリを配布できるソリューションが必要なのです。

テスター向け配布のサードパーティサービス

モバイルアプリをテスター向けに配布するサードパーティのサービスといえば、国内での有名どころはFabricのCrashlytics BetaとDeployGateだと思います。

get.fabric.io

deploygate.com

特にCrashlytics Betaはお金もかからないので、重宝していました。

そんな中、Fabric事業がTwitter社からGoogle社へと売却されました。CrashlyticsはFirebaseへの統合が進んでいきましたが、Crashlytics Betaのロードマップがなかなか見えずに、不安な日々が続きました。

Firebase版のCrashlytics Betaがアナウンスされた

5/7にFabric Blogで、Firebase版のCrashlytics Betaともいうべき「Firebase App Distribution」がアナウンスされました。

fabric.io

これは待ち望んでいたものだったので、アーリーアクセスに応募してみたところ、4ヶ月ほどの期間を経て、本日、アーリーアクセス権をもらえました。

Firebase App Distributionとは

現状では、Firebaseの公式ドキュメントにある言葉が一番わかりやすいです。

firebase.google.com

Firebase App Distribution is the next evolution of Fabric’s Crashlytics Beta.

コンセプトは次世代版Crashlytics Betaです。Firebaseシリーズなので、紹介動画も作成されています。

www.youtube.com

これを見る限りでは、Crashlytics + Crashlytics Betaが提供していた体験がそのままFirebaseにスライドしてきたように見えます。

実際に触ってみて

ひと通り触ってみましたが、あまり言えることがありません。というのも、アーリーアクセス参加者向けに公開されている公式ドキュメントの冒頭で、釘を刺されているからです。

f:id:Nkzn:20190912142352p:plain
釘です

というわけで、詳細がわからない程度の感想文を書いて、お茶を濁したいと思います。

App Distributionは正しくCrashlytics Betaの進化版である

ひとまず、Android, iOSそれぞれに向けて配信をしてみました。

Crashlytics + Crashlytics Betaが提供していた体験がそのままFirebaseにスライドしてきたように見えます

ほぼ前述のこの言葉の通りで、Crashlytics Betaの良かったところはほぼそのままに、痒いところに手が届かなかった部分が改善されています。Betaで採用していた運用フローは、ほぼそのまま踏襲できるはずです。

特に魔法じみたことが新しく導入された様子もありません。AndroidやiOSのビルドに慣れた人ならば、問題なく利用することができるでしょう。

CI周りでも嬉しいツールが用意されていますが具体的な名前が出せません! つらい!

まとめ

具体的な内容について触れない縛りで記事を書くのは難しいということがわかりました。

ひとまず言えるのは、周辺ツールも含めて、安心してCrashlytics Betaから移行できそう*1ということです。Crashlytics Beta愛好家のみんな! 未来は明るいぞ!🎉

*1:まだ課金体系がよく見えないけど

WaterCell Tech Night #4 を開催しました

f:id:sug1t0m0_agrict:20190722183158j:plain
WaterCell Tech Night #4

こんにちは、杉山 @sug1t0m0_agrict です。

3回目からだいぶ期間が空いてしまいましたが(決まり文句担ってしまいました)、6/21日に4回目の社内開催のテックトークイベント「WaterCell Tech Night #4」が無事に開催されました。

いつもどおり、🍕と🍺と発表者を、みんなで囲み、和気あいあいと開催されました。 最重要課題でもあった、賞味期限スレスレのビールの消費を無事に達成できて幹事としても、嬉しい限りです。

「#4」も無事開催され「#5」を計画中な訳ですが、弊社内外から「このイベントを一般公開してみては?」という意見もあり心が揺れています。

以下「 #4」 のダイジェストです。 ちなみに発表順はランダムになるように毎回ガチャを回して決めています。@_yukikayukiさん、いつもご協力ありがとうございます。

業務で使えるXDを使ったクソコラ技術 @wtnb_j

「XDを使って業務を効率化しちゃおう!」という趣旨の発表でしたが、途中からクソコラ画像の作り方教室に(笑) マスク機能はUIを絡めたドキュメントを作成するときも役立ちそうです! 弊社では徐々に流行り始めていますが、プレゼン資料ももちろんXDでアニメーションもサクサクでした。

ExcelでWebAPIを叩きデータを取得する @10mikiya

speakerdeck.com

もともとExcelでWebAPIを叩くことはできたらしいんですが、Power Queryを使うことでデータの整形がとっても楽になるということでした。 また、VBAを使った画像の取得の話は、ノウハウたっぷりでした!

統計検定の思い出 @nozma

speakerdeck.com

美味しいウイスキーを飲みに行くついでに、統計検定準1級を受けてきたという話でした。 北海道の美味しそうな画像と、統計検定の難しい問題を同時に味わうことができる発表でした。 合格おめでとうございます🎉

Railsの上を好きに走る @ooooooo_q

これまでに見つけたRailsの脆弱性についての発表でした。 セキュリティのことを考えると、使わないほうがあるmethodって結構あるんですね! railsに限らず、しっかりアンテナを張っていこうと心が引き締まる思いになりました。

@sug1t0m0_agrict

speakerdeck.com

蛇足ですが、私の発表。Pythonのスクレイピング用ライブラリのScrapyとヘッドレスブラウザSplashを使ってSPAをスクレイピングするデモをしてみました。 シナリオテストの自動化とかしてみたいなと思ったり、、、

ReactのSSRをAWS Lambda上のExpressでServerlessFrameworkを使って簡単に(?)実装できた話 @kam1nchu

speakerdeck.com

サーバーレスでサーバサイドレンダリングする発表です。node.jsでサーバーを立ち上げる代替案としてLambda on Expressを使ったり,LambdaにServerlessFrameworkを使ってデプロイしたりと内容が濃い発表でした。

「JAWS-UG新潟県 第60回勉強会」登壇の裏側 @sakapun

実は翌日に「JAWS-UG新潟県 第60回勉強会」でAWSのサービスを全て説明するという発表を控えていた@sakapun さんですが、約200枚のスライドをどうやって作成したのかを裏話として教えてくれました。 発表当日もしっかりやりきっていました(笑)

HTML @circled9

speakerdeck.com 普段からHTMLを書いているのに、これまでどんな組織がHTMLの仕様に関わっていて、仕様変更がどんな感覚で行われていたのか全く知らなかったです。Web フロントエンドの1年目としてはしっかり「WHATWG Living Standard」を読んでおかなくてはいけないという気持ちになりました。

JaSST'19 Niigataにウォーターセルのエンジニアが登壇します

f:id:Nkzn:20190522145703p:plain

こんにちは、@Nkznです。

7月19日(金)に開催される「JaSST ソフトウェアテストシンポジウム 2019 新潟」に、ウォーターセルのエンジニアが登壇します。

www.jasst.jp

「実践コードレビュー」と第して、フロントエンドチームの松井が、弊社におけるコードレビューのノウハウをお話します。

弊社ではGitをバージョン管理システムとして採用しており、GitLabと組み合わせてソースコードを管理しています。また、Merge Request(GitHubでいうPull Request)を用いたコードレビュー体制を構築しています。

多くの分野にまたがったアグリテックを扱う弊社では、多くの事業が並列で動いており、社内を行き交うコードレビューも大量かつ多様を極めるものになっています。そんな混沌の中で、開発フローをどのように整えていくか、コードレビューをする/される側に立ったときに何を気をつけるのか、皆さんにお伝えできれば幸いです。

申し込みについて

JaSSTソフトウェアテストシンポジウム-JaSST'19 Niigata-参加お申込み

興味のある方は、上記のリンクからお申し込みください。

宣伝

ウォーターセル株式会社では、すべての人にスマート農業を届けるために一緒に働いてくれるエンジニアを募集しています。

water-cell.jp

JAWS-UG 新潟 #4 がウォーターセルオフィスで開催されます

f:id:Nkzn:20190522113512p:plain

こんにちは、@Nkznです。

新潟市で活動しているAWSのユーザーグループ「JAWS-UG 新潟」の第4回のイベントが、今週末、5月25日(土)に行われます。

jawsug-niigata.connpass.com

ウォーターセルもAWSのユーザー企業であり、JAWS-UG 新潟の運営にも弊社メンバーが参加しているというご縁もあって、今回はウォーターセルオフィスの1F会議スペースで開催されることになりました👏

Amazon EC2とAmazon Lightsailを使って、WordPressサイトを構築するハンズオン形式のイベントとなっています。この機会に、AWSの使いかたを学んでみるのはいかがでしょうか。

AWSに興味がある方は、connpassのイベントページからお申し込みください。

ウォーターセルのオフィスを見学してみたい方は、参加者の中に紛れ込んでいる弊社メンバーを捕まえれば、ちょっとだけご案内できます。