Yeomanのgenerator-angularで作ったプロジェクトにE2EテストフレームワークのProtractorを導入してCoffeeScriptで書いたテストを実行する
generator-angularはkarma,jasmineのtestは用意されているけど、e2eテストはAngular Scenario Runner(非推奨)が入ってはいるものの使えるようになってないので、Protractorを入れる。
前提
yo angular --coffee でフロントエンド部を生成済みとする*1。
作業
% cd ngapp % bower uninstall -D angular-scenario % npm install -D protractor % npm install -D grunt-protractor-runner % npm install -D protractor-coffee-preprocessor % npm install -D grunt-exec % mkdir test/e2e
test/下にprotractorの設定ファイルを置いてみた
// test/protractor.conf.js "use strict"; exports.config = { // Seleniumサーバーのアドレス seleniumAddress: "http://localhost:4444/wd/hub", // テストで利用するブラウザの条件を設定 // 詳細は https://code.google.com/p/selenium/wiki/DesiredCapabilities capabilities: { browserName: "chrome" }, // テスト対象のspecファイルのパス(この設定ファイルからの相対パス) specs: [ "e2e/**/*.coffee" ], // テスト対象のアプリケーションのベースURL baseUrl: "http://localhost:9001", framework: "jasmine", plugins: [ "protractor-coffee-preprocessor" ], // Disable animations so e2e tests run more quickly onPrepare: function () { // Disable animations so e2e tests run more quickly var disableNgAnimate = function () { angular.module("disableNgAnimate", []).run(["$animate", function ($animate) { $animate.enabled(false); }]); }; browser.addMockModule("disableNgAnimate", disableNgAnimate); // Store the name of the browser that's currently being used. browser.getCapabilities().then(function (caps) { browser.params.browser = caps.get("browserName"); }); }, jasmineNodeOpts: { showColors: true, isVerbose: false, defaultTimeoutInterval: 30000 } };
Gruntfile.coffeeに追加。
# Gruntfile.coffee module.exports = (grunt) -> grunt.initConfig # ................................省略................................. # E2E test protractor: options: keepAlive: true noColor: false coffee: configFile: "test/protractor.conf.js" exec: webdriverUpdate: "node_modules/protractor/bin/webdriver-manager update" # ................................省略................................. grunt.registerTask "test", [ "exec:webdriverUpdate" # <- 追加 "clean:server" "concurrent:test" "autoprefixer" "connect:test" "karma" "protractor" # <- 追加 ]
上記は手抜きでtestのタスクに混ぜてしまっているが、ちゃんとunitテストのとは別にtest:protractorとかにしといた方がいいと思う。
正しく設定出来てテストが動くか確認のために、サンプルを用意。 こちらのを使わせていただきました。HTMLにidが入っていなかったのでそこだけ追加。
<!-- main.html--> <div class="jumbotron"> <h1>'Allo, 'Allo!</h1> <p class="lead"> <img src="images/yeoman.png" alt="I'm Yeoman"><br> Always a pleasure scaffolding your apps. </p> <p><a class="btn btn-lg btn-success" ng-href="#">Splendid!<span class="glyphicon glyphicon-ok"></span></a></p> <p><a class="btn btn-lg btn-success" ng-click="click()" id="ShowListBtn">Add List<span class="glyphicon glyphicon-ok"></span></a></p> </div> <div class="row marketing" ng-if="visibleList"> <ul id="awesomeThings" ng-repeat="awesomeThing in awesomeThings"> <li>{{awesomeThing}}</li> </ul> </div>
テスト記述
# test/e2e/main_spec.coffee 'use strict' describe 'E2ETestSample',-> beforeEach -> browser.get('/#/') it 'ボタン押下後、3つのリストが出る事の確認',-> expect(element.all(By.repeater('awesomeThing in awesomeThings')).count()).toEqual(0) button = browser.findElement(By.css('#ShowListBtn')) button.click() expect(element.all(By.repeater('awesomeThing in awesomeThings')).count()).toEqual(3)
テスト実行
% node_modules/protractor/bin/webdriver-manager update % node_modules/protractor/bin/webdriver-manager start
% grunt test
OK.
上記ではseleniumのスタートを手動で叩いているけど、seleniumをStandalone Server as a Serviceとするのが良さ気↓
- AngularJS Headless End to End Testing With Protractor and Selenium
Chefのcookbook↓ - exratione/protractor-selenium-server-cookbook · GitHub
追記
grunt testを、unit,e2e,全部実行としてみた。
# Gruntfile.coffee grunt.registerTask "test", (target) -> if target is "unit" grunt.task.run([ "clean:server" "concurrent:test" "autoprefixer" "connect:test" "karma" ]) else if target is "e2e" grunt.task.run([ "exec:webdriverUpdate" "clean:server" "concurrent:test" "autoprefixer" "connect:test" "protractor" ]) else grunt.task.run([ "exec:webdriverUpdate" "clean:server" "concurrent:test" "autoprefixer" "connect:test" "karma" "protractor" ])
これでgrunt test:unitでkarma, grunt test:e2eでprotractor, grunt testで両方実行出来る。
参考
- angular/protractor · GitHub
- AngularJS Headless End to End Testing With Protractor and Selenium
- Protractor × CoffeeScript × AngularJS (導入編) - Qiita
- AngularJSにE2Eテスト環境としてProtractorを導入する。 | Developers.IO
- Protractor: AngularJSの次世代E2Eテストフレームワーク - Qiita
*1:generator-angular