I would like to share my story about how our team was building an efficient testing process, how these changes affect the development process overall, how to solve common problems of BDD-style tests with DEMO on real examples. My story begins with several failures/problems, which every team meets at the beginning of involving BDD tools in automation tests.
The next topic is including several improvements such as universal step definitions, cucumber expressions, own parameter types, text localization testing, involving REGEXP to test special symbols, etc.
After, slides cover solving irritable problems of BDD tests such as: getting, remembering and reusing unique data during test run sessions, working with API to avoid repeatable steps, file verifications in headless mode, excel files content, hash, screenshot testing, etc.
16. IMPLEMENT YOUR OWN TYPES
In *.feature file
User logs in as "USER" on "MAIN”
User logs in as "ADMIN" on "API"
users: {
USER: {
DEV: {
login: "test", password: "test"
},
……
ADMIN: {
DEV: {
login: "admin", password: "admin"
},
____________________________
urls: {
MAIN: {
DEV: "http://juliemr.github.io/protractor-demo/",
……..
API: {
DEV: "http://juliemr.github.io/protractor-demo/api",
In conf.js
params: {
timeout: 3000,
env: process.env.TEST_ENV ||
'LOCAL',
},
process.env.TEST_ENV = DEV
17. SETUP JENKINS JOB
#!/usr/bin/env bash
# Use this script to run tests
npm i
npm run webdriver &
# Wait for port 5555 to be listening connections
chmod +x wait-for-it.sh && ./wait-for-it.sh -t 60 127.0.0.1:5555 -- echo "driver is up"
npm run test-jenkins
21. PARAMETER TYPES WITH REGEXP
defineParameterType({
name: 'text',
transformer: function (s) {
if (s.indexOf('REGEXP:') !== -1) {
s = s.split('REGEXP:')[1];
let dataArray = s.split(':');
let page = dataArray[0];
let textToVerify = dataArray[1];
return new
RegExp(text[page][textToVerify][language]);
}
}
});
todayText: {
ENG: "single's",
RU: "(англ.)русск.,"
}
Then Article "wikiPage|todayText" with text
"REGEXP:mainPage:todayText" is displayed
And Article "wikiPage|todayText" with text
"mainPage:todayText" is displayed
25. DO BETTER ON NEW PROJECTS
• Move common steps, helpers, hooks, configurations to the library
• Work with API for preconditions
login: async (host, username, password) => {
let loginRequest = host + "/login";
let data = {"username": username, "password":
password};
let headers = new Map();
headers.set("accept", "application/json");
headers.set("Content-Type", "application/json");
const res = await api.getResponseHeaders("POST",
loginRequest, JSON.stringify(data), headers);
const token = await res['authorization'];
return await global.uniqueMap[token] = token;
},
await userApi.login(host, user.login,
user.password);
When('{user} uploads file to server {landing-url}',
async function (user, host) {
let token = global.uniqueMap[token];
..........
}
26. REUSE DATA WITHIN SESSION
let response = await apiHelper.sendRequest("GET", url, '',
headers);
return browser.getSession().then(session => {
let body = JSON.parse(response.body);
let coordinates = body['coord'];
let lat = coordinates['lat'];
let lon = coordinates['lon'];
global.uniqueMap[`${session['id_']}lat`] =lat;
global.uniqueMap[`${session['id_']}lon`] =lon;
});
return browser.getSession().then(session => {
let lat = global.uniqueMap[`${session['id_']}lat`];
let lon = global.uniqueMap[`${session['id_']}lon`];
let url = string+'/weather?lat='+lat+'&lon='+lon
let headers = new Map();
headers.set("accept", "application/json");
return apiHelper.sendRequest("GET", url, '',
headers).then(function (response) {
……………..
})
{"b546863e5dc9ea38992a5c5d99570efflat":51.51,"b546863e5dc9ea38992a5c5d99570efflon":-0.13}
29. WORK WITH EXCEL FILES
Then('User verifies that file {string} is downloaded', (fileName) => {
const filePath = browser.params.basePath + fileSep + fileName;
return browser.wait(function () {
return fs.existsSync(filePath);
}, 30000, "Wait for '" + filePath + "' to be downloaded").then(function () {
return true;
});
});
30. VERIFY FILE BY HASH
• Navigate to https://md5file.com/calculator
• Upload a file that you want to use as template
• Copy calculated value for hash type SHA-1 and paste it into
Then('User verify downloaded file {text} hash is equal to {hash}', function (fileName, hash) {
return expect(fileHelper.getFileHash(fileName)).to.eventually.equal(hash);
});
Then User verify downloaded file "Test.xlsx" hash is equal to "HASH:fileHash”
hashes: {
fileHash: 'e2c39165ebd60772062684d218259370c739b062',
}