How I Tricked Our Testers Into Becoming JavaScript Developers
Craig
TRADE ME
@phenomnominal
Testing user interfaces is really hard
REALLY HARD
OLD SITE
COMPLICATED
Lots of manual testing
SLOWING US DOWN
AUTOMATED USER INTERFACE TESTING?
ROBOT FRAMEWORK + RIDE
SLOW & HARD
UNRELIABLE
HARD TO MAINTAIN
BUT!
THEY WORK!
(ish)
WE DON'T TRUST OUR TESTS
BUILDING TRUST...
CAN WE USE BETTER TOOLS?
GHERKIN + CUCUMBER
# doSomething.feature
Feature: Do something
In order to feel good about myself
As a human
I want to do something
Scenario: Do a thing
When I do something
Then I should feel good about myself
FEATURES:
# whenIDoSomething.js
this.When(/^I do something$/, function(done) {
done.pending();
});
# thenIShouldFeelGoodAboutMyself.js
this.Then(/^I should feel good about myself$/, function(done) {
done.pending();
});
STEP DEFINITIONS:
YAY!
EASY TO UNDERSTAND LANGUAGE
REUSABLE CHUNKS OF INTERACTION
NICELY ALIGNED WITH BUSINESS RULES
& ACCEPTANCE CRITERIA
ANGULARJS + PROTRACTOR
WEB DRIVER JS
PROMISES (NO WAITS)
WORKS WITH CUCUMBER!
ROBUSTNESS++
RELIABILITY++
But...
NEW FUNCTIONALITY = FAST
NEW TESTS = SLOW
UI TESTS NOW WRITTEN IN JAVASCRIPT?
Tests not getting written
TESTERS GOING BACK TO ROBOT FRAMEWORK
TESTS BREAK EASILY AS THE CODEBASE CHANGES...
BETTER:
Modular reuseable step definitions
UI tests written in JavaScript
More reliable & ROBUST tests
NOT BETTER:
STILL SLOW TO CREATE TESTS
NEW PROBLEM:
WHOSE RESPONSIBILITY?
WHAT NEXT?
TRACTOR!
A UI FOR CREATING AUTOMATED UI TESTS WITH PROTRACTOR
COMPONENTS
FEATURES
STEP DEFINITIONS
MOCK DATA
COMPONENTS
Just like page objects in Selenium
ENCAPSULATED BEHAVIOUR
this.When(/^I type in my username$/, function (done) {
element(by.css('#UserName')).sendKeys('username');
done();
});
this.When(/^I type in my password$/, function (done) {
element(by.css('#Password')).sendKeys('secret');
done();
});
this.When(/^I click the login button$/, function (done) {
element(by.css('#LoginButton')).click();
done();
});
BEFORE:
// UserLogin.component.js
function UserLogin () {
this.userNameInput = element(by.css('#UserName'));
this.passwordInput = element(by.css('#Password'));
this.loginButton = element(by.css('#LoginButton'));
}
UserLogin.prototype.login = function (username, password) {
this.userNameInput.sendKeys(username);
this.passwordInput.sendKeys(password);
this.loginButton.click();
};
// WhenILogIn.step.js
this.When(/^I log in$/, function (done) {
var UserLogin = new UserLogin();
UserLogin.login('username', 'secret');
});
AFTER:
FEATURES + STEP DEFINITIONS
GIVEN - SET UP MOCK DATA
WHEN - INTERACT WITH PAGE
THEN - CHECK EXPECTATIONS
MOCK DATA
DATA IS EXPECTED TO BE MOCKED BY DEFAULT
YOU CAN JUST PASS-THROUGH TO REAL DATA
Everything is just files!
DEMO
JSONDIR
BE CAREFUL?
ESPRIMA + ESCODEGEN
ACTUAL MAGIC
ESQUERY
ESTEMPLATE
NODE + WINDOZE
JUST USE PATH FOR EVERYTHING
SRSLY.
REWIRE - Node DI
BROWSERIFY
GUlp
GITHUB: TRADE ME / TRACTOR
How I tricked out testers into becoming JavaScript developers
By Craig Spence
How I tricked out testers into becoming JavaScript developers
- 2,983