Test Driven In Groovy

Uploaded on

Using Groovy for unit and acceptance testing. Includes material on GMock and cuke4duke.

Using Groovy for unit and acceptance testing. Includes material on GMock and cuke4duke.

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads


Total Views
On Slideshare
From Embeds
Number of Embeds



Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

    No notes for slide
  • NEW
  • Behaviour-driven development is an “outside-in” methodology. It starts at the outside by identifying business outcomes, and then drills down into the feature set that will achieve those outcomes. Each feature is captured as a “story”, which defines the scope of the feature along with its acceptance criteria. This article introduces the BDD approach to defining and identifying stories and their acceptance criteria.


  • 1. Test-Driven in Groovy
    Joseph Muraski
    Christopher Bartling
  • 2. Joseph Muraski
    Independent Consultant in the Twin Cities
    Develop enterprise applications using Java, .Net, Groovy, Grails…
    Email: joe.muraski@mantacs.com
    Twitter: jmuraski
    Blog: joemuraski.blogspot.com
  • 3. Christopher Bartling
    Independent consultant, based in the Twin Cities
    Teach, mentor and coach for DevJam
    Experiences include building enterprise applications with Java, Groovy, Grails, .NET, and Adobe Flex
    Email: chris.bartling@gmail.com
    Twitter: cbartling
    Blog: bartling.blogspot.com
  • 4. Goals of the workshop
    Introduce features in Groovy that will help your Java testing efforts
    Introduce Cucumber and cuke4duke as new tools in your testing arsenal
    Demonstrate unit, integration, and acceptance testing with Groovy and Cucumber (via cuke4duke) via an example Java web application
    Get hands on with these technologies
  • 5. Summary
    Design principles
    Testing facilities built into Groovy
    Acceptance/BDD testing with Groovy
    Cucumber and cuke4duke
    Presentation and code available
    Instructions on how to use Mercurial to clone the repository or retrieve everything in an archive file
  • 6. Prerequisites for hands on labs
    Java 1.6 JDK installation
    Maven 2
    That’s it…Maven will take care of resolving all the other dependencies
  • 7. Maven 2
    Maven2 installation required
    We’re using version 2.2.1
    This is not a Maven presentation
    We use it because it’s quite handy and does a great job of resolving dependencies
    Maven commands will be presented when needed
  • 8. Maven plugins used
  • 9. Sample web application
    Starting the web app
    mvn jetty:run-exploded
    Running tests
    mvn tests
    Running cuke4duke
    mvn cuke4duke:cucumber
  • 10. Design principles
    Single responsibility per class (high cohesion)
    Loose coupling of collaborators (low coupling)
    Injection of dependencies
  • 11. Why Groovy?
    Groovy works seamlessly with Java
    It’s all just bytecode in the end
    Groovy offers a relaxed Java syntax
    Interesting tools included in Groovy
    XmlSlurper, XmlParser, Builders
    Convenient collections
    Private method testing
  • 12. GroovyTestCase
    Included in Groovy distribution
    Extends junit.framework.TestCase
    Provides a number of helper methods for assertions
    Does not require test* methods to be void return type
    No need to declared throws checked exceptions in tests
    Groovy converts checked exceptions to unchecked exceptions
  • 13. Convenience assert methods
    assertArrayEquals(Object[] expected, Object[] actual)
    assertContains(char expected, char[] actualArray)
    assertContains(int expected, int[] actualArray)
    assertInspect(Object value, String expected)
    assertLength(int length, Object[] array)
    assertScript(String script)
    assertToString(Object value, String expected)
  • 14. shouldFail() closures
    shouldFail(Closure closure)
    Asserts supplied closure fails when evaluated
    shouldFail(Class desiredThrownType, Closure closure)
    Asserts supplied closure fails when evaluated and particular exception type is thrown
    shouldFailWithCause(Class desiredCauseType, Closure closure)
    Will check for a checked exception as the root cause (checked exceptions are wrapped in Groovy)
  • 15. Mocking Java classes with Groovy
    Map coercion
    Groovy’s mock library
    GMock library
    Java mocking frameworks
  • 16. Map coercion
    Add named closures to the map
    Only one closure can be mapped to a “method name”
    Cannot overload methods
    Coerce to desire type using the as operator
  • 17. Map coercion example
  • 18. Private Method Calling
    Groovy can call private methods
    Broken encapsulation?
    Better reflection abstractions?
    Java can invoke private methods, it’s just more painful
    Is testing private methods Good or a Smell?
  • 19. Private method testing example
  • 20. Groovy mocking library
    Groovy's built-in mock support does not allow us to test Java classes
    Relies on hooking into Groovy's object lifecycle mechanisms
    Java can not make call to Groovy Mock or Stub
    Use Java mocking frameworks instead
    Can cheat by putting Groovy Mock in a coerced map but why??
  • 21. GMock
    Groovy-based mock objects framework
    Easy syntax and usage
    Works when called by Java classes
  • 22. GMock
    Create Mock
    AddressService service = mock(AddressService)
    Create Expectation
    service.fetch(“id”).returns(new Address()).once()
    Easy Mathcing
    service.save(match{it.personId == “id”}).returns(“id”).once()
  • 23. GMock example
  • 24. Java Mocking Frameworks
    Java Mocking frameworks can be used with Groovy
    Some have minor syntax issues or needed work arounds (JMock)
    Great to use if you already have one you are using and don’t want to switch
  • 25. GSQL
    Easy to create connections
    sql= Sql.newInstance("jdbc:hsqldb:hsql://localhost/", "sa", "", "org.hsqldb.jdbcDriver")
    Simple to work with row sets
    sql.rows(“select * from address”).each {println “id: ${it.id}”}
    No try catch blocks
  • 26. GSQL example
  • 27. Acceptance Test-Driven
    Story tests manifest themselves as executable tests
    Drives the development of complete features
    Frameworks are available
    Fit, FitLibrary, FitNesse
    Robot Framework
  • 28. Cucumber
    Tool for executing plain-text functional descriptions as automated tests
    Supports BDD
    Cucumber tests are typically written before anything else
    verified by business analysts, domain experts, non-technical stakeholders
    The production code is then written to make the Cucumber tests pass
    Outside-in development
  • 29. Cucumber (via cuke4duke)
    Cucumber for the JVM
    Outside-in testing
    Facilitates automation of acceptance/story tests
    Features and scenarios use normal language
    Step definitions can be written in Groovy, as we’ll see
    Uses JRuby to run the core Cucumber framework
  • 30. Cucumber features
    Documentation of the system
    Automated, executable acceptance tests
    What code should I write next?
    Written in Gherkin
    Business readable DSL
    Describe software behavior without detailing implementation
    Grammar exists in different spoken languages (37 currently)
    Feature source files have .feature extension
  • 31. Given-When-Then
    Scenarios consist of steps
    Given: Put the system in a known state before the user starts interacting with the system; pre-conditions
    When: Describe the key action a user performs in this scenario
    Then: Observe outcomes; observations should relate to business value of the feature
    Use And and But to keep features fluent
  • 32. Cucumber step definitions
    Written in Groovy for our examples
    Can be written in many different programming languages
    Analogous to method or function definition
    Start with adjective/adverb
    Regular expression which will match some text from a feature(s)
    Take 0 or more arguments
    Arguments bound to regular expression groups
    Multi-line step arguments
  • 33. Hooks
    Executes before the first step of each scenario
    Executes after the last step of each scenario
    Execute regardless if there are failing, undefined, pending or skipped steps
    Executes after each step in a scenario
  • 34. Hooks
    Found in Groovy files in the support directory
    Our example uses one: env.groovy
    Hooks allow us to run blocks of code at various points in the Cucumber test cycle
    No association between where the hook is defined and which scenario/step it is run for
    All defined hooks (one or more) are run whenever the relevant event occurs
  • 35. Tagged hooks
    Need to execute a certain hook for only certain scenarios
    Achieved by associating a Before, After or AfterStep hook with one or more tags
    See the env.groovy file
    It uses a Before hook with a @database tag to load the database via DBUnit
  • 36. Tagging scenarios
    Allows you to group scenarios for inclusion or exclusion in a Cucumber run
    @wip is provided out of the box
    Using tags in cuke4duke and Maven…
    mvn cuke4duke:cucumber –DcukeArgs=“--tags @wip”
    mvn cuke4duke:cucumber -DcukeArgs=“--tags ~@wip”
    Inside of the Maven POM: <cucumberArg>${cukeArgs}</cucumberArg>
  • 37. Running cuke4duke
    The cuke4duke Maven plugin
    mvn cuke4duke:cucumber
    First time: use –Dcucumber.installGems=true
    Add –o option to work offline
    Features and step definitions are discovered by the plugin
    Features belong in features directory
    Step definitions found in the step_definitions directory
  • 38. cuke4duke acceptance tests
    Step definitions will be written in Groovy
    Other JVM languages are allowed
    Use cuke4duke.GroovyDsl
    Use WebDriver: http://code.google.com/p/selenium
    Test web UI
    Use DbUnit: http://www.dbunit.org/
    Bulk load the database with known fixture data
  • 39. Acceptance testing configuration
  • 40. Cucumber examples
  • 41. Workshop activities
    Now it’s your turn!
    Try your hand at unit testing with Groovy
    Refactor the existing web app
    Introduce DAO for database functionality
    Add services to orchestrate business logic
    Write some Cucumber features and build out or reuse the Groovy step definitions
    Try to add new features and practice outside-in development
    Is ATDD beneficial? Why or why not?
  • 42. Interesting resources
  • 43. Discussion