Titaniumで作ってきたCraftBeerFanですが、Alloyで全面的に書きなおしつつこんな感じ↓でiOS7に対応させる作業を先日終えました
ひとまず申請はして、現在Waiting For Reviewになってて、この合間にあまり手を入れてないCraftBeerFanのWebアプリの方を手入れすることに決めました。
スマホアプリ版ではすでに実装してる開栓情報からの検索機能を実装しようかなと思ったけど、UI部分含めた結合テスト(っていうんですかね?)をあまりしっかりしてないので、その辺りも前から気になっていたのでそっちに力を入れることにしました。
UI自動化テストのツールに何を選ぶか?
Titanium Mobileで開発してることもあって、なるべくNode.js界隈の技術に精通してたほうが色々応用聞くと思って最近はNode.jsなツールを選定するように心がけています。
少し前にQiitaに Nightwatch.jsで自動ブラウザテストという投稿があって、Node.jsで書いたテストコードをSeleniumで実行してくれるという割と自分の求めてることが出来そうだったのでこれを試しました
環境構築
Seleniumサーバ
上記記事だと、jarファイルダウンロード・・となってましたが、Macなので、brew 使ったほうがいいかなと思ったので以下のようにしました。
~/selenium % brew install selenium-server-standalone Warning: Your Xcode (5.0.2) is outdated Please update to Xcode 5.1. Xcode can be updated from the App Store. ==> Downloading http://selenium-release.storage.googleapis.com/2.41/selenium-server-standalone-2.41.0.jar ######################################################################## 100.0% ==> Caveats To have launchd start selenium-server-standalone at login: ln -sfv /usr/local/opt/selenium-server-standalone/*.plist ~/Library/LaunchAgents Then to load selenium-server-standalone now: launchctl load ~/Library/LaunchAgents/homebrew.mxcl.selenium-server-standalone.plist Or, if you don't want/need launchctl, you can just run: selenium-server -p 4444 WARNING: launchctl will fail when run under tmux. ==> Summary 🍺 /usr/local/Cellar/selenium-server-standalone/2.41.0: 4 files, 33M, built in 11 seconds ~/selenium
最初これを見て、エイリアスを・・・と思ったけど、上記brew でインストールした時のターミナルに
To have launchd start selenium-server-standalone at login: ln -sfv /usr/local/opt/selenium-server-standalone/*.plist ~/Library/LaunchAgents Then to load selenium-server-standalone now: launchctl load ~/Library/LaunchAgents/homebrew.mxcl.selenium-server-standalone.plist Or, if you don't want/need launchctl, you can just run: selenium-server -p 4444
とあり、Mac起動時にlaunchd経由でselenium-serverを起動させる方法書いてあったので
ln -sfv /usr/local/opt/selenium-server-standalone/*.plist ~/Library/LaunchAgents
とした後に、すぐに起動させたかったので、書いてある通り
launchctl load ~/Library/LaunchAgents/homebrew.mxcl.selenium-server-standalone.plist
としました。
実際に起動してるのかどうか確認するためには、launchctlに、listオプションをつけてあげればよいみたいだったので、そのオプションをつけて実行しつつ、Unixのコマンドラインのパイプ機能をつかって、grepで、seleniumが含まれてるものだけ画面表示してみたら以下のようになったのでひとまずOKっぽい
% launchctl list|grep selenium 62199 - homebrew.mxcl.selenium-server-standalone
Nightwathc.js
すでにnpm install 出来る環境整えてるのでこっちは簡単に作業できました
~//node/nightwatchjs % sudo npm install -g nightwatch Password: npm http GET https://registry.npmjs.org/nightwatch npm http 200 https://registry.npmjs.org/nightwatch npm http GET https://registry.npmjs.org/nightwatch/-/nightwatch-0.4.17.tgz npm http 200 https://registry.npmjs.org/nightwatch/-/nightwatch-0.4.17.tgz npm http GET https://registry.npmjs.org/ejs npm http GET https://registry.npmjs.org/mkpath npm http GET https://registry.npmjs.org/minimatch npm http GET https://registry.npmjs.org/optimist npm http 200 https://registry.npmjs.org/mkpath npm http GET https://registry.npmjs.org/mkpath/-/mkpath-0.1.0.tgz npm http 200 https://registry.npmjs.org/ejs npm http 200 https://registry.npmjs.org/minimatch npm http 200 https://registry.npmjs.org/mkpath/-/mkpath-0.1.0.tgz npm http GET https://registry.npmjs.org/ejs/-/ejs-1.0.0.tgz npm http 200 https://registry.npmjs.org/optimist npm http 200 https://registry.npmjs.org/ejs/-/ejs-1.0.0.tgz npm http GET https://registry.npmjs.org/lru-cache npm http GET https://registry.npmjs.org/sigmund npm http GET https://registry.npmjs.org/wordwrap npm http GET https://registry.npmjs.org/minimist npm http 304 https://registry.npmjs.org/sigmund npm http 304 https://registry.npmjs.org/wordwrap npm http 200 https://registry.npmjs.org/minimist npm http 304 https://registry.npmjs.org/lru-cache /usr/local/bin/nightwatch -> /usr/local/lib/node_modules/nightwatch/bin/nightwatch nightwatch@0.4.17 /usr/local/lib/node_modules/nightwatch ├── mkpath@0.1.0 ├── ejs@1.0.0 ├── minimatch@0.2.14 (sigmund@1.0.0, lru-cache@2.5.0) └── optimist@0.6.1 (wordwrap@0.0.2, minimist@0.0.10)
環境整ったのでNightwatch.jsを試す
上記のQiitaの記事を参考にNightwatch.jsを試そうとしたら、こんなメッセージが出たので、Selenium FirefoxDriverが必要なように見えました
=========================== Running: Demo test Google There was an error while executing the Selenium command - enabling the --verbose option might offer more details. Cannot find firefox binary in PATH. Make sure firefox is installed. OS appears to be: MAC Build info: version: '2.41.0', revision: '3192d8a', time: '2014-03-27 17:17:32' System info: host: 'HiroshiOyamada-no-MacBook-Air.local', ip: '10.42.47.111', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.8.5', java.version: '1.6.0_65' Driver info: driver.version: FirefoxDriver
でも、最近Firefox使ってないし、Chrome使いたいのでNightwatch.jsでChromeのテストを参考にして、Chrome使う方法模索しました。
Chrome使うやり方に大分ハマった
ハマったポイントを先に書くと、ChromeのDriverをダウンロードして、それの保存先を間違っていたからでした。 どういうことかというとターミナル上で
which chromedriver
とした時に、chromedriverのロケーションが表示されるところにおけばすぐに動作したのですが、この辺りあまり深く考えず、~/Documents/chromedriverとかに置いてました
ChromeDriverのGetting startedを見てたら
Any of these steps should do the trick: include the ChromeDriver location in your PATH environment variable
という記述を見つけて、この時点で
「あ、PATHが通ってるところに置かないとダメっぽいのかな?」
というのに気づき、ひとまず/usr/sbin/にchromedriverをコピーしたら無事に実行できました
参考までにディレクトリ構成など
ディレクトリはこんな感じ
. ├── globals.json ├── reports │ ├── craftbeerfan.xml │ └── google.xml ├── screenshots └── tests ├── craftbeerfan.js └── google.js
上記ディレクトリ内のglobals.jsonはこんな感じ
{ "src_folders" : ["./tests"], "output_folder" : "./reports", "custom_commands_path" : "", "selenium" : { "start_process" : false, "server_path" : "/usr/local/Cellar/selenium-server-standalone/2.41.0/libexec/selenium-server-standalone-2.41.0.jar", "log_path" : "", "host" : "127.0.0.1", "port" : 4444 }, "test_settings" : { "default" : { "launch_url" : "http://localhost", "selenium_host" : "127.0.0.1", "selenium_port" : 4444, "silent": true, "output": true, "firefox_profile": false, "chrome_driver" : "/usr/sbin/chromedriver", "screenshots" : { "enabled" : true, "path" : "./screenshots" }, "desiredCapabilities": { "browserName": "chrome", "javascriptEnabled": true, "acceptSslCerts": true } } } }
で実行する時には以下のようにやってます。
nightwatch -c ./globals.json -t tests/google.js --verbose
--verbose オプションは付けることで、
✔ Testing if element <#main> contains text: "The Night Watch". LOG → Completed command getText (1098 ms) INFO Request: DELETE /wd/hub/session/7358e240-94be-49f9-a2af-c0ecc2fb29f8 - data: - headers: {"Content-Length":0} INFO Response 204 DELETE /wd/hub/session/7358e240-94be-49f9-a2af-c0ecc2fb29f8 {} LOG → Completed command session (582 ms) INFO FINISHED OK. 5 assertions passed. (9568 ms)
という感じで詳細の情報がターミナル上に表示されるので一応このオプション付きでやってます
CraftBeerFanの管理ページ機能の自動テストも一応動作した
上記実行できたので、今度はCraftBeerFanのWebアプリについて
- GoogleMapsが表示されることを確認する
- 管理ページにログイン出来る
という簡単なテストもやってみました。
tests/以下にcraftbeerfan.jsというファイルを作って以下のようにしました
module.exports = { setup: function() {}, teardown: function() {}, "top page": function(client) { client.url("http://craftbeer-fan.herokuapp.com/") .waitForElementVisible("body", 3000) .assert.title("CraftBeerFan") .assert.visible("#map_canvas") .end(); }, "Login": function(client) { client.url("http://craftbeer-fan.herokuapp.com/login") .waitForElementVisible("body", 3000) .setValue('input[type=text]', 'USERID') .setValue('input[type=password]', 'PASSWORD') .click('.btn-danger') .pause(1000) .assert.title("管理者サイト") .end(); } };
上記実行すると、ブラウザが勝手に起動して無事にテストもパスしました
まとめ
Seleniumは、割と昔から憧れがあったのでそれが使えるのは個人的に魅力だし、あとはテストコードをNode.jsというかJavaScriptで書けるのは自分としては扱いやすいです
Nightwathc.jsのサイト見てると、カスタマイズしてコマンド拡張もできるようなので今後はこれを使ってくことにします。