32
www.coremedia.com www.coremedia.com © CoreMedia | 2014-08-09 | 1 SoCraTes 2014: Testing Rich-Web-UI Mark Michaelis Kudos to Martti Jeenicke including Session Notes

SoCraTes 2014: Testing Rich-Web-UI

Embed Size (px)

DESCRIPTION

Slides from the SoCraTes 2014 session "Testing Rich-Web-UI" including notes taken within the session like links to additional testing approaches. The slides refer to a proprietary UI-testing-framework and some important patterns in order to get UI tests robusts and easy to read.

Citation preview

Page 1: SoCraTes 2014: Testing Rich-Web-UI

www.coremedia.comwww.coremedia.com© CoreMedia | 2014-08-09 | 1

SoCraTes 2014:Testing Rich-Web-UI

Mark Michaelis

Kudos to Martti Jeenicke

including Session Notes

Page 2: SoCraTes 2014: Testing Rich-Web-UI

© CoreMedia AG | 2014-08-09 | 2

User Interface

Page 3: SoCraTes 2014: Testing Rich-Web-UI

© CoreMedia | 10 April 2014 | 3© CoreMedia AG | 2014-08-09 | 3

UI-Example: CoreMedia Studio

Page 4: SoCraTes 2014: Testing Rich-Web-UI

© CoreMedia | 10 April 2014 | 4© CoreMedia AG | 2014-08-09 | 4

Client-Server-Architecture

Studio-Server(WebApp)

Client (Browser)

ContentREST Service

Presentation

ExtJS

MVCRemoting

Backend Services

…Content Server

Search

AJAX Request

JSON

Page 5: SoCraTes 2014: Testing Rich-Web-UI

© CoreMedia AG | 2014-08-09 | 5

Testing UI-Components

Page 6: SoCraTes 2014: Testing Rich-Web-UI

© CoreMedia | 10 April 2014 | 6© CoreMedia AG | 2014-08-09 | 6© CoreMedia AG | 2014-08-09 | 6

Test-Pyramide (adopted from Mike Cohn)

UI

Service

Unit

Manual

Page 7: SoCraTes 2014: Testing Rich-Web-UI

© CoreMedia | 10 April 2014 | 7© CoreMedia AG | 2014-08-09 | 7

SoCraTes 2014 Session Notes

Another pyramid introduced by Gojko Adzic:How to implement UI testing without shooting yourself in the foot (2010-04-13)

Page 8: SoCraTes 2014: Testing Rich-Web-UI

© CoreMedia AG | 2014-08-09 | 8

Technical Approach

Page 9: SoCraTes 2014: Testing Rich-Web-UI

© CoreMedia | 10 April 2014 | 9© CoreMedia AG | 2014-08-09 | 9

Primary Design Principles

Simplicity

Bornto Fail

Succeed FastReusable

Extensible

Sweetspot

Page 10: SoCraTes 2014: Testing Rich-Web-UI

© CoreMedia AG | 2014-08-09 | 10

UI-Test-Evolution

Page 11: SoCraTes 2014: Testing Rich-Web-UI

© CoreMedia | 10 April 2014 | 11© CoreMedia AG | 2014-08-09 | 11

UI-Test-EvolutionOld

@Test

