Showing posts with label spock. Show all posts
Showing posts with label spock. Show all posts

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

Sunday, December 11, 2016

Know test cases run order in Grails-3 app to help solve issues with "test pollution". . .

In a Grails 3 application that I upgraded recently from Grail 2.2.1 to Grails 3.2.1, it was very puzzling when an integration specification (test case upgraded from Grails 2.2.1) with few feature methods (test case methods) passed locally but failed on the Bamboo CI server. From the kind of failure, it was evident that this particular specification failed due to "data pollution"- some unwanted data hanging around in the database by the time it ran.

The failed specification was an integration test specification and I was under the impression when grails test-app command is run, the test specifications are run in the order of test categories: unit tests, followed by integration tests, followed by functional tests.  If that was the case, the integration test that failed should have never failed as all integration specifications were properly annotated with @Integration and @Rollback and there was no setup() method creating data that couldn't be rolled back by @Rollback annotation causing the pollution. Grails 3 doesn't distinguish integration tests from functional test (at least when they are run as part of integrationTest gradle task), though they are distinguished by code. Typically integration tests extend Spock's Specification and annotated with @Integration and @Rollback, where as functional tests simply extend GebSpec.

Both local and CI server ran test-app task against an empty database. The only difference was: local was on Mac OS X and Bamboo CI server was on Linux. There was a functional test (GebSpec) in the set of integration tests under integration-test/groovy/myapp dir which had a bunch of feature methods. That one obviously did not have any data cleanup methods like: cleanup() or cleanupSpec(). I didn't even want to do any cleanup at the end in that functional spec because it was perfectly fine with local run. That led me to think of test data pollution causing this issue. But the most puzzling question was: "Why this functional test was coming in between and polluting integration test cases?" The only way to find it out was to know the order in which test-cases run and compare local run with Bamboo CI run.

I read through some documentation of Spock and Junit but didn't find an easy way of knowing the order of tests. Spock supports @Stepwise annotation to specify the order, but it was only within a specification. I read through some Gradle documentation about the test task and found a way to tap into the lifecycle of test cases and print the description of each test case that gets run. This helped me finding test-cases run order, and compare local with CI run to nail down the issue. Locally on Mac OS X, test-cases ran in alphabetical order, where as on Bamboo CI server (Linux), they seemed running in random order and one GebSpec functional test that was part of integration tests that got run along with all integration tests during integrationTest task as part of grails test-app task was the culprit. It was a coincidence that the functional specification name alphabetically was the last in the set of integration tests. On Mac OS X, it ran as the very last test case but on Linux it was running in between causing the following test to fail by leaving data in the database and thus leading to "test data pollution".

Following is the code snippet I added in build.gralde that prints each test before it's run:

/** * Configure test and integrationTest tasks. * Added beforeTest closure to get notified before a test is run. The closure simply logs the test descriptor which * indicates the test method that is being executed. Added to help find the test execution order differences between two * test runs or even differences between two systems like local, ci etc. */ test { beforeTest { descriptor -> logger.lifecycle("Running test: " + descriptor) } } integrationTest { beforeTest { descriptor -> logger.lifecycle("Running test: " + descriptor) } }

This will print as shown below, for instance when unit tests are run with the command: grails test-app -unit
:compileJava UP-TO-DATE :compileGroovy :buildProperties :processResources :classes :compileTestJava UP-TO-DATE :compileTestGroovy :processTestResources UP-TO-DATE :testClasses :test Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=2048m; support was removed in 8.0 Running test: Test testIndex(myapp.FirstTestSpec) Running test: Test testList(myapp.FirstTestSpec) Running test: Test testCreate(myapp.FirstTestSpec) Running test: Test testList(myapp.SecondTestSpec) Running test: Test testCreate(myapp.SecondTestSpec) Running test: Test testIndex(myapp.ThirdTestSpec) . . .

Ideally the order in which test cases run should not be a concern at all. But when functional tests and integration tests run together as integration tests, there are high chances of functional tests and integration tests getting mixed up in the sequence of running integration tests, and thus polluting integration tests. So, knowing the order in which test cases run will help solving this problem.

