Test driving development of Gaelyk applications
Introduction
Unit testing with Gaelyk Spock Helpers
Functional testing with Geb and Gaelyk Functional Test Tools
Live TDD demo
Grails Developer at BSkyB
Groovy user since 2010
Groovy and Open Source enthusiast
Geb committer
Gaelyk committer
Contributed to other Groovy projects: Grails, Gradle and Codenarc
TDD practitioner
This-code-is-not-clean-moaner ;)
Created by Guillaume
A lightweight Groovy toolkit for Google App Engine
Applications built using Groovlets and Groovy Templates
Own URL routing system
Lots of syntactic sugar for GAE datastore and services
Initially created by Marco Vermeulen (@marcoVermeulen)
Maintained by Vladimír Oraný (@musketyr)
Provides base Spock specification classes for testing Groovlets and routes
Targeted at making it easier to write unit tests for Gaelyk applications
Uses service mocks from appengine-testing and Spock mocks where service mocks are unavailable or it's more convenient
GaelykUnitSpec
ConventionalGaelykUnitSpec
GaelykRoutingSpec
basicGroovlet.groovy
located in src/webapp/WEB-INF/groovy/
request.hello = "Hello ${params.name}!"
forward '/WEB-INF/pages/hello.gtpl'
class BasicGroovletSpec extends GaelykUnitSpec {
void setup() {
groovlet 'basicGroovlet.groovy'
}
void 'hello message is constructed'() {
given:
basicGroovlet.params.name = 'Gaelyk'
when:
basicGroovlet.get()
then:
basicGroovlet.request.hello == 'Hello Gaelyk!'
}
}
class BasicGroovletSpec extends ConventionalGaelykUnitSpec {
void 'hello message is constructed'() {
given:
basicGroovlet.params.name = 'Gaelyk'
when:
basicGroovlet.get()
then:
basicGroovlet.request.hello == 'Hello Gaelyk!'
basicGroovlet.forward == '/WEB-INF/pages/hello.gtpl'
}
}
Read and modify variables in Groovlet binding
Verify interactions with the response to check what was written out
Check state of the datastore and GAE services after Groovlet execution
See what has been logged
get '/about', forward: '/WEB-INF/pages/about.gtpl'
post '/number/@number',
redirect: '/number.groovy?number=@number',
validate: { number.isNumber() }
class RoutesSpec extends GaelykRoutingSpec {
void setup() {
routing 'routes.groovy'
}
void 'about route'() {
expect:
with get('/about'), {
matches
redirectionType == FORWARD
destination == '/WEB-INF/pages/about.gtpl'
}
}
...
...
void 'number route for not a number'() {
expect:
!post('/number/NaN')
}
void 'number route'() {
expect:
with post('/number/123'), {
matches
variables.number == '123'
redirectionType == REDIRECT
destination == '/number.groovy?number=123'
}
}
}
Verify routes for put, delete and all methods
Test ignored routes
Check email and jabber routes
Test routes with single and double star wildcards
Assert route caching
Test capability-aware routes
Verify namespaced routes
Template outputs
JavaScript
Integration of all layers
Everything you're not able to unit test
Gradle GAE plugin supports running functional tests since 0.7
gradle gaeFunctionalTest
Geb
Gaelyk Remote Control
Gaelyk Functional Test Tools
It's a browser automation solution
Can be used for acceptance testing of web applications
WebDriver under the hood
JQuery-like content selection
Page Object modeling of content
Adapters for multiple test frameworks:
Allows to run arbitrary code in a remote Gaelyk application
Slightly modified version of Groovy Remote
Adds all Gaelyk specific variables to the context of commands
Installed by adding an endpoint served by RemoteControlServlet
Works only in local mode
Simplifies accessing remote application with Gaelyk Remote
Easy way to clean up datastore after test execution
Provides a DSL to set up datastore state
Allows to login into the application with a single method call
Luke Daley
My blog - blog.proxerd.pl