10 Testing Ratpack applications
Ratpack provides testing support, both at the functional and unit level. The ratpack-test
library contains the core support, and ratpack-test-groovy
provides convenient Groovy extensions.
Note: The ratpack
and ratpack-groovy
Gradle plugins auto configure these libraries to be added to the test classpath.
10.1 Unit testing
The primary integration point between Ratpack and your code is the Handler
contract. Ratpack provides the RequestFixture.handle()
and GroovyRequestFixture.handle()
for contriving the invocation of a handler. As the routing of requests is also implemented via handlers in Ratpack, this can also be used to test the routing.
Ratpack doesn’t couple to any particular test framework. It only provides some utilities that you can use from whatever test framework you choose. However, we strongly recommend using the Groovy based Spock Framework, even if your application is implemented in Java.
There is no special setup or teardown required for unit testing Ratpack applications, as by definition they require no server infrastructure.
10.2 Functional testing
Functional testing for Ratpack is built up around the ApplicationUnderTest.
This interface provides the address of the running application. Implementations of this interface will take care of starting the server for you.
10.2.1 TestHttpClient
Ratpack provides TestHttpClient in ratpack-test-groovy
, this is a client that makes it very simple to test status codes and responses.
Note below we use @Delegate so we just need to call get()
in the when block instead of client.get()
.
import ratpack.groovy.test.LocalScriptApplicationUnderTest
import ratpack.test.http.TestHttpClient
import ratpack.test.http.TestHttpClients
import ratpack.test.ApplicationUnderTest
class SiteSmokeSpec {
LocalScriptApplicationUnderTest aut = new LocalScriptApplicationUnderTest()
@Delegate TestHttpClient client = TestHttpClients.testHttpClient(aut)
def "Check Site Index"() {
get("index.html")
assert response.statusCode == 200
assert response.body.text.contains('<title>Ratpack: A toolkit for JVM web applications</title>')
}
def "Check Site Root"() {
get()
assert response.statusCode == 200
assert response.body.text.contains('<title>Ratpack: A toolkit for JVM web applications</title>')
}
def cleanup() {
aut.stop()
}
}
10.2.2 Geb
Geb can also be used we just need to set up the correct base URL and make sure the test app is shut down.
To set the correct base URL we will use the ServerBackedApplicationUnderTest instance to get the address and give that to the Geb browser instance.
For shutting down the app we will call stop in the cleanup function.
An example of a Geb based test is available here.
10.2.3 Application subsets, modules and extensions
The ratpack.test.embed
package (provided by the ratpack-test
library) provides the EmbeddedApp
type. These can be used to functionally test features in isolation, by creating small Ratpack apps within test cases and is actually the basis for how Ratpack itself is tested. This approach is most commonly used for functionally testing reusable Ratpack components (e.g. Guice modules) but can also be used for functionally testing a subset of an application.
The ratpack.groovy.test.embed
package (provided by the ratpack-groovy-test
library) provides the GroovyEmbeddedApp
Groovy specialization. This is the preferred implementation to use as it provides Guice support, flexibility and is easy to use.
The EmbeddedApp
type extends the ApplicationUnderTest
type. This makes them convenient to use with the TestHttpClient
mechanism provided by the ratpack-groovy-test
library.