Reputation: 59
Wondering if there is a possibility to have a data driven tests with protractor + jasmine to execute it in parallel.
I have the following: storeList.json - an array with input params to test individual store. We have around 40 stores - records.
[
{
"storeId": "Store_ID_1",
"storeController": "Store_Controller_1"
},
{
"storeId": "Store_ID_2",
"storeController": "Store_Controller_2"
}
]
ordering.js - code (protractor) which takes each element from json above and executes it as separate test.
describe('Ordering', function () {
all(require('../../assets/data/storeList'), (storeData) => {
it(`Add all items with all modifiers to cart and checkout on ${storeData.storeId}`, async function () {
let user = await userGenerator.Registered(storeData);
await shoppingCartActions.fillCart(storeData,user);
await homePageActions.openCart();
await shoppingCartActions.validateCartMath();
await shoppingCartActions.proceedToCheckout();
await recommendedActions.continueToDeliveryOptions();
await deliveryAndTipsActions.pickupAnd15PercentTip();
await deliveryAndTipsActions.validateCartMath();
await deliveryAndTipsActions.continueToAddressConfirmation();
await pickupAddressConfirmationActions.continueToPaymentMethod();
await paymentActions.fillCardData(storeData);
await paymentActions.pay();
});
});});
all.js - a snippet to make ordering.js a bit data driven
module.exports = (data, test) => {
const rows = Array.isArray(data) ? data : [data];
rows.forEach((row, index) => {
test(row, index + 1)
})};
config.js
exports.config = {
seleniumAddress: 'http://localhost:4444/wd/hub',
baseUrl : 'localhost',
restartBrowserBetweenTests: true,
maxSessions: 3,
multiCapabilities: [{
'browserName': 'chrome'
}, {
'browserName': 'chrome'
}, {
'browserName': 'chrome'
}],
specs: ['./testsuite/ordering/*.js'],
allScriptsTimeout: 20000,
framework: 'jasmine2',
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 600000,
isVerbose: true,
},
onPrepare: () => {
global.all = require('./all');
}};
Using this setup I get 3 instances of chrome running each executing ordering.js test with all available data inputs from storeList. So I get 6 tests executed, but in fact I'm willing 2 tests to be executed in parallel.
Another option I have tried is having multiple json for data input, and copies of ordering js, but that seems to be a bad practice.
Could someone point me to right direction having protractor data driven tests executed in parallel.
Upvotes: 1
Views: 1211
Reputation: 13722
You need to know protractor running in parallel against spec files, rather than it
blocks cross all spec files. So a solution is to create many spec files for data rows (per row per spec file).
// protractor conf.js
var fs = require('fs');
var util = require('util');
var uuidv1 = require('uuid/v1');
function splitData2Sepc(datarows) {
datarows.forEach(function(row) {
let id = uuidv1();
let dataFilePath = './data/data_'+id + '.json';
let specFilePath = './specs/spec_parallel_'+id + '.js';
// read the spec template
let templatePath = './specs/template_01.js';
let template = fs.readFileSync(templatePath, 'utf8');
// generate data file for per row
fs.writeFileSync(dataFilePath,JSON.stringify(row));
// generate spec file for per row
let content = util.format('var row = require("%s");', dataFilePath);
fs.writeFileSync(specFilePath,[content, template].join('\n\n'));
});
}
var datarows = require('./data/all.js');
splitData2Sepc(datarows);
exports.config = {
capabilities: {
browserName: 'chrome',
shardTestFiles: true,
maxInstances: 3,
},
specs: [
'./specs/spec_parallel*.js'
]
};
// specs/template_01.js
describe('', function(row){
it(`Add all items with all modifiers to cart and checkout on ${row.storeId}`, async function () {
let user = await userGenerator.Registered(row);
await shoppingCartActions.fillCart(row.user);
...
});
});
// data/all.js
module.exports = [
{storeId: 1, user: 'user_01', ...},
{storeId: 2, user: 'user_02', ...},
...
];
Upvotes: 1