SlideShare a Scribd company logo
End-to-end
testing
A “spocky” story
Blatant self-promotion
Jesús L. Domínguez Muriel
@jdmuriel
Freelance, working at DIGIBÍS
End to end testing
- Chapter I: Why
- Chapter II: A spooky story
- Chapter III: Doing it with geb
Chapter I- Why: Sometimes, software starts small...
... and then it grows
Then, any small change can awake the beast
Ways to handle a 15 year software beast
- Flee
- Rewrite
- Refactor
How to handle a 15 year software beast (I): Flee
(No quiero mirar a nadie :-P )
How to handle a 15 year software beast (II): Rewrite
(Usually not an option)
How to handle a 15 year software beast (III): Refactor
- Refactor need tests
- You usually have untestable code
- Start testing at the lowest level possible
- Unit
- Integration
- End-to-end
- Add new code with good testing practices
- References
- https://www.youtube.com/watch?v=6W-EyIfUTmI
End-to-end tests
- Aka functional tests
- Test the application as an end user would do it
- Backend + frontend + everything in between
- Good for
- Acceptance criteria in user stories
- Systems with many coordinated pieces
- Testing untestable code
End to end testing
wisdom (I)
“End to end tests are like
cats”
(they always do the
same until they don’t)
End to end testing
wisdom (II)
““As anyone who has tried
knows, maintaining a large
suite of functional web tests for
a changing application can
become an expensive and
frustrating process””
Chapter II: a spooky story
Our story starts
with a library
With the years, it somehow has grown in other thing
Digibib - later Digiarch, Digihub, Digimus
- 2003 - 2017
- 43 jars, 136 dependencies
- Several hundred thousands lines of code
- Our own framework -in 2003 there is not Spring
- XML based :-(
- Reimplementations
- Code who nobody knows if it is used or not
- Several generations of front-ends
- Some time around 2012 we start thinking we need some tests
First iteration: Selenium IDE for non technical users
- Firefox extension
- Records browser activity
- Generates an script
- Small IDE to edit the script
- Script can be replayed
- Can be automated with some
effort
- Usable by trained non
technical users…?
- Firefox extension
- Records browser activity
- Generates an script
- Small IDE to edit the script
- Script can be replayed
- Can be automated with some
effort
- Usable by trained non
technical users…?
First iteration: Selenium IDE for non technical users
Selenium IDE: not what we expected
- Selecting the element to check not easy for non technical users (even
if the tool allows selecting it in the browser)
- By CSS
- By XPath
- Changes in a page require recapture of whole, long scripts
- Firefox updates break the extension
- Automation too brittle
- Multi script test execution too slow
- We never get end users to really use the IDE
Selenium IDE: not what we expected
Second iteration: exporting scripts to Java
Advantages
- News scripts can be created faster
- Easier to integrate with jenkins
- Easier to use other browsers
- Improved speed using headless browser
PhantomJS
Second iteration: exporting scripts to Java
Disadvantages
“The key to not pulling your hair out when dealing with web tests” - @ldaley
Tests call domain methods, no HTML
becomes
Access to the specific HTML and CSS only within that Page Objects
If the HTML is changed, only the affected Page object must be changed
Even Martin Fowler said it!!! (https://martinfowler.com/bliki/PageObject.html)
Page object pattern
So, we have work to do
3 or 4 most tested pages are already converted to Page objects
Login
Search form
Many still to do:
Results
Configuration, Indexes, etc.
Chapter III: Enters geb
Developer focused tool
Uses Groovy's dynamism to remove boilerplate, achieve pseudo English code
Uses WebDriver (evolution of Selenium 2) - Cross browser
Inspired by jQuery, robust Page Object modelling support
Good documentation. The “Book of Geb” http://www.gebish.org/manual/current/
Luke Daley (Gradle, Ratpack), Marcin Erdmann (current)
Why geb
Concise
Team already using Groovy with Spock for tests
Standard, tested implementation of utilities we were implementing ad hoc:
- Driver configuration
- Timeout configuration
- Screenshots
- Integration
You can give a talk!!!
Why not geb
Dependency madness (specially with Maven and eclipse)
No autocomplete (on Eclipse)
Oriented to Groovy developers
Geb in 10 slides - Browser
Browser.drive {
go "http://gebish.org"
assert title == "Geb - Very Groovy Browser Automation"
$("div.menu a.manuals").click()
waitFor { !$("#manuals-menu").hasClass("animating") }
$("#manuals-menu a")[0].click()
assert title.startsWith("The Book Of Geb")
}
Browser always have a current page and delegates methods and properties to it.
Geb in 10 slides - Test adapter
class GebishOrgTest extends GebSpec {
@Test
void “clicking first manual goes to book of geb”() {
given:
go "http://gebish.org" //Delegate to browser
when:
$("div.menu a.manuals").click() //Delegate to page
waitFor { !$("#manuals-menu").hasClass("animating") }
$("#manuals-menu a")[0].click()
then:
title.startsWith("The Book Of Geb")
}
}
//Automatic screenshot reporting after every test
Geb in 10 slides - $(), Navigator
Inspired by jQuery:
//$("<css selector>", index_or_range, <attribute/text matcher>)
$("div>p", 0..2, class: "heading", text: iEndsWith("!")) == [“a!”, “b!”]
$("p", text: ~/This./).size() == 2
$(By.id("some-id"))
$(By.xpath('//p[@class="xpath"]'))
//Navigators are iterable
$("p").max { it.text() }.text() == "2"
$("p")*.text().max() == "2"
//Methods for filtering, element traversal
$("div").filter(".a").not(".c").has("p", text: "Found!").hasNot("br")
$("div").find("p").parent().next().children("a", href: contains("www"))
//nextAll(), previous(), siblings(), parents(), closest(),
//nextUntil(), prevUntil(), parentsUntil()
Geb in 10 slides - $(), Navigator
//Composition
$( $("p.a"), $("p.b") )
//Methods
$("a.login").click()
$("input") << "test" << Keys.chord(Keys.CONTROL, "c")
//Properties
displayed, focused //single element needed
height, width, x, y
text(), tag(), classes(), @attribute
//CSS Properties
css("<css property>")
Geb in 10 slides - Page objects
class GebHomePage extends Page {
static url = "http://gebish.org"
static at = { title.contains "Groovy" }
static content = {
toggle { $("div.menu a.manuals") }
linksContainer { $("#manuals-menu") }
links { linksContainer.find("a") }
//stacked content
}
}
class TheBookOfGebPage extends Page {
//url is optional
static at = {
title.startsWith("The Book Of Geb")
}
}
void “clicking first manual goes to book of geb”() {
given:
to GebHomePage //checks at
when:
toggle.click()
waitFor {
!linksContainer.hasClass("animating")
}
links[0].click()
then:
at TheBookOfGebPage
}
Geb in 10 slides - Module
class GebHomePage extends Page {
static url = "http://gebish.org"
static at = { title.contains "Groovy" }
static content = {
manualsMenu { module(ManualsMenuModule)}
}
}
class ManualsMenuModule extends Module {
static content = {
toggle { $("div.menu a.manuals") }
linksContainer { $("#manuals-menu") }
links { linksContainer.find("a") }
}
void open() {
toggle.click()
waitFor { !linksContainer.hasClass
("animating") }
}
}
void “clicking first manual goes to book of geb”() {
given:
to GebHomePage //checks at
when:
manualsMenu.open()
manualsMenu.links[0].click()
then:
at TheBookOfGebPage
}
Geb in 10 slides - Content DSL, moduleList()
static content = {
«name»(«options map») { «definition» }
theDiv(required: false) { $("div", id: "a") }
theDiv(min: 1, max: 2) { $("div", id: "a") }
theDiv(cache: false) { $("div", id: "a") }
helpLink(to: HelpPage) { $("a", text: "Help") } //helpLink.click() sets browser page
loginButton(to: [LoginSuccessfulPage, LoginFailedPage]) { $("input.loginButton") }
dynamicallyAdded(wait: true) { $("p.dynamic") }
someDiv { $("div#aliased") }
aliasedDiv(aliases: "someDiv")
firstCartItem { $("table tr", 0) module (CartRow)}
cartItems {
$("table tr").tail().moduleList(CartRow)
}
assert cartItems.every { it.price > 0.0 }
Geb in 10 slides - Interact API, javascript interface
interact {
clickAndHold($('#draggable'))
moveByOffset(150, 200)
release()
} //All WebDriver Actions
<html>
<head>
<script type="text/javascript">
var aVariable = 1;
</script>
</head>
</html>
assert Browser.js.aVariable == 1
$("div#a").jquery.mouseover()
Geb in 10 slides - Configuration
GebConfig.groovy or GebConfig class in classpath
driver = “firefox” //driver = { new FirefoxDriver() }
environments {
prod {
driver = chrome
}
}
waiting {
timeout = 10
retryInterval = 0.5
presets {
slow {
Timeout = 20
}
}
}
retorsDir = “target/geb-reports”
Geb in 10 slides - Download API
Browser.drive {
to LoginPage
login("me", "secret")
def pdfBytes = downloadBytes(pdfLink.@href)
}
//downloadStream, downloadText, downloadContent
Browser.drive {
go "/"
def jsonBytes = downloadBytes { HttpURLConnection connection ->
connection.setRequestProperty("Accept", "application/json")
}
}
Geb in 10 slides - windows & frames
<a href="http://www.gebish.org" target="myWindow">Geb</a>
Browser.drive {
go()
$("a").click()
withWindow("myWindow", close: true) {
assert title == "Geb - Very Groovy Browser Automation"
}
withWindow({ title == "Geb - Very Groovy Browser Automation" }) {
assert $(".slogan").text().startsWith("Very Groovy browser automation.")
}
}
//withNewWindow(), withFrame(), withNewFrame()
Closures everywhere!
Contents, modules,
waitFor, browser, interact
Rewritten AST “a la Spock”, so that every
expression is turned in an assert (in ats, waits)
Wrapped classes - all page, browser available in
test specs
MethodMissing,
PropertyMissing
Geb’s black magic
Summary
If you have a big application,
use end-to-end tests
If you use Groovy, use Geb
Don’t walk alone in a misty forest...
Thanks
Questions?
@jdmuriel
Ad

More Related Content

What's hot (20)

DrupalCon Dublin 2016 - Automated browser testing with Nightwatch.js
DrupalCon Dublin 2016 - Automated browser testing with Nightwatch.jsDrupalCon Dublin 2016 - Automated browser testing with Nightwatch.js
DrupalCon Dublin 2016 - Automated browser testing with Nightwatch.js
Vladimir Roudakov
 
FuncUnit
FuncUnitFuncUnit
FuncUnit
Brian Moschel
 
jQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & CompressionjQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & Compression
Paul Irish
 
Web Projects: From Theory To Practice
Web Projects: From Theory To PracticeWeb Projects: From Theory To Practice
Web Projects: From Theory To Practice
Sergey Bolshchikov
 
tut0000021-hevery
tut0000021-heverytut0000021-hevery
tut0000021-hevery
tutorialsruby
 
Realize mais com HTML 5 e CSS 3 - 16 EDTED - RJ
Realize mais com HTML 5 e CSS 3 - 16 EDTED - RJRealize mais com HTML 5 e CSS 3 - 16 EDTED - RJ
Realize mais com HTML 5 e CSS 3 - 16 EDTED - RJ
Leonardo Balter
 
Django Heresies
Django HeresiesDjango Heresies
Django Heresies
Simon Willison
 
Front End Development: The Important Parts
Front End Development: The Important PartsFront End Development: The Important Parts
Front End Development: The Important Parts
Sergey Bolshchikov
 
Pragmatic Browser Automation with Geb - GIDS 2015
Pragmatic Browser Automation with Geb - GIDS 2015Pragmatic Browser Automation with Geb - GIDS 2015
Pragmatic Browser Automation with Geb - GIDS 2015
Naresha K
 
#NewMeetup Performance
#NewMeetup Performance#NewMeetup Performance
#NewMeetup Performance
Justin Cataldo
 
Design patterns revisited with PHP 5.3
Design patterns revisited with PHP 5.3Design patterns revisited with PHP 5.3
Design patterns revisited with PHP 5.3
Fabien Potencier
 
Meetup Performance
Meetup PerformanceMeetup Performance
Meetup Performance
Greg Whalin
 
High Performance Ajax Applications
High Performance Ajax ApplicationsHigh Performance Ajax Applications
High Performance Ajax Applications
Julien Lecomte
 
JavaScript Advanced - Useful methods to power up your code
JavaScript Advanced - Useful methods to power up your codeJavaScript Advanced - Useful methods to power up your code
JavaScript Advanced - Useful methods to power up your code
Laurence Svekis ✔
 
Introduction To Django (Strange Loop 2011)
Introduction To Django (Strange Loop 2011)Introduction To Django (Strange Loop 2011)
Introduction To Django (Strange Loop 2011)
Jacob Kaplan-Moss
 
jQuery from the very beginning
jQuery from the very beginningjQuery from the very beginning
jQuery from the very beginning
Anis Ahmad
 
The Django Web Application Framework 2
The Django Web Application Framework 2The Django Web Application Framework 2
The Django Web Application Framework 2
fishwarter
 
Working with the django admin
Working with the django admin Working with the django admin
Working with the django admin
flywindy
 
SharePoint and jQuery Essentials
SharePoint and jQuery EssentialsSharePoint and jQuery Essentials
SharePoint and jQuery Essentials
Mark Rackley
 
Create responsive websites with Django, REST and AngularJS
Create responsive websites with Django, REST and AngularJSCreate responsive websites with Django, REST and AngularJS
Create responsive websites with Django, REST and AngularJS
Hannes Hapke
 
DrupalCon Dublin 2016 - Automated browser testing with Nightwatch.js
DrupalCon Dublin 2016 - Automated browser testing with Nightwatch.jsDrupalCon Dublin 2016 - Automated browser testing with Nightwatch.js
DrupalCon Dublin 2016 - Automated browser testing with Nightwatch.js
Vladimir Roudakov
 
jQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & CompressionjQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & Compression
Paul Irish
 
Web Projects: From Theory To Practice
Web Projects: From Theory To PracticeWeb Projects: From Theory To Practice
Web Projects: From Theory To Practice
Sergey Bolshchikov
 
Realize mais com HTML 5 e CSS 3 - 16 EDTED - RJ
Realize mais com HTML 5 e CSS 3 - 16 EDTED - RJRealize mais com HTML 5 e CSS 3 - 16 EDTED - RJ
Realize mais com HTML 5 e CSS 3 - 16 EDTED - RJ
Leonardo Balter
 
Front End Development: The Important Parts
Front End Development: The Important PartsFront End Development: The Important Parts
Front End Development: The Important Parts
Sergey Bolshchikov
 
Pragmatic Browser Automation with Geb - GIDS 2015
Pragmatic Browser Automation with Geb - GIDS 2015Pragmatic Browser Automation with Geb - GIDS 2015
Pragmatic Browser Automation with Geb - GIDS 2015
Naresha K
 
#NewMeetup Performance
#NewMeetup Performance#NewMeetup Performance
#NewMeetup Performance
Justin Cataldo
 
Design patterns revisited with PHP 5.3
Design patterns revisited with PHP 5.3Design patterns revisited with PHP 5.3
Design patterns revisited with PHP 5.3
Fabien Potencier
 
Meetup Performance
Meetup PerformanceMeetup Performance
Meetup Performance
Greg Whalin
 
High Performance Ajax Applications
High Performance Ajax ApplicationsHigh Performance Ajax Applications
High Performance Ajax Applications
Julien Lecomte
 
JavaScript Advanced - Useful methods to power up your code
JavaScript Advanced - Useful methods to power up your codeJavaScript Advanced - Useful methods to power up your code
JavaScript Advanced - Useful methods to power up your code
Laurence Svekis ✔
 
Introduction To Django (Strange Loop 2011)
Introduction To Django (Strange Loop 2011)Introduction To Django (Strange Loop 2011)
Introduction To Django (Strange Loop 2011)
Jacob Kaplan-Moss
 
jQuery from the very beginning
jQuery from the very beginningjQuery from the very beginning
jQuery from the very beginning
Anis Ahmad
 
The Django Web Application Framework 2
The Django Web Application Framework 2The Django Web Application Framework 2
The Django Web Application Framework 2
fishwarter
 
Working with the django admin
Working with the django admin Working with the django admin
Working with the django admin
flywindy
 
SharePoint and jQuery Essentials
SharePoint and jQuery EssentialsSharePoint and jQuery Essentials
SharePoint and jQuery Essentials
Mark Rackley
 
Create responsive websites with Django, REST and AngularJS
Create responsive websites with Django, REST and AngularJSCreate responsive websites with Django, REST and AngularJS
Create responsive websites with Django, REST and AngularJS
Hannes Hapke
 

Similar to End-to-end testing with geb (20)

Javascript first-class citizenery
Javascript first-class citizeneryJavascript first-class citizenery
Javascript first-class citizenery
toddbr
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
Fabio Franzini
 
Introduction to jQuery
Introduction to jQueryIntroduction to jQuery
Introduction to jQuery
Alek Davis
 
Knolx session
Knolx sessionKnolx session
Knolx session
Knoldus Inc.
 
Reactive Type safe Webcomponents with skateJS
Reactive Type safe Webcomponents with skateJSReactive Type safe Webcomponents with skateJS
Reactive Type safe Webcomponents with skateJS
Martin Hochel
 
Passo a Passo para criar uma aplicação Móvel Híbrida
Passo a Passo para criar uma aplicação Móvel HíbridaPasso a Passo para criar uma aplicação Móvel Híbrida
Passo a Passo para criar uma aplicação Móvel Híbrida
Juliano Martins
 
Three Simple Chords of Alternative PageObjects and Hardcore of LoadableCompon...
Three Simple Chords of Alternative PageObjects and Hardcore of LoadableCompon...Three Simple Chords of Alternative PageObjects and Hardcore of LoadableCompon...
Three Simple Chords of Alternative PageObjects and Hardcore of LoadableCompon...
Iakiv Kramarenko
 
Comprehensive Browser Automation Solution using Groovy, WebDriver & Obect Model
Comprehensive Browser Automation Solution using Groovy, WebDriver & Obect ModelComprehensive Browser Automation Solution using Groovy, WebDriver & Obect Model
Comprehensive Browser Automation Solution using Groovy, WebDriver & Obect Model
vodQA
 
Selenium & PHPUnit made easy with Steward (Berlin, April 2017)
Selenium & PHPUnit made easy with Steward (Berlin, April 2017)Selenium & PHPUnit made easy with Steward (Berlin, April 2017)
Selenium & PHPUnit made easy with Steward (Berlin, April 2017)
Ondřej Machulda
 
Automatisation in development and testing - within budget
Automatisation in development and testing - within budgetAutomatisation in development and testing - within budget
Automatisation in development and testing - within budget
David Lukac
 
Introduction to Django
Introduction to DjangoIntroduction to Django
Introduction to Django
James Casey
 
Build Your Own CMS with Apache Sling
Build Your Own CMS with Apache SlingBuild Your Own CMS with Apache Sling
Build Your Own CMS with Apache Sling
Bob Paulin
 
Geb presentation
Geb presentationGeb presentation
Geb presentation
Ivar Østhus
 
Fewd week4 slides
Fewd week4 slidesFewd week4 slides
Fewd week4 slides
William Myers
 
Intro to jQuery @ Startup Institute
Intro to jQuery @ Startup InstituteIntro to jQuery @ Startup Institute
Intro to jQuery @ Startup Institute
Rafael Gonzaque
 
The Big Picture and How to Get Started
The Big Picture and How to Get StartedThe Big Picture and How to Get Started
The Big Picture and How to Get Started
guest1af57e
 
Getting Started with Test Automation: Introduction to Cucumber with Lapis Lazuli
Getting Started with Test Automation: Introduction to Cucumber with Lapis LazuliGetting Started with Test Automation: Introduction to Cucumber with Lapis Lazuli
Getting Started with Test Automation: Introduction to Cucumber with Lapis Lazuli
Rebecca Eloise Hogg
 
OSGi and Spring Data for simple (Web) Application Development - Christian Bar...
OSGi and Spring Data for simple (Web) Application Development - Christian Bar...OSGi and Spring Data for simple (Web) Application Development - Christian Bar...
OSGi and Spring Data for simple (Web) Application Development - Christian Bar...
mfrancis
 
OSGi and Spring Data for simple (Web) Application Development
OSGi and Spring Data  for simple (Web) Application DevelopmentOSGi and Spring Data  for simple (Web) Application Development
OSGi and Spring Data for simple (Web) Application Development
Christian Baranowski
 
jQuery in the [Aol.] Enterprise
jQuery in the [Aol.] EnterprisejQuery in the [Aol.] Enterprise
jQuery in the [Aol.] Enterprise
Dave Artz
 
Javascript first-class citizenery
Javascript first-class citizeneryJavascript first-class citizenery
Javascript first-class citizenery
toddbr
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
Fabio Franzini
 
Introduction to jQuery
Introduction to jQueryIntroduction to jQuery
Introduction to jQuery
Alek Davis
 
Reactive Type safe Webcomponents with skateJS
Reactive Type safe Webcomponents with skateJSReactive Type safe Webcomponents with skateJS
Reactive Type safe Webcomponents with skateJS
Martin Hochel
 
Passo a Passo para criar uma aplicação Móvel Híbrida
Passo a Passo para criar uma aplicação Móvel HíbridaPasso a Passo para criar uma aplicação Móvel Híbrida
Passo a Passo para criar uma aplicação Móvel Híbrida
Juliano Martins
 
Three Simple Chords of Alternative PageObjects and Hardcore of LoadableCompon...
Three Simple Chords of Alternative PageObjects and Hardcore of LoadableCompon...Three Simple Chords of Alternative PageObjects and Hardcore of LoadableCompon...
Three Simple Chords of Alternative PageObjects and Hardcore of LoadableCompon...
Iakiv Kramarenko
 
Comprehensive Browser Automation Solution using Groovy, WebDriver & Obect Model
Comprehensive Browser Automation Solution using Groovy, WebDriver & Obect ModelComprehensive Browser Automation Solution using Groovy, WebDriver & Obect Model
Comprehensive Browser Automation Solution using Groovy, WebDriver & Obect Model
vodQA
 
Selenium & PHPUnit made easy with Steward (Berlin, April 2017)
Selenium & PHPUnit made easy with Steward (Berlin, April 2017)Selenium & PHPUnit made easy with Steward (Berlin, April 2017)
Selenium & PHPUnit made easy with Steward (Berlin, April 2017)
Ondřej Machulda
 
Automatisation in development and testing - within budget
Automatisation in development and testing - within budgetAutomatisation in development and testing - within budget
Automatisation in development and testing - within budget
David Lukac
 
Introduction to Django
Introduction to DjangoIntroduction to Django
Introduction to Django
James Casey
 
Build Your Own CMS with Apache Sling
Build Your Own CMS with Apache SlingBuild Your Own CMS with Apache Sling
Build Your Own CMS with Apache Sling
Bob Paulin
 
Intro to jQuery @ Startup Institute
Intro to jQuery @ Startup InstituteIntro to jQuery @ Startup Institute
Intro to jQuery @ Startup Institute
Rafael Gonzaque
 
The Big Picture and How to Get Started
The Big Picture and How to Get StartedThe Big Picture and How to Get Started
The Big Picture and How to Get Started
guest1af57e
 
Getting Started with Test Automation: Introduction to Cucumber with Lapis Lazuli
Getting Started with Test Automation: Introduction to Cucumber with Lapis LazuliGetting Started with Test Automation: Introduction to Cucumber with Lapis Lazuli
Getting Started with Test Automation: Introduction to Cucumber with Lapis Lazuli
Rebecca Eloise Hogg
 
OSGi and Spring Data for simple (Web) Application Development - Christian Bar...
OSGi and Spring Data for simple (Web) Application Development - Christian Bar...OSGi and Spring Data for simple (Web) Application Development - Christian Bar...
OSGi and Spring Data for simple (Web) Application Development - Christian Bar...
mfrancis
 
OSGi and Spring Data for simple (Web) Application Development
OSGi and Spring Data  for simple (Web) Application DevelopmentOSGi and Spring Data  for simple (Web) Application Development
OSGi and Spring Data for simple (Web) Application Development
Christian Baranowski
 
jQuery in the [Aol.] Enterprise
jQuery in the [Aol.] EnterprisejQuery in the [Aol.] Enterprise
jQuery in the [Aol.] Enterprise
Dave Artz
 
Ad

Recently uploaded (20)

EASEUS Partition Master Crack + License Code
EASEUS Partition Master Crack + License CodeEASEUS Partition Master Crack + License Code
EASEUS Partition Master Crack + License Code
aneelaramzan63
 
Automation Techniques in RPA - UiPath Certificate
Automation Techniques in RPA - UiPath CertificateAutomation Techniques in RPA - UiPath Certificate
Automation Techniques in RPA - UiPath Certificate
VICTOR MAESTRE RAMIREZ
 
PDF Reader Pro Crack Latest Version FREE Download 2025
PDF Reader Pro Crack Latest Version FREE Download 2025PDF Reader Pro Crack Latest Version FREE Download 2025
PDF Reader Pro Crack Latest Version FREE Download 2025
mu394968
 
Exploring Wayland: A Modern Display Server for the Future
Exploring Wayland: A Modern Display Server for the FutureExploring Wayland: A Modern Display Server for the Future
Exploring Wayland: A Modern Display Server for the Future
ICS
 
Who Watches the Watchmen (SciFiDevCon 2025)
Who Watches the Watchmen (SciFiDevCon 2025)Who Watches the Watchmen (SciFiDevCon 2025)
Who Watches the Watchmen (SciFiDevCon 2025)
Allon Mureinik
 
F-Secure Freedome VPN 2025 Crack Plus Activation New Version
F-Secure Freedome VPN 2025 Crack Plus Activation  New VersionF-Secure Freedome VPN 2025 Crack Plus Activation  New Version
F-Secure Freedome VPN 2025 Crack Plus Activation New Version
saimabibi60507
 
How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?
How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?
How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?
steaveroggers
 
Secure Test Infrastructure: The Backbone of Trustworthy Software Development
Secure Test Infrastructure: The Backbone of Trustworthy Software DevelopmentSecure Test Infrastructure: The Backbone of Trustworthy Software Development
Secure Test Infrastructure: The Backbone of Trustworthy Software Development
Shubham Joshi
 
Meet the Agents: How AI Is Learning to Think, Plan, and Collaborate
Meet the Agents: How AI Is Learning to Think, Plan, and CollaborateMeet the Agents: How AI Is Learning to Think, Plan, and Collaborate
Meet the Agents: How AI Is Learning to Think, Plan, and Collaborate
Maxim Salnikov
 
Pixologic ZBrush Crack Plus Activation Key [Latest 2025] New Version
Pixologic ZBrush Crack Plus Activation Key [Latest 2025] New VersionPixologic ZBrush Crack Plus Activation Key [Latest 2025] New Version
Pixologic ZBrush Crack Plus Activation Key [Latest 2025] New Version
saimabibi60507
 
Landscape of Requirements Engineering for/by AI through Literature Review
Landscape of Requirements Engineering for/by AI through Literature ReviewLandscape of Requirements Engineering for/by AI through Literature Review
Landscape of Requirements Engineering for/by AI through Literature Review
Hironori Washizaki
 
Microsoft AI Nonprofit Use Cases and Live Demo_2025.04.30.pdf
Microsoft AI Nonprofit Use Cases and Live Demo_2025.04.30.pdfMicrosoft AI Nonprofit Use Cases and Live Demo_2025.04.30.pdf
Microsoft AI Nonprofit Use Cases and Live Demo_2025.04.30.pdf
TechSoup
 
Avast Premium Security Crack FREE Latest Version 2025
Avast Premium Security Crack FREE Latest Version 2025Avast Premium Security Crack FREE Latest Version 2025
Avast Premium Security Crack FREE Latest Version 2025
mu394968
 
Proactive Vulnerability Detection in Source Code Using Graph Neural Networks:...
Proactive Vulnerability Detection in Source Code Using Graph Neural Networks:...Proactive Vulnerability Detection in Source Code Using Graph Neural Networks:...
Proactive Vulnerability Detection in Source Code Using Graph Neural Networks:...
Ranjan Baisak
 
The Significance of Hardware in Information Systems.pdf
The Significance of Hardware in Information Systems.pdfThe Significance of Hardware in Information Systems.pdf
The Significance of Hardware in Information Systems.pdf
drewplanas10
 
Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...
Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...
Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...
Eric D. Schabell
 
Douwan Crack 2025 new verson+ License code
Douwan Crack 2025 new verson+ License codeDouwan Crack 2025 new verson+ License code
Douwan Crack 2025 new verson+ License code
aneelaramzan63
 
Scaling GraphRAG: Efficient Knowledge Retrieval for Enterprise AI
Scaling GraphRAG:  Efficient Knowledge Retrieval for Enterprise AIScaling GraphRAG:  Efficient Knowledge Retrieval for Enterprise AI
Scaling GraphRAG: Efficient Knowledge Retrieval for Enterprise AI
danshalev
 
Designing AI-Powered APIs on Azure: Best Practices& Considerations
Designing AI-Powered APIs on Azure: Best Practices& ConsiderationsDesigning AI-Powered APIs on Azure: Best Practices& Considerations
Designing AI-Powered APIs on Azure: Best Practices& Considerations
Dinusha Kumarasiri
 
Adobe Lightroom Classic Crack FREE Latest link 2025
Adobe Lightroom Classic Crack FREE Latest link 2025Adobe Lightroom Classic Crack FREE Latest link 2025
Adobe Lightroom Classic Crack FREE Latest link 2025
kashifyounis067
 
EASEUS Partition Master Crack + License Code
EASEUS Partition Master Crack + License CodeEASEUS Partition Master Crack + License Code
EASEUS Partition Master Crack + License Code
aneelaramzan63
 
Automation Techniques in RPA - UiPath Certificate
Automation Techniques in RPA - UiPath CertificateAutomation Techniques in RPA - UiPath Certificate
Automation Techniques in RPA - UiPath Certificate
VICTOR MAESTRE RAMIREZ
 
PDF Reader Pro Crack Latest Version FREE Download 2025
PDF Reader Pro Crack Latest Version FREE Download 2025PDF Reader Pro Crack Latest Version FREE Download 2025
PDF Reader Pro Crack Latest Version FREE Download 2025
mu394968
 
Exploring Wayland: A Modern Display Server for the Future
Exploring Wayland: A Modern Display Server for the FutureExploring Wayland: A Modern Display Server for the Future
Exploring Wayland: A Modern Display Server for the Future
ICS
 
Who Watches the Watchmen (SciFiDevCon 2025)
Who Watches the Watchmen (SciFiDevCon 2025)Who Watches the Watchmen (SciFiDevCon 2025)
Who Watches the Watchmen (SciFiDevCon 2025)
Allon Mureinik
 
F-Secure Freedome VPN 2025 Crack Plus Activation New Version
F-Secure Freedome VPN 2025 Crack Plus Activation  New VersionF-Secure Freedome VPN 2025 Crack Plus Activation  New Version
F-Secure Freedome VPN 2025 Crack Plus Activation New Version
saimabibi60507
 
How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?
How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?
How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?
steaveroggers
 
Secure Test Infrastructure: The Backbone of Trustworthy Software Development
Secure Test Infrastructure: The Backbone of Trustworthy Software DevelopmentSecure Test Infrastructure: The Backbone of Trustworthy Software Development
Secure Test Infrastructure: The Backbone of Trustworthy Software Development
Shubham Joshi
 
Meet the Agents: How AI Is Learning to Think, Plan, and Collaborate
Meet the Agents: How AI Is Learning to Think, Plan, and CollaborateMeet the Agents: How AI Is Learning to Think, Plan, and Collaborate
Meet the Agents: How AI Is Learning to Think, Plan, and Collaborate
Maxim Salnikov
 
Pixologic ZBrush Crack Plus Activation Key [Latest 2025] New Version
Pixologic ZBrush Crack Plus Activation Key [Latest 2025] New VersionPixologic ZBrush Crack Plus Activation Key [Latest 2025] New Version
Pixologic ZBrush Crack Plus Activation Key [Latest 2025] New Version
saimabibi60507
 
Landscape of Requirements Engineering for/by AI through Literature Review
Landscape of Requirements Engineering for/by AI through Literature ReviewLandscape of Requirements Engineering for/by AI through Literature Review
Landscape of Requirements Engineering for/by AI through Literature Review
Hironori Washizaki
 
Microsoft AI Nonprofit Use Cases and Live Demo_2025.04.30.pdf
Microsoft AI Nonprofit Use Cases and Live Demo_2025.04.30.pdfMicrosoft AI Nonprofit Use Cases and Live Demo_2025.04.30.pdf
Microsoft AI Nonprofit Use Cases and Live Demo_2025.04.30.pdf
TechSoup
 
Avast Premium Security Crack FREE Latest Version 2025
Avast Premium Security Crack FREE Latest Version 2025Avast Premium Security Crack FREE Latest Version 2025
Avast Premium Security Crack FREE Latest Version 2025
mu394968
 
Proactive Vulnerability Detection in Source Code Using Graph Neural Networks:...
Proactive Vulnerability Detection in Source Code Using Graph Neural Networks:...Proactive Vulnerability Detection in Source Code Using Graph Neural Networks:...
Proactive Vulnerability Detection in Source Code Using Graph Neural Networks:...
Ranjan Baisak
 
The Significance of Hardware in Information Systems.pdf
The Significance of Hardware in Information Systems.pdfThe Significance of Hardware in Information Systems.pdf
The Significance of Hardware in Information Systems.pdf
drewplanas10
 
Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...
Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...
Mastering Fluent Bit: Ultimate Guide to Integrating Telemetry Pipelines with ...
Eric D. Schabell
 
Douwan Crack 2025 new verson+ License code
Douwan Crack 2025 new verson+ License codeDouwan Crack 2025 new verson+ License code
Douwan Crack 2025 new verson+ License code
aneelaramzan63
 
Scaling GraphRAG: Efficient Knowledge Retrieval for Enterprise AI
Scaling GraphRAG:  Efficient Knowledge Retrieval for Enterprise AIScaling GraphRAG:  Efficient Knowledge Retrieval for Enterprise AI
Scaling GraphRAG: Efficient Knowledge Retrieval for Enterprise AI
danshalev
 
Designing AI-Powered APIs on Azure: Best Practices& Considerations
Designing AI-Powered APIs on Azure: Best Practices& ConsiderationsDesigning AI-Powered APIs on Azure: Best Practices& Considerations
Designing AI-Powered APIs on Azure: Best Practices& Considerations
Dinusha Kumarasiri
 
Adobe Lightroom Classic Crack FREE Latest link 2025
Adobe Lightroom Classic Crack FREE Latest link 2025Adobe Lightroom Classic Crack FREE Latest link 2025
Adobe Lightroom Classic Crack FREE Latest link 2025
kashifyounis067
 
Ad

End-to-end testing with geb

  • 2. Blatant self-promotion Jesús L. Domínguez Muriel @jdmuriel Freelance, working at DIGIBÍS
  • 3. End to end testing - Chapter I: Why - Chapter II: A spooky story - Chapter III: Doing it with geb
  • 4. Chapter I- Why: Sometimes, software starts small...
  • 5. ... and then it grows
  • 6. Then, any small change can awake the beast
  • 7. Ways to handle a 15 year software beast - Flee - Rewrite - Refactor
  • 8. How to handle a 15 year software beast (I): Flee (No quiero mirar a nadie :-P )
  • 9. How to handle a 15 year software beast (II): Rewrite (Usually not an option)
  • 10. How to handle a 15 year software beast (III): Refactor - Refactor need tests - You usually have untestable code - Start testing at the lowest level possible - Unit - Integration - End-to-end - Add new code with good testing practices - References - https://www.youtube.com/watch?v=6W-EyIfUTmI
  • 11. End-to-end tests - Aka functional tests - Test the application as an end user would do it - Backend + frontend + everything in between - Good for - Acceptance criteria in user stories - Systems with many coordinated pieces - Testing untestable code
  • 12. End to end testing wisdom (I) “End to end tests are like cats” (they always do the same until they don’t)
  • 13. End to end testing wisdom (II) ““As anyone who has tried knows, maintaining a large suite of functional web tests for a changing application can become an expensive and frustrating process””
  • 14. Chapter II: a spooky story Our story starts with a library
  • 15. With the years, it somehow has grown in other thing
  • 16. Digibib - later Digiarch, Digihub, Digimus - 2003 - 2017 - 43 jars, 136 dependencies - Several hundred thousands lines of code - Our own framework -in 2003 there is not Spring - XML based :-( - Reimplementations - Code who nobody knows if it is used or not - Several generations of front-ends - Some time around 2012 we start thinking we need some tests
  • 17. First iteration: Selenium IDE for non technical users - Firefox extension - Records browser activity - Generates an script - Small IDE to edit the script - Script can be replayed - Can be automated with some effort - Usable by trained non technical users…?
  • 18. - Firefox extension - Records browser activity - Generates an script - Small IDE to edit the script - Script can be replayed - Can be automated with some effort - Usable by trained non technical users…? First iteration: Selenium IDE for non technical users
  • 19. Selenium IDE: not what we expected
  • 20. - Selecting the element to check not easy for non technical users (even if the tool allows selecting it in the browser) - By CSS - By XPath - Changes in a page require recapture of whole, long scripts - Firefox updates break the extension - Automation too brittle - Multi script test execution too slow - We never get end users to really use the IDE Selenium IDE: not what we expected
  • 21. Second iteration: exporting scripts to Java Advantages - News scripts can be created faster - Easier to integrate with jenkins - Easier to use other browsers - Improved speed using headless browser PhantomJS
  • 22. Second iteration: exporting scripts to Java Disadvantages
  • 23. “The key to not pulling your hair out when dealing with web tests” - @ldaley Tests call domain methods, no HTML becomes Access to the specific HTML and CSS only within that Page Objects If the HTML is changed, only the affected Page object must be changed Even Martin Fowler said it!!! (https://martinfowler.com/bliki/PageObject.html) Page object pattern
  • 24. So, we have work to do 3 or 4 most tested pages are already converted to Page objects Login Search form Many still to do: Results Configuration, Indexes, etc.
  • 25. Chapter III: Enters geb Developer focused tool Uses Groovy's dynamism to remove boilerplate, achieve pseudo English code Uses WebDriver (evolution of Selenium 2) - Cross browser Inspired by jQuery, robust Page Object modelling support Good documentation. The “Book of Geb” http://www.gebish.org/manual/current/ Luke Daley (Gradle, Ratpack), Marcin Erdmann (current)
  • 26. Why geb Concise Team already using Groovy with Spock for tests Standard, tested implementation of utilities we were implementing ad hoc: - Driver configuration - Timeout configuration - Screenshots - Integration You can give a talk!!!
  • 27. Why not geb Dependency madness (specially with Maven and eclipse) No autocomplete (on Eclipse) Oriented to Groovy developers
  • 28. Geb in 10 slides - Browser Browser.drive { go "http://gebish.org" assert title == "Geb - Very Groovy Browser Automation" $("div.menu a.manuals").click() waitFor { !$("#manuals-menu").hasClass("animating") } $("#manuals-menu a")[0].click() assert title.startsWith("The Book Of Geb") } Browser always have a current page and delegates methods and properties to it.
  • 29. Geb in 10 slides - Test adapter class GebishOrgTest extends GebSpec { @Test void “clicking first manual goes to book of geb”() { given: go "http://gebish.org" //Delegate to browser when: $("div.menu a.manuals").click() //Delegate to page waitFor { !$("#manuals-menu").hasClass("animating") } $("#manuals-menu a")[0].click() then: title.startsWith("The Book Of Geb") } } //Automatic screenshot reporting after every test
  • 30. Geb in 10 slides - $(), Navigator Inspired by jQuery: //$("<css selector>", index_or_range, <attribute/text matcher>) $("div>p", 0..2, class: "heading", text: iEndsWith("!")) == [“a!”, “b!”] $("p", text: ~/This./).size() == 2 $(By.id("some-id")) $(By.xpath('//p[@class="xpath"]')) //Navigators are iterable $("p").max { it.text() }.text() == "2" $("p")*.text().max() == "2" //Methods for filtering, element traversal $("div").filter(".a").not(".c").has("p", text: "Found!").hasNot("br") $("div").find("p").parent().next().children("a", href: contains("www")) //nextAll(), previous(), siblings(), parents(), closest(), //nextUntil(), prevUntil(), parentsUntil()
  • 31. Geb in 10 slides - $(), Navigator //Composition $( $("p.a"), $("p.b") ) //Methods $("a.login").click() $("input") << "test" << Keys.chord(Keys.CONTROL, "c") //Properties displayed, focused //single element needed height, width, x, y text(), tag(), classes(), @attribute //CSS Properties css("<css property>")
  • 32. Geb in 10 slides - Page objects class GebHomePage extends Page { static url = "http://gebish.org" static at = { title.contains "Groovy" } static content = { toggle { $("div.menu a.manuals") } linksContainer { $("#manuals-menu") } links { linksContainer.find("a") } //stacked content } } class TheBookOfGebPage extends Page { //url is optional static at = { title.startsWith("The Book Of Geb") } } void “clicking first manual goes to book of geb”() { given: to GebHomePage //checks at when: toggle.click() waitFor { !linksContainer.hasClass("animating") } links[0].click() then: at TheBookOfGebPage }
  • 33. Geb in 10 slides - Module class GebHomePage extends Page { static url = "http://gebish.org" static at = { title.contains "Groovy" } static content = { manualsMenu { module(ManualsMenuModule)} } } class ManualsMenuModule extends Module { static content = { toggle { $("div.menu a.manuals") } linksContainer { $("#manuals-menu") } links { linksContainer.find("a") } } void open() { toggle.click() waitFor { !linksContainer.hasClass ("animating") } } } void “clicking first manual goes to book of geb”() { given: to GebHomePage //checks at when: manualsMenu.open() manualsMenu.links[0].click() then: at TheBookOfGebPage }
  • 34. Geb in 10 slides - Content DSL, moduleList() static content = { «name»(«options map») { «definition» } theDiv(required: false) { $("div", id: "a") } theDiv(min: 1, max: 2) { $("div", id: "a") } theDiv(cache: false) { $("div", id: "a") } helpLink(to: HelpPage) { $("a", text: "Help") } //helpLink.click() sets browser page loginButton(to: [LoginSuccessfulPage, LoginFailedPage]) { $("input.loginButton") } dynamicallyAdded(wait: true) { $("p.dynamic") } someDiv { $("div#aliased") } aliasedDiv(aliases: "someDiv") firstCartItem { $("table tr", 0) module (CartRow)} cartItems { $("table tr").tail().moduleList(CartRow) } assert cartItems.every { it.price > 0.0 }
  • 35. Geb in 10 slides - Interact API, javascript interface interact { clickAndHold($('#draggable')) moveByOffset(150, 200) release() } //All WebDriver Actions <html> <head> <script type="text/javascript"> var aVariable = 1; </script> </head> </html> assert Browser.js.aVariable == 1 $("div#a").jquery.mouseover()
  • 36. Geb in 10 slides - Configuration GebConfig.groovy or GebConfig class in classpath driver = “firefox” //driver = { new FirefoxDriver() } environments { prod { driver = chrome } } waiting { timeout = 10 retryInterval = 0.5 presets { slow { Timeout = 20 } } } retorsDir = “target/geb-reports”
  • 37. Geb in 10 slides - Download API Browser.drive { to LoginPage login("me", "secret") def pdfBytes = downloadBytes(pdfLink.@href) } //downloadStream, downloadText, downloadContent Browser.drive { go "/" def jsonBytes = downloadBytes { HttpURLConnection connection -> connection.setRequestProperty("Accept", "application/json") } }
  • 38. Geb in 10 slides - windows & frames <a href="http://www.gebish.org" target="myWindow">Geb</a> Browser.drive { go() $("a").click() withWindow("myWindow", close: true) { assert title == "Geb - Very Groovy Browser Automation" } withWindow({ title == "Geb - Very Groovy Browser Automation" }) { assert $(".slogan").text().startsWith("Very Groovy browser automation.") } } //withNewWindow(), withFrame(), withNewFrame()
  • 39. Closures everywhere! Contents, modules, waitFor, browser, interact Rewritten AST “a la Spock”, so that every expression is turned in an assert (in ats, waits) Wrapped classes - all page, browser available in test specs MethodMissing, PropertyMissing Geb’s black magic
  • 40. Summary If you have a big application, use end-to-end tests If you use Groovy, use Geb Don’t walk alone in a misty forest...