15.3 Functional Testing 6.0.0

(Quick Reference) # 15.3 Functional Testing Version: 6.0.0 ## 15.3 Functional Testing Functional tests involve making HTTP requests against the running application and verifying the resultant behaviour. This is useful for end-to-end testing scenarios, such as making REST calls against a JSON API. Grails by default ships with support for writing functional tests using the Geb framework. To create a functional test you can use the `create-functional-test` command which will create a new functional test:
    $ grails create-functional-test MyFunctional
The above command will create a new Spock spec called `MyFunctionalSpec.groovy` in the `src/integration-test/groovy` directory. The test is annotated with the Integration annotation to indicate it is an integration test and extends the `GebSpec` super class:
    @Integration
    class HomeSpec extends GebSpec {

        def setup() {
        }

        def cleanup() {
        }

        void "Test the home page renders correctly"() {
            when:"The home page is visited"
                go '/'

            then:"The title is correct"
                $('title').text() == "Welcome to Grails"
        }
    }
When the test is run the application container will be loaded up in the background and you can send requests to the running application using the Geb API. Note that the application is only loaded once for the entire test run, so functional tests share the state of the application across the whole suite. In addition the application is loaded in the JVM as the test, this means that the test has full access to the application state and can interact directly with data services such as GORM to setup and cleanup test data. The `Integration` annotation supports an optional `applicationClass` attribute which may be used to specify the application class to use for the functional test. The class must extend GrailsAutoConfiguration.
    @Integration(applicationClass=com.demo.Application)
    class HomeSpec extends GebSpec {

        // ...

    }
If the `applicationClass` is not specified then the test runtime environment will attempt to locate the application class dynamically which can be problematic in multiproject builds where multiple application classes may be present. When running the server port by default will be randomly assigned. The `Integration` annotation adds a property of `serverPort` to the test class that you can use if you want to know what port the application is running on this isn’t needed if you are extending the `GebSpec` as shown above but can be useful information. If you want to run the tests on a fixed port (defined by the `server.port` configuration property), you need to manually annotate your test with `@SpringBootTest`:
    import grails.testing.mixin.integration.Integration
    import org.springframework.boot.test.context.SpringBootTest
    import spock.lang.Specification

    @Integration
    @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
    class MySpec extends Specification {

        // ...

    }
| Quick Reference (hide)