After finding out the issue, I refactored test cases under integration-test/groovy/myapp directory and separated out functional from integration tests into two different folders/packages (myapp.integration and myapp.functional) and even separated out their executions by running unit, integration and functional in 3 steps instead of running all in one step (grails test-app) as follows:
grails -Dgrails.env=development test-app -unit grails -Dgrails.env=development test-app myapp.integration.* -integration grails -Dgrails.env=development test-app myapp.functional.* -integration

This will guarantee that my functional tests which are expected to leave data in the database after run (as they were written) are run as the last group of tests in a bit controlled manner.

References

Gradle Test task documentation

Wednesday, September 17, 2014

SpringOne2GX-2014 Day-2

Day-2 Sessions

Groovy in 2014 and Beyond - Guillaume Laforge
Groovy in 2014 and Beyond - Guillaume Lafarge
The very first session I chose to attend was Groovy in 2014 and Beyond by Guillaume Laforge, the Head of Groovy Development. It was very informative session giving details on Groovy's recent neat features and future possibilities and directions.

My notes
  • Groovy news letter is out every Tue
  • Google+ groovy page google.com/+groovy
  • Google+ groovy community
  • Closures vs. Lambdas
  • Traits
    • New: trait keyword
    • Like interfaces but with method bodies
    • Multiple inheritance without the <<Diamond>> problem
    • When a class implements traits, methods are available and visible, traits properties are also visible making the class stateful
    • Inheritance: trait can extend another trait and inherit properties
  • New: @TailRecursive
  • New: @Sortable - contributed by Griffon, Makes class comparable, can specify includes, excludes.
  • @BaseScript improvement, custom internal abstract method
  • NIO2 module
  •  JDK7+ NIO2 Path
    •  All familiar methods like withReader, eachLine, << , readLines etc. in GDK on File have been retrofitted on Path as well
  •  JSON
    • Rewrote and performance improvement, 3 to 4 times faster than Jackson and GSON JsonSlurper for configuration files
  •  Markup Template Engine
  •  GroovyDoc 2.3.6 and up - nicer looking javadoc
  •  beta.groovy-lang.org - generated from groovy template engine, groovy code, ascii doctor
  • Groovy 2.4
    •  Android support bit.ly/nyt-groovy
    • Groovy Macros - Authoring AST transformations is verbose, with Groovy macros it is simpler
  •  Groovy 3.0
    • New MOP goals: leverage JDK 7+ invoke dynamic, get java-like performance even for dynamic code
  •  Antlr v4 grammar - Google summer code. student helping
    • Groovy still uses antlr v2, but v3 and v4 are out, harder to evolve with v2 as groovy grammar evolved from Java grammar
  •  Java 8 Support
    • Lambdas, Stream API, Date and Time API, method references, default methods in interfaces, annotations on types and repeated annotations

Grails 3.0 Preview - Graeme Rocher
Grails 3.0 Preview
This session gave a good view of Grails future and how it's shaping up in view of Spring Boot getting so much of traction in the community lately. Grails is grails and future versions are going to leverage Spring Boot.

My notes
  • Grails 2.4.3 is the recent
  • Grails 3.0 - The Future
    • is the master branch @Github
    • Goals: embrace Gradle, Reach outside the Servlet Container, deployment with runnable jars, Build on Spring Boot, Support micro services, many improvements
    • Grails is one of the entry layers along with Spring XD, with Groovy being at the foundation of Spring IO platform
    • Gradle as the build system
    • Demo
    • Benefit of building upon Spring boot is - IDE tooling doesn’t need any special efforts. Project can just be imported as Gradle project into IntelliJ community edition and the app can just be run as an application. Grails 3.0 has Application class which extends Spring boot class with run method. This makes the application runnable from the IDE.
    • Spring Boot is going to handle Embedded Servers, Runnable JARs, WAR packaging, Scripting and Micro services, includes monitoring and health checkes, Grails takes advantage of Spring Boot.
    • Full Boot powered micro services
    • Servlet 3.x only and no web.xml
    • Simplifications (just DispatchedServlet and GrailsController)
      • GrailsPageFilter, UrlMappingFilter are gone
      • Less code to maintain, better performance, no internal forwarding, better integration with spring
    • Deprecations /Removals
      • Servlet 2.5 Support, no web.xml
      • GDoc replaced with AsciiDoctor
      • Gant & current build system is gone
      • Filters replaced by new mechanisms
  • Evolution of Metaprogramming
  • Grails 1.x: runtime meta programming ExpandoMetaClass, Grails 2.x - compile time, Grails 3.0- Traits and Transforms
  • Most code previously added by AST Transforms will now be added by Traits
  • Application profiles
  • Grails 3.0 Challenges: Compatibility-plugins, build system, Modularization-servlet API independence. Refactoring.
  • The whole package structure has changed, package renaming, separating out new public api and old api etc.

