2014年12月26日

前編:Vagrant(+ VirtualBox/Ubuntu Server 14.04)環境で Appium(Node.js)と Cucumber(Ruby)を組み合わせて Android デバイス上のアプリケーションを BDD する方法

考えるのが面倒になりキーワードだけを組み合わせたらよくわからないタイトルになりましたが、シュミレーターでは無く複数の実機上で Android アプリケーションの動作検証(受け入れ試験)をすると聞き、物理サーバー上にテスト環境をセットアップ・テスト自動化要素を評価しようと考えたけど仮想環境として作った方がチームでも共有できるし絶対に便利だよな、と思い Vagrant(VirtualBox)上でどこまで出来るか調べて見たよ、というお話です。

Android_robot


Vagrant(VirtualBox)で Ubuntu Server 14.04 環境をセットアップ


僕のラップトップで利用してる OS は Ubuntu 14.04 で Vagrant (https://www.vagrantup.com/)と VirtualBox (https://www.virtualbox.org/)がイントールされています。 ここまでは準備ができている前提でお話しますよ(Vagrant はゲスト OS 側のVirtualBox Guest Additions を自動更新してくれる vagrant-vbguest プラグインをインストールしておくのがおすすめ =>  $ vagrant plugin install vagrant-vbguest)。

さて、まず最初に自身のアカウントが VirtualBox グループ(vboxusers)と同じ権限を持っているかを確認しましょう。 権限が不足していれば /dev/vboxusb/ 以下にアクセスができず、ホスト OS に USB 接続した Android デバイスをゲスト OS 側で利用することはできません。 ホスト OS 上で $ VBoxManage list usbhost と入力して何もリストされないのはこれが原因。

次の例では僕のアカウント(netbuffalo)を vboxusers グループに追加しています。

$ sudo usermod -a -G vboxusers netbuffalo
$ cat /etc/group | grep vboxusers
vboxusers:x:125:netbuffalo


これで一度再起動(又はログアウト?)すれば貴方のアカウントで VirtualBox が Android デバイスを認識するようになります。

$ VBoxManage list usbhost
Host USB Devices:
...
UUID:               cf39baf7-fa18-4f9c-b4fe-d89d0cf5254f
VendorId:           0x0b05 (0B05) # ASUS
ProductId:          0x7781 (7781) # ZenFone5
...
Manufacturer:       Android
Product:            Android
SerialNumber:       EBAZCYXXXXXX
...


では vagrant に Ubuntu server 14.04 (trusty)のイメージ(ベース・ボックス)を登録しましょう。

$ vagrant box add ubuntu/trusty64 --provider virtualbox


適当なディレクトリを作り、仮想マシンを init。

$ mkdir testdroid
$ cd testdroid
testdroid $ vagrant init ubuntu/trusty64


起動前に init で作られた Vagrantfile を編集しときましょう。 ポイントは modifyvm で usb デバイスをオン、usbfilter で VBoxManage で確認したデバイスの vendorid (ここでは ASUS と SONY)を指定しているところ。

# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure(2) do |config|
  config.vm.box = "ubuntu/trusty64"
  config.vm.hostname = "TestDroid"
  config.vm.network "private_network", ip: "192.168.33.10"
  config.vm.provider "virtualbox" do |vb|
    vb.memory = "1024"
    vb.customize ['modifyvm', :id, '--usb', 'on']
    vb.customize ['usbfilter', 'add', '0', '--target', :id, '--name', 'ASUS', '--vendorid', '0x0b05']
    vb.customize ['usbfilter', 'add', '0', '--target', :id, '--name', 'SONY', '--vendorid', '0x0fce']
  end
end


ここからは全て仮想世界でのお話。 マシンをパワーオンして ssh で作業します。

testdroid $ vagrant up
testdroid $ vagrant ssh


今回 Vagrant Cloud から入手したイメージは環境設定が英語圏。 言語環境を ja_JP.utf8 にしましょう。

vagrant@TestDroid $ sudo apt-get install language-pack-ja
vagrant@TestDroid $ sudo update-locale LANG=ja_JP.utf8

タイムゾーンも Asia/Tokyo へ。

vagrant@TestDroid $ sudo cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
vagrant@TestDroid $ date
2014年 12月 22日 月曜日 23:20:09 JST


Java, Android SDK 環境のセットアップ


まず Oracle JDK をダウンロードして Java 実行環境から用意しましょうか。 ダウンロードしたファイルは全て ~/Downloads 配下に置くことにします。

vagrant@TestDroid $ mkdir ~/Downloads
vagrant@TestDroid $ ~/Downloads
vagrant@TestDroid $ cd Downloads
vagrant@TestDroid ~/Downloads $ wget --header "Cookie: oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/8u25-b17/jdk-8u25-linux-x64.tar.gz
vagrant@TestDroid ~/Downloads $ tar xvzf jdk-8u25-linux-x64.tar.gz
vagrant@TestDroid $ ln -s ~/Downloads/jdk1.8.0_25 ~/Downloads/jdk


~/.bashrc に JAVA_HOME を追加すればおk。

$ vi ~/.bashrc
...
# JAVA HOME
export JAVA_HOME=/home/vagrant/Downloads/jdk
export PATH=$JAVA_HOME/bin:$PATH


今後 .bashrc を編集した後は”必ず!” source で反映しましょうね。

vagrant@TestDroid $ source ~/.bashrc
vagrant@TestDroid $ java -version
java version "1.8.0_25"


Java 環境を手に入れたら次は Android SDK

vagrant@TestDroid:~/Downloads $ wget http://dl.google.com/android/android-sdk_r24.0.2-linux.tgz
vagrant@TestDroid:~/Downloads $ tar xvzf android-sdk_r24.0.2-linux.tgz


同じく ~/.bashrc に環境変数を追加します。

# ANDROID SDK
ANDROID_SDK_HOME=/home/vagrant/Downloads/android-sdk-linux
export ANDROID_HOME=$ANDROID_SDK_HOME
export PATH=$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools:$PATH


android コマンドにパスが通ったら Appium で Android アプリケーションを自動操作するのに最低限必要な platform-tools(adb)と build-tools を追加インストールします。

vagrant@TestDroid $ android update sdk --no-ui --filter tools,platform-tools,build-tools-21.1.2
  ...
  Unable to run 'adb': Cannot run program "/home/vagrant/Downloads/android-sdk-linux/platform-tools/adb": error=2, No such file or directory.
  Starting ADB server failed (code -1).
  Done. 2 packages installed.


おっと気になるメッセージが出ましたね adb へのパスは通してあるにも関わらず No such file って・・・。

答えは 32 bit アーキテクチャにも依存しているから。 次のコマンドで必要なパッケージを追加します。

vagrant@TestDroid $ sudo dpkg --add-architecture i386
vagrant@TestDroid $ sudo apt-get -qqy update
vagrant@TestDroid $ sudo apt-get -qqy install libncurses5:i386 libstdc++6:i386 zlib1g:i386


これで adb コマンドが使えるようになり、開発者モードが有効になっている(KitKat であれば設定 > 端末情報 > ソフトウェア情報 > ビルド番号を 7 回タップ) Android デバイスがあればリストされます。

vagrant@TestDroid $ adb devices
* daemon not running. starting it now on port 5037 *
* daemon started successfully *
List of devices attached
????????????    no permissions


と思いきや、僕の Zenfone 5 らしきデバイスが no permissions 表示・・・。

この理由は認識された USB デバイスに対する権限が足りず vagrant ユーザで直接アクセスできないから。 udev に Android デバイス向けの設定を追加しましょう。 Google が公開しているベンダー(メーカー)識別子(http://developer.android.com/tools/device.html#VendorIds)に基づき /etc/udev/rules.d/51-android.rules というファイルを作ります。

vagrant@Testroid $ sudo vi /etc/udev/rules.d/51-android.rules

SUBSYSTEM=="usb", ATTRS{idVendor}=="0bb4", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0e79", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0502", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0b05", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="413c", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0489", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="091e", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="18d1", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0bb4", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="12d1", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="24e3", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="2116", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0482", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="17ef", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="1004", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="22b8", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0409", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="2080", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0955", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="2257", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="10a9", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="1d4d", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0471", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="04da", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="05c6", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="1f53", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="04e8", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="04dd", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0fce", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="0930", MODE="0666"
SUBSYSTEM=="usb", ATTRS{idVendor}=="19d2", MODE="0666"


ふう、一度 udev サービスを再起動しましょう。

vagrant@TestDroid $ sudo service udev restart
udev stop/waiting
udev start/running, process 6746


USB ケーブルを抜き差しすればゲスト OS 側で認識されるはず。

vagrant@TestDroid $ adb devices
List of devices attached
EBAZCYXXXXXX    unauthorized


unauthorized は USB 接続した際に Android デバイス側で承認してあげれば大丈夫。

android_usb_debug


ここまで長かった・・・。

vagrant@TestDroid $ adb devices
List of devices attached
EBAZCYXXXXXX    device


Appium と Ruby 環境のセットアップ


Appium(Selenium for Application)
は Web アプリケーションのテスト自動化フレームワークである Selenium と同等のインタフェースを用いて iOS/Android などモバイル・アプリケーションのテストを自動化しようというプロダクト。


まずはランタイムになる Node.js 環境を用意します。

vagrant@TestDroid:~/Downloads $ wget http://nodejs.org/dist/v0.10.34/node-v0.10.34-linux-x64.tar.gz
vagrant@TestDroid $ ln -s ~/Downloads/node-v0.10.34-linux-x64 ~/Downloads/nodejs


~/.bashrc に環境変数を設定。

# NODE.JS
export NODE_HOME="/home/vagrant/Downloads/nodejs"
export PATH=$NODE_HOME/bin:$NODE_HOME/lib/node_modules/npm/bin:$PATH


node にパスが通っていることも確認しときましょう。

vagrant@TestDroid $ node -v
v0.10.34


npm(node package manager)で appium をインストール。

vagrant@TestDroid $ npm install -g appium
vagrant@TestDroid $ appium -v
1.3.4


おっと、安心してはいけません。 環境設定が不十分だとテスト・コードを走らせた際にエラーが出ちゃいます。 appium-doctor でヘルス・チェックしときましょう。

vagrant@TestDroid $ appium-doctor
Running Android Checks
✔ ANDROID_HOME is set to "/home/vagrant/Downloads/android-sdk"
✔ JAVA_HOME is set to "/home/vagrant/Downloads/jdk."
✔ ADB exists at /home/vagrant/Downloads/android-sdk/platform-tools/adb
✔ Android exists at /home/vagrant/Downloads/android-sdk/tools/android
✔ Emulator exists at /home/vagrant/Downloads/android-sdk/tools/emulator
✔ Android Checks were successful.

✔ All Checks were successful


さて Appium(Selenium)には各種言語向けにドライバが用意されているのですが、後述する BDD フレームワークに Cucumber を使う関係上 Ruby をインストールします。 気軽に Ruby 環境を切り替えられるによう rbenv を使いましょうか。

vagrant@TestDroid $ sudo apt-get install git build-essential libssl-dev
vagrant@TestDroid $ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
vagrant@TestDroid $ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build


もういい加減最後にしたい ~/.bashrc への環境変数追加。

# RBENV
export PATH="~/.rbenv/bin:$PATH"
eval "$(rbenv init -)"


rbenv にパスが通ったことを確認したら、ruby 2.1.5(インストール可能なバージョンは $ rbenv install -l で確認可能)をインストール、global な ruby にします。

vagrant@TestDroid $ rbenv -v
rbenv 0.4.0-129-g7e0e85b
vagrant@TestDroid $ rbenv install 2.1.5
vagrant@TestDroid $ rbenv global 2.1.5
vagrant@TestDroid $ ruby -v
ruby 2.1.5p273 (2014-11-13 revision 48405) [x86_64-linux]

最後に Appium サーバーとの接続に必要なドライバ類をインストールしておしまい。

vagrant@TestDroid $ gem install selenium-webdriver appium_lib --no-ri --no-rdoc


BDD (ビヘイビア駆動開発)実行環境のセットアップ


BDD(Behavior Driven Development)
の本質とは何か?という話は後して BDD を Ruby で実現する cucumber をインストール。

vagrant@TestDroid $ gem install cucumber --no-ri --no-rdoc


最後に Ruby/gem 環境をアップデートして仮想環境の構築作業は全工程が終了!

vagrant@TestDroid $ gem update

この辺で vagrant package してスナップショットを作っても良いかもしれませんね。

続きは後編で。

システムテスト自動化 標準ガイド (CodeZine BOOKS)
Mark Fewster Dorothy Graham テスト自動化研究会 伊藤 望 玉川 紘子 長谷川 孝二 きょん
翔泳社
売り上げランキング: 1,234

Jenkins実践入門 ~ビルド・テスト・デプロイを自動化する技術 (WEB+DB PRESS plus)
佐藤 聖規 和田 貴久 河村 雅人 米沢 弘樹 山岸 啓
技術評論社
売り上げランキング: 4,659

Posted by netbuffalo at 21:00│Comments(0)TrackBack(0)プログラミング | Android


この記事へのトラックバックURL

http://trackback.blogsys.jp/livedoor/netbuffalo/4935981

コメントする

名前
URL
 
  絵文字