SlideShare ist ein Scribd-Unternehmen logo
1 von 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

Weitere ähnliche Inhalte

Was ist angesagt?

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
 

Was ist angesagt? (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
 

Ähnlich wie 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
 

Ähnlich wie 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
 

Kürzlich hochgeladen

The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfproinshot.com
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionSolGuruz
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxComplianceQuest1
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdfPearlKirahMaeRagusta1
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsAndolasoft Inc
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplatePresentation.STUDIO
 
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...kalichargn70th171
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionOnePlan Solutions
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
How to Choose the Right Laravel Development Partner in New York City_compress...
How to Choose the Right Laravel Development Partner in New York City_compress...How to Choose the Right Laravel Development Partner in New York City_compress...
How to Choose the Right Laravel Development Partner in New York City_compress...software pro Development
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnAmarnathKambale
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...OnePlan Solutions
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerThousandEyes
 

Kürzlich hochgeladen (20)

The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdf
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdf
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
How to Choose the Right Laravel Development Partner in New York City_compress...
How to Choose the Right Laravel Development Partner in New York City_compress...How to Choose the Right Laravel Development Partner in New York City_compress...
How to Choose the Right Laravel Development Partner in New York City_compress...
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 

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