carmen popoviciu - protractor styleguide | codemotion milan 2015

67
E2E Testing & Best Practices with Protractor @CarmenPopoviciu

Upload: codemotion

Post on 12-Feb-2017

630 views

Category:

Technology


1 download

TRANSCRIPT

Page 1: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

E2E Testing & Best Practices with Protractor

@CarmenPopoviciu

Page 2: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015
Page 3: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Agenda● E2E Testing

● Protractor

● Best Practices

Page 4: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

E2E Testing

Page 5: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

WHAT?

E2E testing is a means of verifying that all units of

an application interact as expected with each other

and that the system as a whole works as intended

Page 6: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

What?● Testing from the user perspective

Page 7: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

What?● Testing from the user perspective

● Main user interaction flows

Page 8: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

What?● Testing from the user perspective

● Main user interaction flows

● Major subpages or routes in the site

Page 9: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

What?● Testing from the user perspective

● Main user interaction flows

● Major subpages or routes in the site

● Essential elements on a page

Page 10: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

WHY?

E2E testing will give you the confidence that

everything works OK

Page 11: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Why?● Prevents production incidents

Page 12: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Why?● Prevents production incidents

● Manual testing takes too much time

Page 13: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Why?● Prevents production incidents

● Manual testing takes too much time

● E2E tests are documentation

Page 14: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Why?● Prevents production incidents

● Manual testing takes too much time

● E2E tests are documentation

● Makes us better devs

Page 15: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Protractor

Page 16: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Protractor is an end-to-end testing framework for AngularJS applications

Page 17: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Protractor● Wrapper around WebdriverJS

● Adds Angular-specific locator strategies

● Runs tests against real browsers

● node.js program

Page 18: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Everything clear?

Page 19: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Let’s dive in a little deeper

Page 20: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Selenium WebDriver

¯\_(ツ)_/¯

Page 21: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Test Browser

Selenium WebDriver

¯\_(ツ)_/¯

Page 22: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Test Browser

WebDriverClient

Libraries

Page 23: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Test Browser

WebDriverClient

Librarieslanguage specific bindings for Selenium WebDriver API

Page 24: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Test Browser

language specific bindings for Selenium WebDriver API

JAVA

Ruby

Python

JS

Page 25: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Test Browser

JAVA

Ruby

Python

JS

WebDriverBrowser Drivers

Page 26: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Test Browser

WebDriver implementations specific to various browsers

JAVA

Ruby

Python

JS

WebDriverBrowser Drivers

Page 27: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Test Browser

Chrome Driver

Firefox Driver

IE Driver

JAVA

Ruby

Python

JS

WebDriver implementations specific to various browsers

Page 28: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Test Browser

Chrome Driver

Firefox Driver

IE Driver

JAVA

Ruby

Python

JS

Page 29: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Test Browser

Chrome Driver

Firefox Driver

IE Driver

JAVA

Ruby

Python

JS

Real browsers that can connect to anything internet can connect to, including the application under test

Page 30: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Test Browser

Chrome Driver

Firefox Driver

IE DriverJS

Python

Ruby

JAVA

Angular apps are written in JS, so we’ll use the JavaScript bindings for the Selenium WebDriver API

Page 31: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Test Browser

Chrome Driver

Firefox Driver

IE Driver

WebdriverJSJavaScript bindings for WebDriver

Page 32: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Test Browser

Chrome Driver

Firefox Driver

IE Driver

WebdriverJS- findElement()- getText()- click()...

JavaScript bindings for WebDriver

Page 33: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Test Browser

Chrome Driver

Firefox Driver

IE Driver

driver.get(url);

var el = driver.findElement( webdriver.By.name('greet'));el.sendKeys('Hi!');el.click();

Test Code

WebdriverJS- findElement()- getText()- click()...

Page 34: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Test Browser

Chrome Driver

Firefox Driver

IE Driver

Test Code

WebdriverJS- findElement()- getText()- click()...

Webdriver Wire Protocol

/session/:sessionId/element/:id/text/session/:sessionId/element/:id/click/session/:sessionId/keys….

Page 35: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Test Browser

Chrome Driver

Firefox Driver

IE Driver

Test Code

WebdriverJS- findElement()- getText()- click()...

Selenium Server

Page 36: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Test Browser

Chrome Driver

Firefox Driver

IE Driver

Test Code

WebdriverJS- findElement()- getText()- click()...

Selenium ServerProtractor

Page 37: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Test Browser

Chrome Driver

Firefox Driver

IE Driver

Test Code

WebdriverJS- findElement()- getText()- click()...

Selenium ServerProtractor

NodeJS

