Самодельная параметризация и параллелизация тестов...
TRANSCRIPT
Самодельная параметризация и параллелизация тестов для JS фреймворковРазработчик: Иван Котович
6 ноября, 2016
6 НОЯБРЯ, 2016
РАЗРАБОТЧИК: ИВАН КОТОВИЧ
Самодельная параметризация и параллелизация тестов для JS фреймворков
3CONFIDENTIAL
Иван КотовичSoftware Test Automation Engineer
• Более 2-х лет в JS автоматизации• Разработал с нуля и внедрил в проект несколько
тестовых фреймворка на Java и JavaScript• Участвую в Test Automation mentoring program как
ментор• Читаю лекции в EPAM lab по автоматизации на JS
4CONFIDENTIAL
Параллелизация и параметризация на JS
Инструменты сборки (Grunt, Gulp)1
Параметризация с помощью инструментов сборки2
process.env объект содержащий настройки пользовательской среды
3
child_process и его возможности4
Параллелизация тестов с помощью child process5
Итого6
6CONFIDENTIAL
Параллелизация и параметризация на JS
module.exports = function(grunt) { require('load-grunt-tasks')(grunt); grunt.initConfig({ protractor:{ options:{ keepAlive:true, noColor:false }, target:{ options:{ configFile:'test/e2e/protractor-conf.js', args:{ seleniumAddress:'http://localhost:4444/wd/hub', baseUrl:'https://www.somehost.com/', cucumberOpts:{ tags:['~@ignore'] } } } } } }); grunt.loadNpmTasks('grunt-protractor-runner'); grunt.registerTask('e2e', 'Run e2e tests', function(target) { console.log('E2e tests start'); grunt.task.run(['protractor:'+target]); });
};
Инструменты сборки: Grunt
7CONFIDENTIAL
Параллелизация и параметризация на JS
gulp.task('protractor', function(callback) { gulp.src(['example_spec.js']) .pipe(gulpProtractorAngular({ 'configFile': 'protractor.conf.js', 'debug': false, 'autoStartStopServer': true })) .on('error', function(e) { console.log(e); }) .on('end', callback);});
Инструменты сборки: Gulp
Плюсы• Лаконичен• Простое API• Потоковая передача данныхМинусы• Меньше специализированных
модулей• Сложности в понимании процесса
потоковой передачи данных
8CONFIDENTIAL
Параллелизация и параметризация на JSПараметризация с помощью инструментов сборки
var gulp = require('gulp'), util = require('gulp-util');gulp.task('cucumber', function() { util.env.browser ? process.env.BROWSER = util.env.browser : process.env.BROWSER = 'chrome'; util.env.view ? process.env.VIEW = util.env.view : process.env.VIEW = 'desktop';
return gulp.src('test/features/*') .pipe(cucumber({ 'steps': 'test/step_definitions/*.js', 'support': 'test/support/*.js', 'format': 'json:test/reports/json/json-report.json', 'emitErrors': false }));});
gulp cucumber –-browser=chrome –-view=mobile
//выставление параметров через конфиг.batset BROWSER=firefoxset VIEW=mobilegulp cucumber
9CONFIDENTIAL
Параллелизация и параметризация на JSprocess.env объект содержащий настройки пользовательской среды
• process объект – глобаль ный объект содержащий информацию о текущем node процессе и предоставляющий инструменты контроля над ним
• process доступен во всем приложении• process.env содержит объект с
информацией о пользовательской среде• process.env удобное место для хранения
конфигурационной информации для приложения ( в том числе и для тестов )
$node -e ‘process.env.foo = "bar“’ && echo $foo
process.env.foo = 'bar'; console.log(process.env.foo);
chrome: { 'browserName' : 'chrome', 'chromeOptions' : { 'args': [chromeView[process.env.VIEW]] }}
10CONFIDENTIAL
Параллелизация и параметризация на JSchild_process и его
возможности• child_process – модуль который дает
возможность создавать дочерние процессы
• child_process предоставляет удобное API для создания и управления дочерними процессами
• Child process такой же процесс содержащий process объект
child_process.exec(command[, options][, callback])child_process.execFile(file[, args][, options][, callback])child_process.fork(modulePath[, args][, options])child_process.spawn(command[, args][, options])
const exec = require('child_process').exec;exec('cat *.js bad_file | wc -l', (error, stdout, stderr) => { if (error) { console.error(`exec error: ${error}`); return; } console.log(`stdout: ${stdout}`); console.log(`stderr: ${stderr}`); });
11CONFIDENTIAL
Параллелизация и параметризация на JSПараллелизация тестов с помощью child process
gulp parallel = gulp cucumber Х 4
var q = require('q');var exec = require('child-process-promise').exec;gulp.task(‘parallel', function(){ var promises = []; var f1 = function(){ return exec('gulp cucumber') .then(function (results) {console.log(results.stdout);}) .catch(function (err) {console.error('ERROR: ', err);}); }; for( var i = 0; i<4; i++){ promises.push(f1()); } return q.all(promises);});
Минус: зачем нам 4 параллельных прогона с одинаковыми параметрами ??
13CONFIDENTIAL
Параметризация параллельных прогонов
Параллелизация и параметризация на JS
var q = require('q');var exec = require('child-process-promise').exec;gulp.task(‘parallel', function(){ var threads = util.env.threads ? util.env.threads : 3, browsersStr = util.env.browsers ? util.env.browsers : 'chrome/chrome/chrome', viewsStr = util.env.views ? util.env.views : 'desktop/desktop/desktop', promises = [], browsers = browsersStr.split('/'), views = viewsStr.split('/'); var f1 = function(browser,view){ return exec('gulp cucumber --browser='+browser+' --view='+view) .then(function (results) {console.log(results.stdout);}) .catch(function (err) {console.error('ERROR: ', err);}); }; for( var i = 0; i<threads; i++){ if(browsers[i] !== 'firefox' && browsers[i] !== 'phantomjs'){ browsers[i] = 'chrome'; } if(views[i] !== 'mobile' && views[i] !== 'tabletL' && views[i] !== 'tabletP'){ views[i] = 'desktop'; } promises.push(f1(browsers[i],views[i])); } return q.all(promises);});
gulp parallel –threads=2 –-browsers=chrome/firefox –-views=mobile/desktop
15CONFIDENTIAL
Параллелизация и параметризация на JSИтого: Что мы
имеем?• Удобный параметризируемый
прогон тестов в одном потоке с возможностью выбора браузера и разрешения окна браузера через командную строку или конфиг
• Удобный параметризируемый прогон тестов в разных процессах с возможностью задать количество дочерних процессов, браузер и вью для каждого
• Возможность добавлять дополнительные параметры для выборки по тэгам, спекам итд
• Поле для дальнейших исследований и улучшений
• Удовлетворение от проделанной работы
Note: Параллелизация в protractor и других JS фреймворках основана на тех же принципах
16CONFIDENTIAL
• “JavaScript Patterns” Stoyan Stefanov
Useful literature Useful links
• https://nodejs.org/api/• https://www.npmjs.com/package/g
runt• https://www.npmjs.com/package/g
ulp• https://www.npmjs.com/package/c
hild-process-promise
Параллелизация и параметризация на JS