Testing Java, Groovy, Spring and Web applications with Spock - Peter Neiderwieser
Testing Java, Groovy, Apring and Web applications with Spock - Peter Neiderweiser
This was a good Spock session with great many details of Spock as a unit and integration testing FW for Spring and Web applications.

My Notes
  • Spock Web console: https://meetspock.appspot.com/
  • expect block. Everything in this block is treated as assertions. So you don’t need special assertion FW or assert statements.
  • given: when: then: blocks
  • multiple when: then: blocks
  • Mocking FW built in
  • Async support
  • Extensions: Spring, Guice, Tapestry, Unitils, JUnit rules etc.
  • Default Grails FW testing (since 2.3)
  • Diff Dialog Window: Shows differences of assertion failures in a separate window. IntelliJ and Eclipse will have clickable links to get to this window.
  • Mocking- Mock(MyClass)
    • def sub1 = Mock(Subscriber)
    • sub1.receive(_) >> {throw new Exception()} //throws an exception whenever receive method is called on sub1 that takes no arguments. (_) groovy notation to indicate that the method takes no arguments
  • Stubs and Spies
    • Stub - weaker form of mock object
    • Spy- can spy on class, creates a real object under the spy
  • Advanced Mocking for testing Groovy code. GroovyMock for groovy code that has dynamic code, GroovySpy, GroovyStub. The call to mock object has to be a groovy call.
  • Testing Spring Applications
    • Full support for Spring Test Context Framework (2.5 - 4.1, the very latest)
    • Use spock-spring module
    • @SpringApplicationConfiguration
  • Testing web applications
    • Spock + Geb (Groovy Browser Automation, pronounced jeb)- Groovy lib on top of Selenium, easy to script your browser
    • Functional Web Testing
    • Business Friendly Reporting
    • gradle dependencies: geb-spock, geb-junit4
    • MySpec extends GebReportingSpec
    • @Stepwise spock annotation- when annotated spock treats each method as a step instead of a test case.
    • go “/login” //navigate to login page
    • $(“h1”).text == ‘Login Successful” //Geb offers jQuery like accessing html elements
    • when one step fails, it wouldn’t even run the other steps.
    • Page Object pattern: a small abstraction that abstracts the page for the purpose of testing. LoginPage extends Page {}
    • TIP: def page = to LoginPage //tell intelliJ what page object is for code completion
    • alertDialog, alertMessage, alertClosedButton, alertDialogIsClosed
    • Spock report
    • @Title annotation for a testcase
    • @Narrative multi-line
    • @Issue(http://...) //will show up in the report
    • GebConfig.groovy (baseUrl = “”, reportsDir=”geb-reports”, driver = “chrome”)
Spring Boot for the Web Tier - Dave Syer, Philwebb
Spring Boot for the Web Tier - Dave Syer, Phil Webb
This session gave some insights into the Spring Boot especially from the web application point of view.

My Notes
  • Conventions: static content
  • webjars- client side libs like jQuery packaged as jar and served as static content, gives all dependency management advantages, transitive, version etc.
  • Grunt toolchain - Javascript toolchain
  • Wro4j - Web resource optimizer
  • Dynamic content - Templating Support
    • Thymeleaf (modern templating fw) - Spring Boot uses this
    • Groovy Templating Language (DSL based)
    • Freemaker, Velocity
    • JSP(Not recommended)
    • Conventions
    • Choose specific locale using spring.mvc.locale property
    • Choose specific date format using spring.mvc.date-format property
    • Hidden Gems: RequestContextHolder,
    • HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE, Converter, Formatter etc.
    • spring.mvc.message-codes-resolver-format to add a MessageCodesResolver- prefix_error_code or postfix_error_code
    • Embedded Server: Default is Tomcat
    • When using WARs a ServletContainerInitializer (Tomcat) creates Spring ApplicationContext
    • When using embedded server, ApplicationContext creates the server.
    • Embedded server customization, Tomcat, Jetty specific. TomcatConnectorCustomizer, TomcatContextCustomizer
    • Embedding Ratpak
Making Spring Boot even Groovier - Graeme Rocher
Making Spring Boot even Groovier - Graeme Rocher
This was another good session in which Graeme Rocher demonstrated step by step of making Spring Boot more groovier. Of course, Groovy makes any Java based technology groovier ;)