Page 38: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Still confused?

Page 39: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

That’s OK. It will take another few attempts to get it right

Page 40: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

(flashy green) Demo!

Page 41: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Control Flow

Page 42: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Control Flow● Non blocking API

Page 43: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Control Flow● Non blocking API

● WebdriverJS/Protractor APIs are purely

asynchronous

Page 44: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Control Flow● Non blocking API

● WebdriverJS/Protractor APIs are purely

asynchronous

● Every function returns a promise

Page 45: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Control Flowit('should greet’, function() {

browser.get('#/hello-world’);

var name = element(by.model(‘name’));

var greetBtn = element(by.tagName(‘button’));

var greeting = element(by.binding(‘greeting’));

name.sendKeys('DevfestRo');

greetBtn.click();

expect(greeting.getText()).toEqual('Hi DevfestRo!');

// ¯\_(ツ)_/¯

});

Page 46: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Control Flow● WebDriverJS maintains a queue of scheduled tasks

(pending promises), called the control flow

Page 47: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Control Flow● WebDriverJS maintains a queue of scheduled tasks

(pending promises), called the control flow

● Each task is executed once the one before it in the

queue is finished

Page 48: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Control Flow● WebDriverJS maintains a queue of scheduled tasks

(pending promises), called the control flow

● Each task is executed once the one before it in the

queue is finished

● Protractor adapts Jasmine so that each spec

automatically waits until the control flow is empty

before exiting

Page 49: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

That was a LOT of text for one slide

Page 50: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Ready for another quick dive?

Page 51: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

ControlFlow Class

Instancewebdriver.promise.controlFlow()

Task1

Task4

Task3

Task2

Queue

Task4

Task3

Task2

Task1

.execute(..)

Page 52: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Control Flowflow.execute(function() {

console.log('a');

});

flow.execute(function() {

console.log('b');

});

flow.execute(function() {

console.log('c');

});

// a

// b

// c

Page 53: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Control Flowflow.execute(function() {

console.log('a');

}).then(function() {

flow.execute(function() {

console.log('c');

});

});

flow.execute(function() {

console.log('b');

});

// a

// c

// b

Page 54: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

(two seemingly random) Demos!

Page 55: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Best Practices

Page 56: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Use Page Objects to interact with the page under test

WHY?

Encapsulate information about the elements on the page under test

They can be reused across multiple tests

Decouple the test logic from implementation details

Page 57: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

// avoid/* question.spec.js */

describe('Question page', function() { it('should answer any question', function() { var question = element(by.model('question.text')); var answer = element(by.binding('answer')); var button = element(by.css('.question-button'));

question.sendKeys('What is the purpose of life?'); button.click(); expect(answer.getText()).toEqual("Chocolate!"); });});

Page 58: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

// recommended/* question.spec.js */

var QuestionPage = require('./question.page');

describe('Question page', function() { var question = new QuestionPage();

it('should ask any question', function() { question.ask('What is the purpose of meaning?'); expect(question.answer.getText()).toEqual('Chocolate'); });});

Page 59: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

// recommended/* question.page.js */

var QuestionPage = function() { this.question = element(by.model('question.text')); this.answer = element(by.binding('answer')); this.button = element(by.className('question-button'));

this.ask = function(question) { this.question.sendKeys(question); this.button.click(); };};module.exports = QuestionPage;

Page 60: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Declare functions for operations that require more than one step

WHY?

Most elements are exposed by the Page Object and can be used directly in the test

Doing otherwise adds unnecessary complexity

Page 61: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Don't make any assertions in your Page Objects

WHY?

It is the responsibility of the test to do all the assertions

Reader of the test should be able to understand the behavior of the application by

looking at the test only

Page 62: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Prefer protractor locators when possible

WHY?

Access elements easier

Code is less likely to change than markup

More readable locators

Page 63: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

<ul class="red"> <li>{{color.name}}</li> <li>{{color.shade}}</li> <li>{{color.code}}</li></ul>

/* avoid */var nameElem = element.all(by.css('.red li')).get(0);

/* recommended */var nameElem = element(by.binding('color.name'));

Page 64: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

Prefer by.id and by.css when no protractor locators are available

WHY?

Access elements easier

Select markup that is less likely to change

More readable locators

Page 65: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

NEVER use xpath

WHY?

Markup is very easily subject to change

xpath has performance issues

Unreadable locator

Page 66: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

more athttps://github.com/CarmenPopoviciu/protractor-styleguide

https://goo.gl/1SmXer

Page 67: Carmen Popoviciu - Protractor styleguide | Codemotion Milan 2015

THANK YOU!https://goo.gl/1SmXer