Внедрение e2e- и unit-тестов в сборку AngularJS-приложения: Protractor, Karma и gulp
Допустим, у нас уже есть сборка проекта на gulp.
И нужно добавить в процедуру сборки релиза e2e-тесты на protractor.
Добавляем в зависимости protractor и gulp-protractor.
gulp/package.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
{ "name": "", "version": "0.0.1", "dependencies": { "gulp": "=3.6.2", "gulp-util": "=2.2.14", "gulp-uglify": "=0.3.0", "gulp-minify-html": "=0.1.3", "gulp-browserify": "=0.5.0", "gulp-concat": "=2.2.0", "gulp-imagemin": "=0.5.1", "gulp-clean": "=0.3.0", "gulp-livereload": "=1.5.0", "gulp-rename": "=1.2.0", "gulp-connect": "~2.0.6", "connect-route": "~0.1.4", "tiny-lr": "=0.0.7", "connect-livereload": "=0.4.0", "run-sequence": "=0.3.6", "gulp-csso": "=0.2.9", "gulp-rev": "=0.4.0", "gulp-replace": "=0.3.0", "gulp-sass": "~0.7.1", "gulp-protractor": "0.0.11", "protractor": "~1.3.1", "phantomjs": "~1.9.10", "gulp-karma": "0.0.4", "karma": "^0.12.24", "karma-chrome-launcher": "^0.1.5", "karma-firefox-launcher": "^0.1.3", "karma-jasmine": "^0.1.5", "karma-junit-reporter": "^0.2.2", "karma-phantomjs-launcher": "~0.1.4" }, "engines": { "node": "=0.10.25" }, "description": "", "main": "index.js", "authors": [ "bullgare <bullgare@>" ], "private": true, "license": "proprietary" } |
gulp/gulpfile.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
require('events').EventEmitter.prototype._maxListeners = 30; var fs = require('fs'), _path = require('path'), gulp = require('gulp'), ... connect = require('gulp-connect'), // Webserver connectRoute = require("connect-route"), protractor = require("gulp-protractor").protractor, webdriver_update = require("gulp-protractor").webdriver_update, karma = require('gulp-karma'); ... gulp.task('http-server-dev', function () { connect.server({ root: pathBuildDev, port: 9000, middleware: function (connect, opt) { return [ connectRoute(connectMockRoutes) ]; } }); console.log('Dev Server listening on http://localhost:9000'); }); gulp.task('http-server-stop', function () { connect.serverClose(); console.log('Server is shutting down'); }); ... // Downloads the selenium webdriver gulp.task('webdriver-update', webdriver_update); // Setting up the test task gulp.task('protractor'/*, ['webdriver-update']*/, function(callback) { // TODO path into variables gulp.src([pathTestsE2e + "tests/*.js"]) .pipe(protractor({ configFile: pathTestsE2e + "protractor_config.js", debug: true, args: [ //'--capabilities.browserName', 'firefox' //'--capabilities.browserName', 'chrome' '--capabilities.browserName', 'phantomjs', '--capabilities.phantomjs.binary.path', './node_modules/.bin/phantomjs' ] })) .on('error', function (e) { throw e }); }); gulp.task('e2e', ['webdriver-update', 'protractor'], function(callback) {callback();}); gulp.task('unit', function () { return gulp.src([pathBuildProd + 'js/libs.js', pathApp + 'libs/angular-mocks/angular-mocks.js', pathBuildProd + 'js/app.js', pathTestsUnit + 'tests/**/*.js']) .pipe(karma({ configFile: pathTestsUnit + 'karma_config.js', action: 'run', //browsers: ['Firefox'] browsers: ['Chrome'] } ) ) .on('error', function (err) { // Make sure failed tests cause gulp to exit non-zero throw err; }); }); ... gulp.task('build-and-test', function (callback) { runSequence( 'build', 'http-server-prod', 'unit', 'e2e', 'http-server-stop', callback); }); |
<путь к e2e-тестам>protractor_config.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// example from https://raw.github.com/angular/protractor/master/example/conf.js exports.config = { // The address of a running selenium server. seleniumServerJar: '../../scripts/gulp/node_modules/protractor/selenium/selenium-server-standalone-2.43.1.jar', // Make use you check the version in the folder //seleniumAddress: 'http://localhost:4444/wd/hub', // Capabilities to be passed to the webdriver instance. capabilities: { // this could be overwritten by --capabilities.browserName=firefox 'browserName': 'chrome' }, // Options to be passed to Jasmine-node. jasmineNodeOpts: { showColors: true, showTiming: true, defaultTimeoutInterval: 30000 } }; |
<путь к e2e-тестам>tests/spec.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
describe('my tests', function () { it('should search for address', function () { browser.get('/'); element(by.model('address.dirty')).sendKeys('тверская 8'); element(by.css('.search-submit-icon')).click(); var firstResult = element.all(by.repeater('item in addressItems | first_item')); expect(firstResult.count()).toEqual(1); expect(firstResult.get(0).getText()).toContain('улица Тверская, 8'); expect(firstResult.get(0).getText()).toContain('Россия, Москва'); var otherResults = element.all(by.repeater('item in addressItems | except_first_item')); expect(otherResults.count()).toBeGreaterThan(-1); }); it('should build routes', function () { browser.get('/#?type=routes'); element(by.model('from.title')).sendKeys('москва тверская 8'); element(by.model('from.title')).sendKeys(protractor.Key.ENTER)/*.perform()*/; element(by.model('to.title')).sendKeys('москва пушкинская 10'); element(by.model('to.title')).sendKeys(protractor.Key.ENTER)/*.perform()*/; var routes = element.all(by.repeater('route in routes')); expect(routes.count()).toBeGreaterThan(0); routes.get(0).click(); var instructions = element.all(by.repeater('item in route.instructions')); expect(instructions.count()).toBeGreaterThan(5); }); }); |
<путь к unit-тестам>karma_config.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
module.exports = function(config) { config.set({ frameworks: ['jasmine'], reporters: ['progress', 'junit'], junitReporter: { outputFile: 'test-results.xml' }, port: 9876, colors: true, logLevel: config.LOG_INFO, autoWatch: false, captureTimeout: 20000, singleRun: true, reportSlowerThan: 500, plugins: [ 'karma-jasmine', 'karma-chrome-launcher', 'karma-firefox-launcher', 'karma-phantomjs-launcher', 'karma-junit-reporter' ] }); }; |
<путь к unit-тестам>tests/spec.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
'use strict'; /* jasmine specs for filters */ describe('Filters:', function() { beforeEach(angular.mock.module('SmMapApp')); describe('lat:', function() { var lat; beforeEach(inject(function ($filter) { lat = $filter('lat'); })); it('should exist', inject(function() { expect(lat).not.toEqual(null); })); it('should work properly', inject(function() { expect(lat(undefined)).toEqual(undefined); expect(lat('')).toEqual(''); expect(lat({})).toEqual(''); expect(lat({position: 1})).toEqual(''); expect(lat({position: {lat: 1}})).toEqual(1); expect(lat({location: 1})).toEqual(''); expect(lat({location: {lat: 1}})).toEqual(1); })); }); describe('lng:', function() { var lng; beforeEach(inject(function ($filter) { lng = $filter('lng'); })); it('should exist', inject(function() { expect(lng).not.toEqual(null); })); it('should work properly', inject(function() { expect(lng(undefined)).toEqual(undefined); expect(lng('')).toEqual(''); expect(lng({})).toEqual(''); expect(lng({position: 1})).toEqual(''); expect(lng({position: {lng: 1}})).toEqual(1); expect(lng({position: {lon: 1}})).toEqual(1); expect(lng({location: 1})).toEqual(''); expect(lng({location: {lng: 1}})).toEqual(1); expect(lng({location: {lon: 1}})).toEqual(1); })); }); }); |
После чего в консоли
1 2 3 |
cd ./gulp npm install gulp build-and-test |
Это запустит webdriver-update, который скажет, куда поставил selenium, например:
1 2 |
... selenium-server-standalone-2.43.1.jar downloaded to /home/user/projects/maps_ui/scripts/gulp/node_modules/protractor/selenium/selenium-server-standalone-2.43.1.jar |
Есть большая вероятность, что путь не совпадёт с указанным в конфиге <путь к тестам>protractor_config.js, и нужно будет поправить параметр seleniumServerJar.
После этого снова запускаем в консоли
1 |
gulp build-and-test |
и видим, как у нас автоматически стартует хром и проходят тесты.
Полезные ссылки:
http://angular.github.io/protractor/
https://github.com/mllrsohn/gulp-protractor
http://stackoverflow.com/questions/23135649/how-can-i-use-command-line-arguments-in-angularjs-protractor
http://jasmine.github.io/2.0/introduction.html
https://github.com/jtomaszewski/ionic-cordova-gulp-seed/blob/master/gulpfile.coffee
http://karma-runner.github.io/0.8/intro/configuration.html
Similar Posts
LEAVE A COMMENT
Для отправки комментария вам необходимо авторизоваться.