My Notes
  • Spring Boot is not dependent on Groovy but already has groovy
  • Spring Boot Components
    • Boot CLI
    • Spring Groovy Templates
    • Spring Boot AutoConfiguration
  • Adding Groovy to Spring Boot
    • Starting Slow: Gradle for the build, Spock for testing
    • Digging deeper: Groovy controllers, Groovy templates
    • Going Groovy all the way: GORM, GSP
  • Step 1: Adding a powerful build system: Flexible and Powerful, Based on Groovy DSL, extremely well documented, Used by Android, Better than Maven ;)
    • Builds are not static. Maven builds are static, it is not designed to be changed.
  • Step 2: Spock (Path to enlightenment ;))
    • Data driven tests, power assertions with detailed diagnostics of failures, Integrated mocking / stubbing
    • Add Spock as a test scoped dependency testCompile(“spock ….”)
  • Step 3: Groovy Everywhere
    • Seamlessly mixed with Java code, with @CompileStatic now there is no longer performance cost. Performance difference between Groovy and Java with @CompileStatic is basically ZERO.
    • Just annotate classes with @CompileStatic and the job is all done ;)
    • When you use @CompileStatic, meta programming cannot be used. If there is any particular method that needs dynamic behavior, just annotate that particular method with @CompileDynamic, that makes that method dymanic leaving the class compiled to static.
    • With tooling being good, it is now easier than ever to introduce Groovy into the Java organizations.
    • Why Groovy? : Get Java 8 Lambdas but deployable to any JVM (1.5+), Extensive Groovy SDK, Easier to learn, Android support, static or dynamic compilation
  • Step 4: Groovy Templates- Writing views with Groovy
    • MarkupTemplateEngine introduced in Groovy 2.3
    • Add groovy-templates as a dependency
    • Add templates with .tpl extension into src/main/templates/layouts and views into src/main/templates/views
    • Elegant, readable views expressed in Groovy
  • Step 5: GORM
    • Powerful multi-datastore query layer (HIBERNATE, MongoDB, redis, Cassandra, Neo4j)
    • Dynamic finders, criteria and persistence methods, Automatic mapping of entities to underlying database
    • Add dependency gorm-hibernate4-spring-boot
    • Each GORM entity needs to be annotated with grails.persistence.Entity @Entity. With this Spring Boot will detect the class as GORM entity. That’s all you need to do.
    • Data source configurations remain same, GORM will pick it up.
    • with @GrailsCompileStatic, dynamic finders in GORM work. Not with @CompileStatic ;)
    • GORM for HIBERNATE is trivial annotate with Grails @Entity
    • Powerful query composition with detached criteria
    • GORM for MongoDB
      • Geospacial querying
      • GeoJSON models, full text search, stateless and stateful modes etc.
  • Step 6: GSP
    • view rendering engine from Grails
    • Supports tag libraries, xss/double encoding prevention
    • Layout, templates and views
    • More designer friendly
    • XSS prevention, development and precompiled mode
    • Impossible in GSP to double escape data, GSP escapes all data rendered.
    • Just add grails-gsp-spring-boot dependency
    • Add templates with .gsp extension in src/main/resources/templates/views/
    • main.gsp gets applied to every page
    • can do all normal grails things for composing views.
    • Each gsp is a fully formed page with <html>...</html> tags, though main.gsp is taken as the template and only <title> and <body> is taken from the page. It makes designers to work on individual pages.
    • easy definition of tag libraries in Groovy code
    • Elegant markup based views