SlideShare una empresa de Scribd logo
1 de 41
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

Más contenido relacionado

La actualidad más candente

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.jsVladimir Roudakov
 
jQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & CompressionjQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & CompressionPaul Irish
 
Web Projects: From Theory To Practice
Web Projects: From Theory To PracticeWeb Projects: From Theory To Practice
Web Projects: From Theory To PracticeSergey 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 - RJLeonardo Balter
 
Front End Development: The Important Parts
Front End Development: The Important PartsFront End Development: The Important Parts
Front End Development: The Important PartsSergey 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 2015Naresha K
 
#NewMeetup Performance
#NewMeetup Performance#NewMeetup Performance
#NewMeetup PerformanceJustin 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.3Fabien Potencier
 
Meetup Performance
Meetup PerformanceMeetup Performance
Meetup PerformanceGreg Whalin
 
High Performance Ajax Applications
High Performance Ajax ApplicationsHigh Performance Ajax Applications
High Performance Ajax ApplicationsJulien 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 codeLaurence 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 beginningAnis Ahmad
 
The Django Web Application Framework 2
The Django Web Application Framework 2The Django Web Application Framework 2
The Django Web Application Framework 2fishwarter
 
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 EssentialsMark 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 AngularJSHannes Hapke
 

La actualidad más candente (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
 
FuncUnit
FuncUnitFuncUnit
FuncUnit
 
jQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & CompressionjQuery Anti-Patterns for Performance & Compression
jQuery Anti-Patterns for Performance & Compression
 
Web Projects: From Theory To Practice
Web Projects: From Theory To PracticeWeb Projects: From Theory To Practice
Web Projects: From Theory To Practice
 
tut0000021-hevery
tut0000021-heverytut0000021-hevery
tut0000021-hevery
 
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
 
Django Heresies
Django HeresiesDjango Heresies
Django Heresies
 
Front End Development: The Important Parts
Front End Development: The Important PartsFront End Development: The Important Parts
Front End Development: The Important Parts
 
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
 
#NewMeetup Performance
#NewMeetup Performance#NewMeetup Performance
#NewMeetup Performance
 
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
 
Meetup Performance
Meetup PerformanceMeetup Performance
Meetup Performance
 
High Performance Ajax Applications
High Performance Ajax ApplicationsHigh Performance Ajax Applications
High Performance Ajax Applications
 
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
 
Introduction To Django (Strange Loop 2011)
Introduction To Django (Strange Loop 2011)Introduction To Django (Strange Loop 2011)
Introduction To Django (Strange Loop 2011)
 
jQuery from the very beginning
jQuery from the very beginningjQuery from the very beginning
jQuery from the very beginning
 
The Django Web Application Framework 2
The Django Web Application Framework 2The Django Web Application Framework 2
The Django Web Application Framework 2
 
Working with the django admin
Working with the django admin Working with the django admin
Working with the django admin
 
SharePoint and jQuery Essentials
SharePoint and jQuery EssentialsSharePoint and jQuery Essentials
SharePoint and jQuery Essentials
 
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
 

Similar a End-to-end testing with geb

Javascript first-class citizenery
Javascript first-class citizeneryJavascript first-class citizenery
Javascript first-class citizenerytoddbr
 
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 jQueryAlek Davis
 
Reactive Type safe Webcomponents with skateJS
Reactive Type safe Webcomponents with skateJSReactive Type safe Webcomponents with skateJS
Reactive Type safe Webcomponents with skateJSMartin 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íbridaJuliano 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 ModelvodQA
 
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 budgetDavid Lukac
 
Introduction to Django
Introduction to DjangoIntroduction to Django
Introduction to DjangoJames 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 SlingBob Paulin
 
Intro to jQuery @ Startup Institute
Intro to jQuery @ Startup InstituteIntro to jQuery @ Startup Institute
Intro to jQuery @ Startup InstituteRafael 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 Startedguest1af57e
 
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 LazuliRebecca 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 DevelopmentChristian Baranowski
 
jQuery in the [Aol.] Enterprise
jQuery in the [Aol.] EnterprisejQuery in the [Aol.] Enterprise
jQuery in the [Aol.] EnterpriseDave Artz
 

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

Javascript first-class citizenery
Javascript first-class citizeneryJavascript first-class citizenery
Javascript first-class citizenery
 
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...
 
Introduction to jQuery
Introduction to jQueryIntroduction to jQuery
Introduction to jQuery
 
Knolx session
Knolx sessionKnolx session
Knolx session
 
Reactive Type safe Webcomponents with skateJS
Reactive Type safe Webcomponents with skateJSReactive Type safe Webcomponents with skateJS
Reactive Type safe Webcomponents with skateJS
 
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
 
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...
 
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
 
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)
 
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
 
