How to test your Grails application
gr8conf.us 2014
Original Title
How to test the $%# out of your grails app
whoami
Colin Harrington
Principal Consultant
Object Partners Inc
@ColinHarrington
colin.harrington@objectpartners.com
Basics
http://grails.org/doc/latest/guide/testing.html
grails test-app
-------------------------------------------------------
Running Unit Tests…
Running test FooTests...FAILURE
Unit Tests Completed in 464ms …
-------------------------------------------------------
Tests failed: 0 errors, 1 failures
Targeting
grails test-app SimpleController
grails test-app *Controller
grails test-app some.org.*Controller
grails test-app some.org.*
grails test-app some.org.**.*
grails test-app SimpleController.testLogin
grails test-app some.org.* SimpleController.testLogin BookController
Phase:Type
grails test-app unit:
grails test-app :spock
grails test-app phase:type
grails test-app functional:spock
Phases
-
unit
-
integration
-
functional
-
custom
Support to create your own Phases!!
Framework
-
Services
-
Controllers
-
Filters
-
Domains
-
Constraints
-
Command objects
-
Codecs
- Configs
-
GSP
-
UrlMappings
-
WebFlow
Test mixins
grails.test.mixin.TestFor
grails.test.mixin.Mock
grails.test.mixin.TestMixin
grails.test.mixin.support.GrailsUnitTestMixin
grails.test.mixin.domain.DomainClassUnitTestMixin
grails.test.mixin.services.ServiceUnitTestMixin
grails.test.mixin.web.ControllerUnitTestMixin
grails.test.mixin.web.FiltersUnitTestMixin
grails.test.mixin.web.GroovyPageUnitTestMixin
grails.test.mixin.web.UrlMappingsUnitTestMixin
grails.test.mixin.hibernate.HibernateTestMixin
GrailsUnitTestCase
@Deprecated
Example Controller Test
import grails.test.mixin.TestFor import spock.lang.Specification
@TestFor(SimpleController) class SimpleControllerSpec extends Specification { void "test hello"() { when: controller.hello() then: response.text == 'hello' } }
model
UrlMappings
static mappings = {
"/actionOne"(controller: "simple", action: "action1")
"/actionTwo"(controller: "simple", action: "action2")
}
import com.demo.SimpleController
import grails.test.mixin.TestFor
import spock.lang.Specification
@TestFor(UrlMappings)
@Mock(SimpleController)
class UrlMappingsSpec extends Specification {
void "test forward mappings"() {
expect:
assertForwardUrlMapping("/actionOne", controller: 'simple', action: "action1")
assertForwardUrlMapping("/actionTwo", controller: 'simple', action: "action2")
}
}
@Mock
Real in-memory GORM database (unit tests)
@Mock(Book)
Magic
no SQL support
(GORM API not GORM Hibernate)
Spock Data Driven
http://spock-framework.readthedocs.org/en/latest/data_driven_testing.html
class Math extends Specification {
def "maximum of two numbers"(int a, int b, int c) {
expect:
Math.max(a, b) == c
where:
a | b | c
1 | 3 | 3
7 | 4 | 4
0 | 0 | 0
}
}
Hierarchy
GrailsUnitTestMixin
static GrailsWebApplicationContext applicationContext
static GrailsWebApplicationContext mainContext
static GrailsApplication grailsApplication
static ConfigObject config
static MessageSource messageSource
Map validationErrorsMap = new IdentityHashMap()
Set loadedCodecs = []
ControllerUnitTestMixin
-
webRequest
-
request
-
response
-
servletContext
-
groovyPages
-
views
-
session
-
params
-
view
-
model
-
flash
-
sets up codecs
GroovyPageUnitTestMixin
UrlMappingsUnitTestMixin
Perspectives
Unit Testing
No IO in Unit tests!
Unit tests just test your unit!
Mocks/Spies/Stubs
Unit being tested:
Class, Hierarchy, MethodLevel.
Integration Testing
integration of Spring components
Real Database
Spring Container bootstrapped
Transaction wrapper
No HTTP connector.
Functional Testing
Test the whole Application
From the outside
All the layers are there.
As a user would
Browser, API, etc.
Stubs
service.metaClass.myMethod = { //does nothing
//we don't care if it was called or not }
Spies
Spy on the input ..
service.metaClass.someMethod = { input ->
assert input == "expected"
}
Mocks
Mocks
Spies
Stubs
Mocks
-
GrailsMock and mockFor
- in the GrailsUnitTestMixin
- Groovy's MockFor (Capital M)
-
Spock's Interactions Mock()
MetaClass Magic
Additional Perspectives
Smoke tests
performance testing
security (pen) testing
3rd party
Prod testing/monitoring.
Continuous Integration
Occasional Integration
Cluster testing
Tools
IDE
Jenkins
GROM
Quick feedback
Script to open test-reports.
Plugins
Plugin Portal
Test build scope
test ':fixtures:1.3'
Build Scope
BuildConfig.groovy
plugins { test ':fixtures:1.3' }
Data Generator/helper
Code Coverage/Quality
Running tests
Testing Frameworks
Functional Tests
-
GEB
-
Webdriver
-
Selenium RC
- webtest
- functional-test
- rest-client-builder
JavaScript
Tools
Title
Know your tools
Test from different angles
Practice Practice Practice
Build your own tools
Thank you
@ColinHarrington
How to test your Grails application
By Colin Harrington
How to test your Grails application
- 4,925