Upload
mark-michaelis
View
348
Download
3
Tags:
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
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
© CoreMedia AG | 2014-08-09 | 2
User Interface
© CoreMedia | 10 April 2014 | 3© CoreMedia AG | 2014-08-09 | 3
UI-Example: CoreMedia Studio
© 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
© CoreMedia AG | 2014-08-09 | 5
Testing UI-Components
© 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
© 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)
© CoreMedia AG | 2014-08-09 | 8
Technical Approach
© CoreMedia | 10 April 2014 | 9© CoreMedia AG | 2014-08-09 | 9
Primary Design Principles
Simplicity
Bornto Fail
Succeed FastReusable
Extensible
Sweetspot
© CoreMedia AG | 2014-08-09 | 10
UI-Test-Evolution
© 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));
}
© 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);
}
© 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));
© 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();
© 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();
}
© CoreMedia | 10 April 2014 | 16© CoreMedia AG | 2014-08-09 | 16
UI-Test-EvolutionWrapped UI
http://studio/
Content Tags Language
#onlineheldenTitle
Save Cancel
© 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
© CoreMedia | 10 April 2014 | 18© CoreMedia AG | 2014-08-09 | 18
UI-Test-EvolutionWrapper: Mapping ExtJS to Java
Hierarchy in ExtJS Hierarchy in Wrapperns
© 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
© CoreMedia AG | 2014-08-09 | 20
Wrap what?
© 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));
© 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> </i></td>
<td class="x-btn-tc"></td>
<td class="x-btn-tr"><i> </i></td>
</tr>
<tr>
<td class="x-btn-ml"><i> </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>
…
© CoreMedia AG | 2014-08-09 | 23
Some Graphs
© CoreMedia | 10 April 2014 | 24© CoreMedia AG | 2014-08-09 | 24
ResponsibilitiesWebDriver Wait Pattern
© CoreMedia | 10 April 2014 | 25© CoreMedia AG | 2014-08-09 | 25
ResponsibilitiesCoreMedia‘s Wait-Pattern
© CoreMedia | 10 April 2014 | 26© CoreMedia AG | 2014-08-09 | 26
TerminationWebDriver Wait Pattern
© CoreMedia | 10 April 2014 | 27© CoreMedia AG | 2014-08-09 | 27
TerminationCoreMedia‘s Wait Pattern
© CoreMedia | 10 April 2014 | 28© CoreMedia AG | 2014-08-09 | 28
What the Tester needs to knowWebDriver Wait Pattern
Everything…
© CoreMedia | 10 April 2014 | 29© CoreMedia AG | 2014-08-09 | 29
What the Tester needs to knowCoreMedia‘s Wait Pattern
© 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)
© 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
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