Introduction to Django
Introduction to DjangoIntroduction to Django
Introduction to Django
 
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
 
Geb presentation
Geb presentationGeb presentation
Geb presentation
 
Fewd week4 slides
Fewd week4 slidesFewd week4 slides
Fewd week4 slides
 
Intro to jQuery @ Startup Institute
Intro to jQuery @ Startup InstituteIntro to jQuery @ Startup Institute
Intro to jQuery @ Startup Institute
 
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
 
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
 
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...
 
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
 
jQuery in the [Aol.] Enterprise
jQuery in the [Aol.] EnterprisejQuery in the [Aol.] Enterprise
jQuery in the [Aol.] Enterprise
 

Último

OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full RecordingOpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full RecordingShane Coughlan
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...OnePlan Solutions
 
Best Angular 17 Classroom & Online training - Naresh IT
Best Angular 17 Classroom & Online training - Naresh ITBest Angular 17 Classroom & Online training - Naresh IT
Best Angular 17 Classroom & Online training - Naresh ITmanoharjgpsolutions
 
A healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfA healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfMarharyta Nedzelska
 
eSoftTools IMAP Backup Software and migration tools
eSoftTools IMAP Backup Software and migration toolseSoftTools IMAP Backup Software and migration tools
eSoftTools IMAP Backup Software and migration toolsosttopstonverter
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...confluent
 
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...OnePlan Solutions
 
Osi security architecture in network.pptx
Osi security architecture in network.pptxOsi security architecture in network.pptx
Osi security architecture in network.pptxVinzoCenzo
 
Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprisepreethippts
 
Amazon Bedrock in Action - presentation of the Bedrock's capabilities
Amazon Bedrock in Action - presentation of the Bedrock's capabilitiesAmazon Bedrock in Action - presentation of the Bedrock's capabilities
Amazon Bedrock in Action - presentation of the Bedrock's capabilitiesKrzysztofKkol1
 
Introduction to Firebase Workshop Slides
Introduction to Firebase Workshop SlidesIntroduction to Firebase Workshop Slides
Introduction to Firebase Workshop Slidesvaideheekore1
 
Keeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository worldKeeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository worldRoberto Pérez Alcolea
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringHironori Washizaki
 
Comparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfComparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfDrew Moseley
 
Effectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryErrorEffectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryErrorTier1 app
 
Large Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and RepairLarge Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and RepairLionel Briand
 
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdfExploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdfkalichargn70th171
 
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Angel Borroy López
 
SoftTeco - Software Development Company Profile
SoftTeco - Software Development Company ProfileSoftTeco - Software Development Company Profile
SoftTeco - Software Development Company Profileakrivarotava
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identityteam-WIBU
 

Último (20)

OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full RecordingOpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
 
Best Angular 17 Classroom & Online training - Naresh IT
Best Angular 17 Classroom & Online training - Naresh ITBest Angular 17 Classroom & Online training - Naresh IT
Best Angular 17 Classroom & Online training - Naresh IT
 
A healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfA healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdf
 
eSoftTools IMAP Backup Software and migration tools
eSoftTools IMAP Backup Software and migration toolseSoftTools IMAP Backup Software and migration tools
eSoftTools IMAP Backup Software and migration tools
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
 
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
 
Osi security architecture in network.pptx
Osi security architecture in network.pptxOsi security architecture in network.pptx
Osi security architecture in network.pptx
 
Odoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 EnterpriseOdoo 14 - eLearning Module In Odoo 14 Enterprise
Odoo 14 - eLearning Module In Odoo 14 Enterprise
 
Amazon Bedrock in Action - presentation of the Bedrock's capabilities
Amazon Bedrock in Action - presentation of the Bedrock's capabilitiesAmazon Bedrock in Action - presentation of the Bedrock's capabilities
Amazon Bedrock in Action - presentation of the Bedrock's capabilities
 
Introduction to Firebase Workshop Slides
Introduction to Firebase Workshop SlidesIntroduction to Firebase Workshop Slides
Introduction to Firebase Workshop Slides
 
Keeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository worldKeeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository world
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their Engineering
 
Comparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfComparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdf
 
Effectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryErrorEffectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryError
 
Large Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and RepairLarge Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and Repair
 
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdfExploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
 
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
 
SoftTeco - Software Development Company Profile
SoftTeco - Software Development Company ProfileSoftTeco - Software Development Company Profile
SoftTeco - Software Development Company Profile
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identity
 

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...