Saturday, May 13, 2017

Running Tests - differences between Grails 2 and Grails 3 . . .

Grails - A highly-productive and rapid application development framework for developing modern applications on JVM which not only promotes several good design & development practices but also promotes testing. It takes testing as an integral part of development by making many hard things simple. It also makes writing & running tests as fun as development ;)

Grails 3 got so much better than Grails 2. However, there are several differences between Grails 2 and Grails 3 applications and testing is no exception. Due to these differences, confusions arise running tests while switching between Grails 2 and Grails 3 applications. Grails documentation covers this in detail, but it's handy to have all these at one place, and hence I write this blog post ;)

Grails 2 way

Usage grails [environment] test-app [SpecificTest ...] [test-phase:[spock]...]

[environment] is optional, defaults to test, when specified it can be just dev (shortcut for development) or -Dgrails.env=<environment> where <environment> can be development, test or custom-env .

[SpecificTest ...] is optional and when specified, it can take one or more SpecificTests to run separated by a space, each SpecificTest can also take wild card * at either class-level or package-level.

[test-phase:[spock] ...] is optional, defaults to all test phases, unit:, integration: and functional:test phases.  When specified it can be one, any two or all three of test phases separated by space.  The extra spock is only needed for running spock specifications.

Examples # run all tests: unit, integration and functional in test environment grails test-app # run all tests: unit, integration and functional in development environment grails dev test-app grails -Dgrails.env=development test-app # run all tests in 'specific-env' grails -Dgrails.env=<specific-env> test-app # run all unit tests in test environment grails test-app unit: # run all unit and functional tests in test environment grails test-app unit: functional: # run all unit tests in a specific package in test environment grails test-app com.giri.* unit: # run all unit & integration tests in a specific package in test environment grails test-app com.giri.* unit: integration: # run selected unit tests in test environment grails test-app Test1 Test2 unit: # run all unit tests in a package, particular test method of a test-case & specific test-case in test environment grails test-app com.giri.* Test1.testMethod1 MyTest2 unit: # run all spock unit test specifications in test environment grails test-app unit:spock

Grails 3 - Grails way

Grails 3 changed it's build system from GANT (Groovy ANT) to Gradle. It provides Grails commands for Gradle tasks. Gradle doesn't distinguish integration and functional tests and hence in Grails 3 both integration and functional test-phases are combined into integration test phase. In other words, both integration and functional tests are run as part of integration test-phase. Unlike Grails 2 which takes test-phase as test-phase:, Grails 3 takes test-phase as -test-phase.

Note the difference: at the end of test-phase vs. - in the beginning of the test-phase. Also, there is no need for giving any special indication for Spock specifications.

Usage grails [environment] test-app [SpecificTest ...] [-test-phase...]

[environment] is optional, defaults to test, when specified it can be dev (shortcut for development) or -Dgrails.env=environment where environment can be development, test or custom-env .

[SpecificTest ...] is optional and when specified, it can take one or more SpecificTests to run separated by space, each SpecificTest can also take wild card * at either class-level or package-level

[-test-phase ...] is optional, defaults to all: -unit and -integration. When specified it can be one, or both test phases separated by space.

Examples (with grails command) # run all tests: unit, integration and functional in test environment grails test-app # run all tests: unit, integration and functional in development environment grails dev test-app grails -Dgrails.env=development test-app # run all tests in 'specific-env' grails -Dgrails.env=<specific-env> test-app # run all unit tests grails test-app -unit # run all unit, integration & functional tests. Equivalent to not specifying test-phases at all grails test-app -unit -integration # run all unit tests in a specific package grails test-app com.giri.* -unit # run all unit, integration and functional tests in a specific package grails test-app com.giri.* -unit -integration # run selected unit tests grails test-app Test1 Test2 -unit # run all unit tests in a package, particular test method of a test-case & specific test-case grails test-app com.giri.* Test1.testMethod1 MyTest2 -unit

Grails 3 - Gradle way

Grails 3 has Gradle as it's build system and hence one can also use gradle tasks directly to run tests. There are only two test-phases: unit(test) and integration (integrationTest). Integration test-phase covers both integration and functional. Following are examples of running tests with gradle command:

Examples (with gradle command, it's recommended to use gradle wrapper: gradlew) # run all unit tests, units tests don't need to be run in a specific environment ./gradlew test # run all unit tests in a specific package ./gradlew test --tests com.giri.* # run all unit tests in a specific package matching the specific test class name pattern ./gradlew test --tests com.giri.My*Spec # run specific unit test spec ./gradlew test --tests com.giri.Test1Spec # run specific unit test-spec and a specific feature method (when method name is in JUnit style) ./gradlew test --tests com.giri.Test1Spec.testFeatureMethod # run specific unit test-spec and a specific feature method (method name is in Spock style) ./gradlew test --tests com.giri.Test1Spec."test feature method" # run all integration and functional tests in development environment ./gradlew -Dgrails.env=development integrationTest #run integration and functional tests in 'specific-env' ./gradlew -Dgrails.env=<specific-env> integrationTest # clean & run all integration and functional tests in development environment. Continue on failing unit tests ./gradlew -Dgrails.env=development clean test integrationTest --continue # assemble but skip running tests (assemble depends on integrationTest) ./gradlew -Dgrails.env=development assemble -x integrationTest NOTE # run all unit tests in a package, a particular test method of a test-case and a specific test-case I haven't found a way to get this... #./gradlew test --tests com.giri.* Test1.testMethod1 MyTest2

Knowing all these differences and possible ways of running tests will definitely be a time saver in a developer's day-to-day development.

My Other posts on Grails Testing

References

2 comments:

Bruno said...

Very nice post! Test is an indispensable activity in daily software development, and know how to run the tests is vital. Thanks!

Giridhar Pottepalem said...

Thanks Bruno. I appreciate for taking time to to comment on this.