Обзор автоматизации тестирования на javascript
TRANSCRIPT
Viacheslau Bushyla
JavaScript in test automation
Viacheslau BushylaSenior Software Test Automation Engineer
3
Node js platform to execute JS
Node.JS = V8 + I/O + libraries
V8 - fast - modern (all standards) - efficiently uses resources
I/O - files - network - input/output
NPM - installs libraries
JavaScript and Node js
4
var employee = { active: true, age: 20, name: "Ivan", skills: ['Java', 'AT', 'JavaScript'], employer: {company: "Epam"}, workStation: null, summary: undefined, toString: function () { console.log("Name: ", this.name, "Age: ", this.age); }}
typeof(employee.active)"boolean"typeof(employee.age)"number"typeof(employee.name)"string"typeof(employee.skills)"object"typeof(employee.employer)"object"typeof(employee.workStation)"object"typeof(employee.summary)"undefined"typeof(employee.toString)"function"
JavaScript types
5
JSON - JavaScript Object Notation
var objectToString = JSON.stringify(employee);
"{ "active":true, "age":20, "name":"Ivan", "skills":["Java","AT","JavaScript"], "employer":{"company":"Epam"}, "workStation":null}"
var stringToObject = JSON.parse(objectToString)
Object
Object {active: true, age: 20, name: "Ivan", skills: Array[3], employer: Object…}
HTTP
DB
File
Browser
JavaScript and JSON
6
Stack
Input/Output
console.log("start");var file = fs.readFile('/etc/passwd')console.log("done");
main()
readFileconsole.log("end")console.log("done")console.log("start")fs.readFile(cb)
start
done
task queue
console
Synchronous JavaScript
7
Stack
webapis/IO
event loop
cb
console.log("start");fs.readFile('/etc/passwd', (err, data) => { if (err) throw err; console.log("done");});console.log("end");
main()
cbconsole.log("end")console.log("done")console.log("start")fs.readFile(cb)
startend
done
task queue
console
Asynchronous JavaScript
8
Stack
driver
console.log("start");driver.findElement(locator).then(function (q) { console.log("done");}).then(function () { console.log("end");});
main()
driver.findElementconsole.log("done")console.log("end")console.log("start"
)driver.findElement()
startdone
end
console
Synchronization with Promises
9
Promise - represents the eventual result of an asynchronous operation.
Then method, which registers callbacks to receive either a promise’s eventual value or the reason why the promise cannot be fulfilled.
<pending>
fulfilled
rejected
Promises
10
Web Browser Web Serverrequest url
HTML page
AJAX request
response
constant long polling requests....
Synchronization
11
● Run test framework with CLI and configuration file● Integration with popular JavaScript test framework - Jasmine, Cucumber● Maintains a queue of pending promises to keep execution organized● Provides Api to locate and perform actions on DOM elements● Provides synchronization with Angular application
Protractor test framework
12
Page
http pending requests
Browser
DriverWD request
SyncAngular
WD response
Synchronization with Angular
13
RunnerProtractor
Selenium
WDApi
AdapterJasmine
Cucumber
Mocha
Protractor decomposition
14
// C#public class LoginPage{ [FindsBy(How = How.Id, Using = "bbcid_unique")] private IWebElement userName;
[FindsBy(How = How.Id, Using = "bbcid_password")] private IWebElement password;
[FindsBy(How = How.Id, Using = "bbcid_submit_button")] private IWebElement signInButton;
[FindsBy(...)] private IList<IWebElement> someElements;
public LoginPage() { PageFactory.InitElements(DriverManager.getDriver(), this); }
public void login(string login, string password) { userName.SendKeys(login); password.SendKeys(password); signInButton.Click(); }}
// JSvar LoginPage = function() { this.userName = element(by.id('bbcid_unique')); this.password = element(by.id('bbcid_password')); this.signInButton = element(by.id('bbcid_submit_button')); this.someElements = element.all(by.tagName('img')); this.login = function (login, password) { userName.sendKeys; password.sendKeys(password); signInButton.click(); };};
module.exports = LoginPage;
Page Object
15
Page Element- verifyValidationError- checkElement
Clickable Element- click
Custom Element- setElement
Dropdown- setElementByValue- setElementBydate- setElementByIndex
Radiogroup- setElementByIdFragment- setElementByIndex
Textfield- fillElement
BooleanRadioGroup- setElementByIdFragment
Page Elements
16
carRegNumber: {set: {value: 'MF15MYC'}},
findCarButton: 'click',
licenceIssued: {check: {idFragment: 1}},
carRegNumber: {set: {value: false}},
howLongHeldLicenceYear: "verifyValidationError",
Interaction with JSON profile
17
1. Support by Angular community2. High Level abstraction (built-in factories,
builders, workers etc, configuration through config file)
3. Supports JS test frameworks (mocha, jasmine, cucumber)
4. Improved Control Flow (Promises chaining)5. Integration with CI (Bamboo Atlassian, Jenkins,
Teamcity etc.)
1. Tests quite slow2. Build in Solutions make you dependent3. Easy make simple solution build-in for
integration tests4. You have to create complex solution if create
tests as user do
Protractor pros and cons
18
1. Native support JSON2. NPM - build in solutions(REST, BD, reports, IO
libraries)3. Integration with modern web UI solution4. Integration with services, support and
documentation5. Popular Node JS ecosystem6. Easy to start7. Small community
1. Slower than others platform2. Doesn’t support strong typisation3. Slow down development4. Platform depended5. Dinamic6. Async7. Non-standard approaches and code design
patterns
Conclusions
19
https://developer.mozilla.org/ru/docs/Web/JavaScript - mozila development network
https://nodejs.org - Node JS official
https://www.npmjs.com/ - NPM official
https://www.npmjs.com/package/selenium-webdriver - WebDriver JS official documentation
http://protractortest.org - Protractor official
http://jasmine.github.io/ - Jasmine official
https://cucumber.io/ - Cucumber official
Info sources