void testDocUpdate() {

doc = cms.createDoc();

date1 = doc.getDate();

while (!searchServer.isIndexed(doc)) {

Thread.sleep(1000);

}

browser.open(„http://.../studio?id=“ + doc.getId());

Thread.sleep(2000);

browser.getElement(„text“).click();

browser.getElement(„text“).sendKeys(„lorem“);

browser.getElement(„save“).click();

Thread.sleep(500);

date2 = doc.getDate();

assertTrue(date2.after(date1));

}

Page 12: SoCraTes 2014: Testing Rich-Web-UI

© CoreMedia | 10 April 2014 | 12© CoreMedia AG | 2014-08-09 | 12

UI-Test-EvolutionNew

@Test

void scenario_document_change_updates_date() {

Reference<Document> doc = ref();

given_document_D_exists(doc);

given_document_D_is_opened(doc);

when_I_change_document_D(doc);

then_modification_date_of_document_D_is_updated(doc);

}

Page 13: SoCraTes 2014: Testing Rich-Web-UI

© CoreMedia | 10 April 2014 | 13© CoreMedia AG | 2014-08-09 | 13

UI-Test-EvolutionConditions/Matcher

@Test

void scenario_document_change_updates_date() {

Reference<Document> doc = ref();

given_document_D_exists(doc);

given_document_D_is_opened(doc);

when_I_change_document_D(doc);

then_modification_date_of_document_D_is_updated(doc);

}searchServiceWrapper

.indexed(doc)

.waitUntil(equalTo(true));

Page 14: SoCraTes 2014: Testing Rich-Web-UI

© CoreMedia | 10 April 2014 | 14© CoreMedia AG | 2014-08-09 | 14

UI-Test-EvolutionUI-Wrapper

@Test

void scenario_document_change_updates_date() {

Reference<Document> doc = ref();

given_document_D_exists(doc);

given_document_D_is_opened(doc);

when_I_change_document_D(doc);

then_modification_date_of_document_D_is_updated(doc);

}@Inject DocumentPanel panel;

TextField field = panel.getTextField();

field.write(„lorem“);

panel.saveDocument();

Page 15: SoCraTes 2014: Testing Rich-Web-UI

© CoreMedia | 10 April 2014 | 15© CoreMedia AG | 2014-08-09 | 15

UI-Test-EvolutionUI-Wrapper

@Test

void scenario_document_change_updates_date() {

Reference<Document> doc = ref();

given_document_D_exists(doc);

given_document_D_is_opened(doc);

when_I_change_document_D(doc);

then_modification_date_of_document_D_is_updated(doc);

}@Inject DocumentPanel panel;

TextField field = panel.getTextField();

field.write(„lorem“);

panel.saveDocument();

@ExtJSObject(id = „docPanel“)

DocumentPanel extends ExtPanel {

@FindByExtJS(itemId=„save“) Button saveButton;

saveDocument() {

saveButton.click();

}

Page 16: SoCraTes 2014: Testing Rich-Web-UI

© CoreMedia | 10 April 2014 | 16© CoreMedia AG | 2014-08-09 | 16

UI-Test-EvolutionWrapped UI

http://studio/

Content Tags Language

#onlineheldenTitle

Save Cancel

Page 17: SoCraTes 2014: Testing Rich-Web-UI

© CoreMedia | 10 April 2014 | 17© CoreMedia AG | 2014-08-09 | 17

UI-Test-EvolutionExtJS Components

Panel

Toolbar Toolbar

TabView

Tab Tab Tab

Property Field

Toolbar

Label

Textfield

Button

Page 18: SoCraTes 2014: Testing Rich-Web-UI

© CoreMedia | 10 April 2014 | 18© CoreMedia AG | 2014-08-09 | 18

UI-Test-EvolutionWrapper: Mapping ExtJS to Java

Hierarchy in ExtJS Hierarchy in Wrapperns

Page 19: SoCraTes 2014: Testing Rich-Web-UI

© CoreMedia | 10 April 2014 | 19© CoreMedia AG | 2014-08-09 | 19

GridView extends Base {

GridDragZone getDragZone();

Condition<WebElement> cellElement(row ,column);

Condition<WebElement> rowElement(row);

void dragRowFromTo(fromRow,toRow);

BooleanCondition empty();

}

Evolution eines TestsUI-Wrapper – Ein Beispiel aus dem Leben

Page 20: SoCraTes 2014: Testing Rich-Web-UI

© CoreMedia AG | 2014-08-09 | 20

Wrap what?

Page 21: SoCraTes 2014: Testing Rich-Web-UI

© CoreMedia | 10 April 2014 | 21© CoreMedia AG | 2014-08-09 | 21

Wrap what?Hidden Complexity (JavaScript)

self = Ext.getCmp(„panel“);

key = „itemId“; value = „save“;

btn = (self.find && self.find(key, value)[0])

|| (self.buttons

&& self.buttons.filter(

function(b){return b[key] && b[key]==value})[0])

|| (self.items

&& self.items.filter(key, value).get(0));

Page 22: SoCraTes 2014: Testing Rich-Web-UI

© CoreMedia | 10 April 2014 | 22© CoreMedia AG | 2014-08-09 | 22

Wrap what?Hidden Complexity, DOM-Structure

<table cellspacing="0" class="x-toolbar-ct"><tbody> <tr>

<td class="x-toolbar-left" align="left">

<table cellspacing="0"><tbody>

<tr class="x-toolbar-left-row"></tr>

</tbody></table>

</td>

<td class="x-toolbar-right" align="right">

<table cellspacing="0" class="x-toolbar-right-ct"><tbody>

<tr>

<td>

<table cellspacing="0"><tbody>

<tr class="x-toolbar-right-row">

<td class="x-toolbar-cell" id="ext-gen317">

<table id="ext-comp-1314" cellspacing="0" class="x-btn x-btn-noicon" style="width: 75px;">

<tbody class="x-btn-small x-btn-icon-small-left">

<tr>

<td class="x-btn-tl"><i>&nbsp;</i></td>

<td class="x-btn-tc"></td>

<td class="x-btn-tr"><i>&nbsp;</i></td>

</tr>

<tr>

<td class="x-btn-ml"><i>&nbsp;</i></td>

<td class="x-btn-mc">

<em class="" unselectable="on">

<button type="button" id="ext-gen318" style="" class=" x-btn-text">Bestätigen</button> </em>

Page 23: SoCraTes 2014: Testing Rich-Web-UI

© CoreMedia AG | 2014-08-09 | 23

Some Graphs

Page 24: SoCraTes 2014: Testing Rich-Web-UI

© CoreMedia | 10 April 2014 | 24© CoreMedia AG | 2014-08-09 | 24

ResponsibilitiesWebDriver Wait Pattern

Page 25: SoCraTes 2014: Testing Rich-Web-UI

© CoreMedia | 10 April 2014 | 25© CoreMedia AG | 2014-08-09 | 25

ResponsibilitiesCoreMedia‘s Wait-Pattern

Page 26: SoCraTes 2014: Testing Rich-Web-UI

© CoreMedia | 10 April 2014 | 26© CoreMedia AG | 2014-08-09 | 26

TerminationWebDriver Wait Pattern

Page 27: SoCraTes 2014: Testing Rich-Web-UI

© CoreMedia | 10 April 2014 | 27© CoreMedia AG | 2014-08-09 | 27

TerminationCoreMedia‘s Wait Pattern

Page 28: SoCraTes 2014: Testing Rich-Web-UI

© CoreMedia | 10 April 2014 | 28© CoreMedia AG | 2014-08-09 | 28

What the Tester needs to knowWebDriver Wait Pattern

Everything…

Page 29: SoCraTes 2014: Testing Rich-Web-UI

© CoreMedia | 10 April 2014 | 29© CoreMedia AG | 2014-08-09 | 29

What the Tester needs to knowCoreMedia‘s Wait Pattern

Page 30: SoCraTes 2014: Testing Rich-Web-UI

© CoreMedia | 10 April 2014 | 30© CoreMedia AG | 2014-08-09 | 30

SoCraTes 2014 Session Notes

What are you using for testing Web-UIs? DalekJS Selenium FluentLenium Protractor (for AngularJS Apps) ember capybara Greenpepper instanbul-js (Code Coverage)

Page 31: SoCraTes 2014: Testing Rich-Web-UI

© CoreMedia | 10 April 2014 | 31© CoreMedia AG | 2014-08-09 | 31

SoCraTes 2014 Session Notes

Further Reading: testingexperience.de No. 4, January 2014:

(German, registration required for download)

Entwickler entdecken UI-Testing, pp. 12

Page 32: SoCraTes 2014: Testing Rich-Web-UI

www.coremedia.com© CoreMedia | 2014-08-09 | 32

[email protected] +65.6562.8866

[email protected] +49.40.32 55 87.0

San [email protected] +1.415.371.0400

[email protected] +44.207.849.3317

[email protected] +1.703.945.1079