Slides for a talk I present at SkillsMatter.
http://skillsmatter.com/podcast/agile-testing/acceptance-testing-with-geb
This talk will cover the basics of using Geb http://geb.codehaus.org to automate browser testing.
It will compare Geb with raw WebDriver/Selenium showing Geb's expressive Groovy API.
It will also demonstrate how to integrate Geb with acceptance testing frameworks, namely Cucumber via Cuke4Duke.
We will also cover an experience report on how and why we transitioned from raw WebDriver to Geb and how existing WebDriver projects can be ported across to Geb with minimal initial effort due to its underlying use of WebDriver.
4. Cuke4Duke
Allow Cucumber to be run on the JVM via JRuby
All programming can be done in
Java
Groovy
Scala
...
Good fit for teams already fluent in JVM languages.
5. Features - Wikipedia Example
Feature: Search
In order to learn more
As an information seeker
I want to find more information
Scenario: I'm feeling lucky
Given I am on the Wikipedia homepage
When I search for "dog"
Then I am shown the "Dog" article
6. Step Definitions - Wikipedia Example
Given(~'I am on the Wikipedia homepage') {
browser.go()
}
When(~'I search for "(.+)"') { query ->
browser.find('#searchInput').value(query)
browser.find('#searchButton').click()
}
Then(~'I am shown the "(.+)" article') { article ->
assert browser.find('h1').text() == article
}
7. Where does the browser come from?
import geb.Browser
this.metaClass.mixin(cuke4duke.GroovyDsl)
Before {
browser = new Browser('http://wikipedia.org')
}
After {
browser.driver.manage().deleteAllCookies()
}
8. Geb - Very Groovy Browser
Automation
http://geb.codehaus.org/
Provides an expressive API for interacting with web
browsers.
Excellent documentation provided by the manual.
9. Geb - Frequently used APIs
go('/search')
$('#query').value('dog')
$('#query').value() == 'dog'
$('#submit').click()
Covers 90% of use cases
10. Geb - Form Shortcuts
def form = $('#register')
form.firstname = 'Richard'
form.lastname = 'Paul'
form.blog = 'http://rapaul.com'
form.submit()
// Shortcut for
form.find('input[name=firstname]').value('Richard')
// Similarly can inspect with
assert form.firstname == 'Richard'
11. Geb & WebDriver
Geb uses WebDriver under the hood.
Automatically chooses a driver based on classpath.
HtmlUnit
Firefox
IE
Chrome
Can select a specific driver using geb.driver property.
12. WebDriver to Geb Migration
Starting with WebDriver API
browser.findElementByCssSelector('.x')
Change browser from WebDriver to Geb
browser.driver.findElementByCssSelector('.x')
Refactor when working in that area
browser.find('.x')
13. Groovy's PowerAssert
PowerAssert shows values for intermediary statements
assert $('.divTop20item strong')*.text() =~ 'English'
| | |
[] [] ..regex..
Can tell if the selector matched elements or if the text
actual text didn't match without needing to rerun scenario.
14. Geb & the Page Object Pattern
Defines a Content DSL for encapsulating reusable aspects of a
page.
Modules for page fragments.
We use Cucumber's steps as the item of reuse so don't use the
Page Object Pattern.
http://geb.codehaus.org/manual/latest/pages.html#pages
http://skillsmatter.com/podcast/groovy-grails/talk-by-tomas-lin
15. Advantages of Geb (over WebDriver)
Expressive API
Caching of WebDriver between scenarios
All the power of underlying WebDriver if needed
16. Acceptance Testing @ F1000
2 week iterations, releasing every iteration
Story wall with columns
Sprint backlog, specify, dev/test, done
Acceptance tests written with Cucumber
Outside in development
Acceptance tests drive view layer
View layer drivers controller
Controller drives service
...
Acceptance & unit tests running in CI (TeamCity)
17. TeamCity
3 separate builds in TeamCity
Key Features (tagged with @keyfeature)
Non Key Features
Work in Progress (tagged with @wip)
Any WIP scenarios that pass fail the build
Cucumber supports JUnit report format
Instant notification on first failure
Build statistics
More detail at:
http://www.rapaul.com/2010/12/17/cucumber-maven-teamcity/
18. Lessons Learned
The Why & What are so much harder than the How
Identifying the value (In order to) is difficult
Important to have all team members in planning session
Declarative steps instead of imperative trails of clicked GUI
items
Small slices
Vertical slicing (pairing for knowledge gaps)
As small as possible
Initial search had no sorting, paging, filtering etc
Feature Toggles
YAGNI
19. Lessons Learned (continued)
Confidence in acceptance tests is critical
8 hours does not give confidence
Flakey tests should be refactored
Forgetting details for features near end of iteration
Writing up full features & scenarios during planning is time
consuming.
Capture important details on back of card.
Getting stakeholders to look at Cucumber reports is hard
Marking up key features
20. Tips for working with Cucumber
Tag (@now) to just run the scenario you are working on
Find unused steps with --format usage --dry-run
Cuke4Duke with Groovy uses a lot of memory
Both heap and PermGen, RAM is cheap