Behaviour Driven Development with Cucumber, Groovy and Grails
description
Transcript of Behaviour Driven Development with Cucumber, Groovy and Grails
BEHAVIOUR DRIVEN DEVELOPMENTBEHAVIOUR DRIVEN DEVELOPMENTUSING CUCUMBER JVM AND GROOVYUSING CUCUMBER JVM AND GROOVY
reveal.js - The HTML Presentation Framework http://localhost/cucumber/
1 of 37 10/09/14 21:46
ABOUT MEABOUT ME
MARCO VERMEULENMARCO VERMEULEN
Love Coding!Worked for Shazam, Associated Newspapers, Burberry, VisaCurrent: Equal Experts at HMRCCreator of GVM (Groovy enVironment Manager)Blog: Twitter: @marcoVermeulen
Wired for Code
reveal.js - The HTML Presentation Framework http://localhost/cucumber/
2 of 37 10/09/14 21:46
ABOUT THE TALKABOUT THE TALK
BDD in a NutshellThe Good and Bad of BDDCucumber as solutionMini Cucumber DemoGrails Cucumber PluginSample ApplicationThis talk: http://bit.ly/1uIYrEm
reveal.js - The HTML Presentation Framework http://localhost/cucumber/
3 of 37 10/09/14 21:46
ABOUT THE DEMOABOUT THE DEMO
INVADER ZIMINVADER ZIM
reveal.js - The HTML Presentation Framework http://localhost/cucumber/
4 of 37 10/09/14 21:46
American CartoonCreated by Jhonen VasquezOn Nickelodeon from March, 2001Discontinued, with Cult following!Theme of IMPENDING DOOM!Characters: Zim and GIRAvailable on GitHub
reveal.js - The HTML Presentation Framework http://localhost/cucumber/
5 of 37 10/09/14 21:46
ABOUT THE DEMOABOUT THE DEMO
INVADER ZIMINVADER ZIM
reveal.js - The HTML Presentation Framework http://localhost/cucumber/
6 of 37 10/09/14 21:46
ZIM AND GIRZIM AND GIR
reveal.js - The HTML Presentation Framework http://localhost/cucumber/
7 of 37 10/09/14 21:46
BDD DEFINEDBDD DEFINED
Straight from the horse's mouth:
reveal.js - The HTML Presentation Framework http://localhost/cucumber/
8 of 37 10/09/14 21:46
BDD IN A NUTSHELLBDD IN A NUTSHELL
Using Examples
at multiple levels
to create a shared understanding
and surface uncertainty
to deliver software
that matters!
reveal.js - The HTML Presentation Framework http://localhost/cucumber/
9 of 37 10/09/14 21:46
SO WHAT?SO WHAT?Collaborate on Specifications.Write Gherkin.Execute Specifications.Watch tests go Pending.Write the Step Defs.Watch tests Fail.Write Application Code.Watch tests Pass!
reveal.js - The HTML Presentation Framework http://localhost/cucumber/
10 of 37 10/09/14 21:46
BAD WRAPBAD WRAP
An Orphan
Marketing Hype
ATDD (Acceptance Test Driven Development)
Lost it's Zing!!!
reveal.js - The HTML Presentation Framework http://localhost/cucumber/
11 of 37 10/09/14 21:46
CUCUMBER MISUNDERSTOODCUCUMBER MISUNDERSTOOD
reveal.js - The HTML Presentation Framework http://localhost/cucumber/
12 of 37 10/09/14 21:46
GOOD VIBRATIONSGOOD VIBRATIONS
TDD Evolved
Inspires Collaboration (3 Amigos)
Behaviour vs Implementation
Outside In development
Living Documentation
Abundance of Tools
Simples!
reveal.js - The HTML Presentation Framework http://localhost/cucumber/
13 of 37 10/09/14 21:46
ABUNDANCE OF TOOLSABUNDANCE OF TOOLS
JBehave
Concordian
Fitnesse
EasyB
Spock?
Jasmine (for JavaScript)
Cucumber
reveal.js - The HTML Presentation Framework http://localhost/cucumber/
14 of 37 10/09/14 21:46
CUCUMBER AND GRADLECUCUMBER AND GRADLE
reveal.js - The HTML Presentation Framework http://localhost/cucumber/
15 of 37 10/09/14 21:46
CUCUMBER AND GRADLECUCUMBER AND GRADLE
AN ANATOMYAN ANATOMY
DependenciesJUnit Test RunnerGherkinStep DefinitionsHooksTags
reveal.js - The HTML Presentation Framework http://localhost/cucumber/
16 of 37 10/09/14 21:46
CUCUMBER ANATOMYCUCUMBER ANATOMY
DEPENDENCIESDEPENDENCIES
build.gradle
repositories { jcenter()}
dependencies { compile 'org.codehaus.groovy:groovy:2.3.6' testCompile 'junit:junit:4.11' testCompile 'info.cukes:cucumber-groovy:1.1.8' testCompile 'info.cukes:cucumber-junit:1.1.8'}
reveal.js - The HTML Presentation Framework http://localhost/cucumber/
17 of 37 10/09/14 21:46
CUCUMBER ANATOMYCUCUMBER ANATOMY
TEST RUNNERTEST RUNNER
src/test/groovy/RunCukeTests.groovy
import cucumber.api.CucumberOptionsimport cucumber.api.junit.Cucumberimport org.junit.runner.RunWith
@RunWith(Cucumber)@CucumberOptions( format=["pretty", "html:build/reports/cucumber"], strict=true, features=["features"], glue=["src/test/steps"])public class RunCukesTest { }
reveal.js - The HTML Presentation Framework http://localhost/cucumber/
18 of 37 10/09/14 21:46
CUCUMBER ANATOMYCUCUMBER ANATOMY
GHERKINGHERKIN
src/test/cucumber/adding.feature
Feature: Calculate
Scenario: Add two numbers Given the input "2+2" When the calculator is run Then the output should be "4"
Scenario: Subtract two numbers Given the input "9-4" When the calculator is run Then the output should be "5"
reveal.js - The HTML Presentation Framework http://localhost/cucumber/
19 of 37 10/09/14 21:46
CUCUMBER ANATOMYCUCUMBER ANATOMY
STEP DEFINITIONSSTEP DEFINITIONS
src/test/cucumber/steps/add_steps.groovy
import static cucumber.api.groovy.EN.*
Given(~'^the input "([^"]*)"$') { String input -> //some groovy code}
When(~'^the calculator is run$') { -> //some groovy code}
Then(~'^the output should be "([^"]*)"$') { String output -> //some groovy code}
reveal.js - The HTML Presentation Framework http://localhost/cucumber/
20 of 37 10/09/14 21:46
CUCUMBER ANATOMYCUCUMBER ANATOMY
HOOKSHOOKS
src/test/cucumber/support/env.groovy
Before and After each Scenario
import static cucumber.api.groovy.Hooks.*
Before(){ //some groovy code}
After(){ //some groovy code }
reveal.js - The HTML Presentation Framework http://localhost/cucumber/
21 of 37 10/09/14 21:46
MINI DEMOMINI DEMO
reveal.js - The HTML Presentation Framework http://localhost/cucumber/
22 of 37 10/09/14 21:46
GRAILS CUCUMBER PLUGINGRAILS CUCUMBER PLUGIN
Plugin Portal
https://github.com/hauner/grails-cucumber
by Martin Hauner
reveal.js - The HTML Presentation Framework http://localhost/cucumber/
23 of 37 10/09/14 21:46
GRAILS CUCUMBER PLUGINGRAILS CUCUMBER PLUGIN
FEATURESFEATURES
Convention over ConfigurationEasy ConfigurationNo Test RunnerUses Functional Test phaseHas Friends! (Geb, Spock, Build Test Data, Fixtures)Command Line integrationGood IDE SupportUnder active development
reveal.js - The HTML Presentation Framework http://localhost/cucumber/
24 of 37 10/09/14 21:46
GRAILS CUCUMBER EXAMPLEGRAILS CUCUMBER EXAMPLE
Invader Zim ThemeQuote resource pageWalking skeletonAll moving parts of setup
reveal.js - The HTML Presentation Framework http://localhost/cucumber/
25 of 37 10/09/14 21:46
GRAILS CUCUMBER EXAMPLEGRAILS CUCUMBER EXAMPLE
CONFIGURATIONCONFIGURATION
grails-app/conf/BuildConfig.groovy
dependencies { ... test "org.codehaus.geb:geb-junit4:0.7.2" test "org.seleniumhq.selenium:selenium-chrome-driver:2.32.0" test "org.seleniumhq.selenium:selenium-support:2.32.0" ...}
plugins { ... test ':cucumber:1.0.1' compile ':remote-control:1.5' ...}
reveal.js - The HTML Presentation Framework http://localhost/cucumber/
26 of 37 10/09/14 21:46
GRAILS CUCUMBER EXAMPLEGRAILS CUCUMBER EXAMPLE
CONFIGURATIONCONFIGURATION
grails-app/conf/CucumberConfig.groovy
Replaces Test Runner .
cucumber { tags = ["~@wip"] features = ["test/cucumber"] glue = ["test/steps"] formats = [ "html:target/test-reports/cucumber" ] strict = true}
configuration
reveal.js - The HTML Presentation Framework http://localhost/cucumber/
27 of 37 10/09/14 21:46
GRAILS CUCUMBER EXAMPLEGRAILS CUCUMBER EXAMPLE
GHERKIN FEATUREGHERKIN FEATURE
test/cucumber/quote.feature
Feature: Invader Quotes
Scenario: Invader Zim quotes by Name Given an Invader named "Zim" And the Invader "Zim" says "The Earth is safe! I did it, GIR! Now let's go destroy it!" When a Quote is requested for "Zim" Then we are taken to the Quote Page And we see "The Earth is safe! I did it, GIR! Now let's go destroy it!"
Scenario: Invader GIR quotes by Name Given an Invader named "GIR" And the Invader "GIR" says "Can I be a mongoose dog?" When a Quote is requested for "GIR" Then we are taken to the Quote Page And we see "Can I be a mongoose dog?"
reveal.js - The HTML Presentation Framework http://localhost/cucumber/
28 of 37 10/09/14 21:46
GRAILS CUCUMBER EXAMPLEGRAILS CUCUMBER EXAMPLE
STEP DEFINITIONSSTEP DEFINITIONS
test/cucumber/steps/quote_steps.groovy
Gorm no longer supported!
Use instead!
Use Geb!
Given(~'^an Invader named "([^"]*)"$') { String name -> //persist quote}
When(~'^a Quote is requested for "([^"]*)"$') { String name -> to QuotePage}
Then(~'^we see "([^"]*)"$') { String quote -> def invasionQuote = page.fetchInvasionQuote() assert invasionQuote == quote}
Remote Control Plugin
reveal.js - The HTML Presentation Framework http://localhost/cucumber/
29 of 37 10/09/14 21:46
GRAILS CUCUMBER EXAMPLEGRAILS CUCUMBER EXAMPLE
DOMAIN CLASSDOMAIN CLASS
grails-app/domain/../Quote.groovy
class Quote { String name String message}
reveal.js - The HTML Presentation Framework http://localhost/cucumber/
30 of 37 10/09/14 21:46
GRAILS CUCUMBER EXAMPLEGRAILS CUCUMBER EXAMPLE
GEB PAGEGEB PAGE
test/functional/page/QuotePage.groovy
import geb.Page
class QuotePage extends Page { static url = "/zim-grails/invader" static at = { title == "Invader Zim Quotes" }
static content = { quote { $("#message") } }
def fetchInvasionQuote(){ quote.text() }}
reveal.js - The HTML Presentation Framework http://localhost/cucumber/
31 of 37 10/09/14 21:46
GRAILS CUCUMBER EXAMPLEGRAILS CUCUMBER EXAMPLE
ENVIRONMENT HOOKSENVIRONMENT HOOKS
test/cucumber/support/env.groovy
Use for any long running fixtureHooks run before and after each scenarioLike @BeforeClass and @AfterClass in JUnit
import geb.binding.BindingUpdaterimport geb.Browser
import static cucumber.api.groovy.Hooks.Afterimport static cucumber.api.groovy.Hooks.Before
System.setProperty("geb.build.baseUrl", "http://localhost:8080")
Before () { bindingUpdater = new BindingUpdater (binding, new Browser ()) bindingUpdater.initialize ()}
After () { bindingUpdater.remove ()}
reveal.js - The HTML Presentation Framework http://localhost/cucumber/
32 of 37 10/09/14 21:46
GRAILS CUCUMBER EXAMPLEGRAILS CUCUMBER EXAMPLE
CONTROLLERSCONTROLLERS
CONTROLLERCONTROLLER
URL MAPPINGURL MAPPING
class InvaderController { def index(String id) { [quote: Quote.findByName(id)] }}
"/invader/$name"(controller: "invader")
reveal.js - The HTML Presentation Framework http://localhost/cucumber/
33 of 37 10/09/14 21:46
GRAILS CUCUMBER EXAMPLEGRAILS CUCUMBER EXAMPLE
GSPGSP<%@ page contentType="text/html;charset=UTF-8" %><html><head> <meta name="layout" content="main"/> <title>Invader Zim Quotes</title></head><body> <blockquote class="bq1" id="message"> <p>${quote.message}</p> </blockquote> <p class="after" id="name">--Invader ${quote.name}</p></body></html>
reveal.js - The HTML Presentation Framework http://localhost/cucumber/
34 of 37 10/09/14 21:46
CONCLUSIONCONCLUSIONBDD helps us CollaborateBDD helps us make software that Matters!Cucumber JVM and Gradle play nicelyGrails Cucumber plugin Rocks!BDD is lots of fun!
reveal.js - The HTML Presentation Framework http://localhost/cucumber/
35 of 37 10/09/14 21:46
THANK YOU!!!THANK YOU!!!
reveal.js - The HTML Presentation Framework http://localhost/cucumber/
36 of 37 10/09/14 21:46
Q & AQ & A
reveal.js - The HTML Presentation Framework http://localhost/cucumber/
37 of 37 10/09/14 21:46