Aslak Hellesøy - Chief Scientist
twitter.com/aslak_hellesoy
aslak.hellesoy@gmail.com
A Cuke for Duke
http://github.com/asl...
http://cukes.info/
http://www.flickr.com/photos/twose/887903401/
http://www.flickr.com/photos/twose/887903401/
55000 downloads
http://www.flickr.com/photos/twose/887903401/
1350 followers
55000 downloads
http://www.flickr.com/photos/twose/887903401/
125 contributors
1350 followers
55000 downloads
http://www.flickr.com/photos/twose/887903401/
125 contributors
1350 followers
55000 downloads
56 wiki pages
http://www.flickr.com/photos/twose/887903401/
125 contributors
1350 followers
55000 downloads
40 tools
56 wiki pages
http://www.flickr.com/photos/twose/887903401/
125 contributors
1350 followers
55000 downloads
40 tools
8 screencasts
56 wiki pages
http://www.flickr.com/photos/twose/887...
125 contributors
1350 followers
55000 downloads
40 tools
8 screencasts
56 wiki pages
1 book
http://www.flickr.com/photos/tw...
Outside-In
features
src
submit_guess.feature
test/java/codebreaker
GameSteps.java
Feature: code-breaker submits guess
In order to make time pass when I'm alone
As a player
I want to play the against a mac...
Given
When
Then
Given
When
Then
GameSteps.java
package codebreaker;
import cuke4duke.*;
public class GameSteps {
}
features
src
submit_guess.feature
test/java/codebreaker
GameSteps.java
$ gem install cucumber
$ cucumber features
<repositories>
<repository>
<id>cukes</id>
<url>http://cukes.info/maven</url>
</repository>
</repositories>
<pluginReposit...
<dependencies>
<dependency>
<groupId>cuke4duke</groupId>
<artifactId>cuke4duke</artifactId>
<version>0.1.4</version>
</dep...
<plugin>
<groupId>cuke4duke</groupId>
<artifactId>cuke4duke-maven-plugin</artifactId>
<configuration>
<jvmArgs>
<jvmArg>
-...
features
src
submit_guess.feature
test/java/codebreaker
GameSteps.java
$ mvn integration-test 
-Dcucumber.installGems=true...
Feature: code-breaker submits guess
In order to make time pass when I'm alone
As a player
I want to play the against a mac...
You can implement step definitions for undefined steps with these
snippets:
@Given("^the secret code is "([^"]*)"$")
@Pend...
GameSteps.java
package codebreaker;
import cuke4duke.*;
public class CodeBreakerSteps {
@Given("^the secret code is "([^"]...
Feature: code-breaker submits guess
In order to make time pass when I'm alone
As a player
I want to play the against a mac...
Given the secret code is "r g y c"
# public void codebreaker.GameSteps
.theSecretCodeIs(java.lang.String)
Location
public class GameSteps {
private Game game;
@Given("^the secret code is "([^"]*)"$")
public void theSecretCodeIs(String co...
Compilation failure
src/test/java/codebreaker/
CodeBreakerSteps.java:[6,12] cannot find symbol
symbol : class Game
locatio...
features
src
submit_guess.feature
main/java/codebreaker
Game.java
test/java/codebreaker
GameSteps.java
Game.java
package codebreaker;
public class Game {
public Game(String code) {
}
}
Feature: code-breaker submits guess
In order to make time pass when I'm alone
As a player
I want to play the against a mac...
Steps & Step Definitions
Given the secret code is "r g y c"
@Given("^the secret code is "([^"]*)"$")
public void theSecretC...
Steps & Step Definitions
Given the secret code is "r g y c"
@Given("^the secret code is "([^"]*)"$")
public void theSecretC...
Feature: code-breaker submits guess
In order to make time pass when I'm alone
As a player
I want to play the against a mac...
Scenario: all correct
Given the secret code is "r g y c"
When I guess "r g y c"
Then the mark should be "bbbb"
Scenario: 2...
Scenario: all correct # features/c..s.feature:6
Given the secret code is "r g y c" # public void theS..(..)
When I guess "...
Time to write the
algorithm...
Scenario: all correct
Given the secret code is "r g y c"
When I guess "r g y c"
Then the mark should be "bbbb"
Scenario: 2...
Scenario Outline: submit guess
Given the secret code is "<code>"
When I guess "<guess>"
Then the mark should be "<mark>"
E...
Gherkin
OH HAI: STUFFING
MISHUN: CUCUMBR
I CAN HAZ IN TEH BEGINNIN "3" CUCUMBRZ
WEN I EAT "2" CUCUMBRZ
DEN I HAZ "2" CUCUMBERZ IN ...
Multiline args (String)
Then aslak.hellesoy@gmail.com should get email
"""
Hi aslak.hellesoy@gmail.com
Congratulations, Cu...
Multiline args (Tables)
Given the following proposals
| email | title |
| aslak.hellesoy@gmail.com | Cucumber |
| bryan@br...
Hooks
@Before
@After
Feature: Notification emails
Background:
Given the following proposals
| email | title |
| aslak.hellesoy@gmail.com | Cucu...
Tagged Hooks
@Before("@im_special,@me_too")
@me_too
Feature: Lorem
Scenario: Ipsum
Scenario: Dolor
Feature: Sit
@im_specia...
Feature: Take over the world
I want it all
@spanish @french @english
Scenario: Take over Europe
@spanish @english
Scenario...
Feature: Take over the world
I want it all
@spanish @french @english
Scenario: Take over Europe
@spanish @english
Scenario...
Feature: Take over the world
I want it all
@spanish @french @english
Scenario: Take over Europe
@spanish @english
Scenario...
Feature: Take over the world
I want it all
@spanish @french @english
Scenario: Take over Europe
@spanish @english
Scenario...
Formatters
Pretty
Progress
Profile
HTML
JUnit
Rerun
Your Own
Then /^I should have "(d+)" cukes my belly$/ do |cukes|
end
Ruby
Groovy
Then "^I should have "(d+)" cukes my belly$" { int...
Cuke4Duke JavaZone 2009
Cuke4Duke JavaZone 2009
Cuke4Duke JavaZone 2009
Cuke4Duke JavaZone 2009
Cuke4Duke JavaZone 2009
Cuke4Duke JavaZone 2009
Cuke4Duke JavaZone 2009
Upcoming SlideShare
Loading in …5
×

Cuke4Duke JavaZone 2009

5,097 views

Published on

Aslak Hellesøy presents Cuke4Duke (Cucumber on the JVM) at JavaZone 2009.

5 Comments
9 Likes
Statistics
Notes
No Downloads
Views
Total views
5,097
On SlideShare
0
From Embeds
0
Number of Embeds
39
Actions
Shares
0
Downloads
100
Comments
5
Likes
9
Embeds 0
No embeds

No notes for slide

Cuke4Duke JavaZone 2009

  1. 1. Aslak Hellesøy - Chief Scientist twitter.com/aslak_hellesoy aslak.hellesoy@gmail.com A Cuke for Duke http://github.com/aslakhellesoy/cuke4duke
  2. 2. http://cukes.info/
  3. 3. http://www.flickr.com/photos/twose/887903401/
  4. 4. http://www.flickr.com/photos/twose/887903401/
  5. 5. 55000 downloads http://www.flickr.com/photos/twose/887903401/
  6. 6. 1350 followers 55000 downloads http://www.flickr.com/photos/twose/887903401/
  7. 7. 125 contributors 1350 followers 55000 downloads http://www.flickr.com/photos/twose/887903401/
  8. 8. 125 contributors 1350 followers 55000 downloads 56 wiki pages http://www.flickr.com/photos/twose/887903401/
  9. 9. 125 contributors 1350 followers 55000 downloads 40 tools 56 wiki pages http://www.flickr.com/photos/twose/887903401/
  10. 10. 125 contributors 1350 followers 55000 downloads 40 tools 8 screencasts 56 wiki pages http://www.flickr.com/photos/twose/887903401/
  11. 11. 125 contributors 1350 followers 55000 downloads 40 tools 8 screencasts 56 wiki pages 1 book http://www.flickr.com/photos/twose/887903401/
  12. 12. Outside-In
  13. 13. features src submit_guess.feature test/java/codebreaker GameSteps.java
  14. 14. Feature: code-breaker submits guess In order to make time pass when I'm alone As a player I want to play the against a machine Scenario: all correct Given the secret code is "r g y c" When I guess "r g y c" Then the mark should be "bbbb" submit_guess.feature
  15. 15. Given When Then
  16. 16. Given When Then
  17. 17. GameSteps.java package codebreaker; import cuke4duke.*; public class GameSteps { }
  18. 18. features src submit_guess.feature test/java/codebreaker GameSteps.java $ gem install cucumber $ cucumber features
  19. 19. <repositories> <repository> <id>cukes</id> <url>http://cukes.info/maven</url> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>cukes</id> <url>http://cukes.info/maven</url> </pluginRepository> </pluginRepositories>
  20. 20. <dependencies> <dependency> <groupId>cuke4duke</groupId> <artifactId>cuke4duke</artifactId> <version>0.1.4</version> </dependency> <dependency> <groupId>org.picocontainer</groupId> <artifactId>picocontainer</artifactId> <version>2.8.3</version> </dependency> </dependencies>
  21. 21. <plugin> <groupId>cuke4duke</groupId> <artifactId>cuke4duke-maven-plugin</artifactId> <configuration> <jvmArgs> <jvmArg> -Dcuke4duke.objectFactory= cuke4duke.internal.java.PicoFactory </jvmArg> </jvmArgs> <cucumberArgs> <cucumberArg>${basedir}/src/test/java</cucumberArg> </cucumberArgs> <gems> <gem>cucumber:0.3.100</gem> </gems> </configuration> </plugin>
  22. 22. features src submit_guess.feature test/java/codebreaker GameSteps.java $ mvn integration-test -Dcucumber.installGems=true pom.xml
  23. 23. Feature: code-breaker submits guess In order to make time pass when I'm alone As a player I want to play the against a machine Scenario: all correct # features/c..s.feature:6 Given the secret code is "r g y c" # features/c..s.feature:7 When I guess "r g y c" # features/c..s.feature:8 Then the mark should be "bbbb" # features/c..s.feature:9 1 scenario (1 undefined) 3 steps (3 undefined) 0m0.076s Undefined Steps
  24. 24. You can implement step definitions for undefined steps with these snippets: @Given("^the secret code is "([^"]*)"$") @Pending public void theSecretCodeIsRGYC_(String arg1) { } @When("^I guess "([^"]*)"$") @Pending public void iGuessRGYC_(String arg1) { } @Then("^the mark should be "([^"]*)"$") @Pending public void theMarkShouldBeBbbb_(String arg1) { } Snippets
  25. 25. GameSteps.java package codebreaker; import cuke4duke.*; public class CodeBreakerSteps { @Given("^the secret code is "([^"]*)"$") @Pending public void theSecretCodeIs(String code) { } @When("^I guess "([^"]*)"$") @Pending public void iGuess(String guess) { } @Then("^the mark should be "([^"]*)"$") @Pending public void theMarkShouldBe(String mark) { } }
  26. 26. Feature: code-breaker submits guess In order to make time pass when I'm alone As a player I want to play the against a machine Scenario: all correct # features/c..s.feature:6 Given the secret code is "r g y c" # public void theS..(..) TODO (Cucumber::Pending) f../c..s.feature:7:in `Given the secret code is "r g y c"' When I guess "r g y c" # public void iGue..(..) Then the mark should be "bbbb" # public void theM..(..) 1 scenario (1 pending) 3 steps (2 skipped, 1 pending) 0m0.079s $ mvn integration-test
  27. 27. Given the secret code is "r g y c" # public void codebreaker.GameSteps .theSecretCodeIs(java.lang.String) Location
  28. 28. public class GameSteps { private Game game; @Given("^the secret code is "([^"]*)"$") public void theSecretCodeIs(String code) { game = new Game(code); } } Implement Intention
  29. 29. Compilation failure src/test/java/codebreaker/ CodeBreakerSteps.java:[6,12] cannot find symbol symbol : class Game location: class codebreaker.CodeBreakerSteps
  30. 30. features src submit_guess.feature main/java/codebreaker Game.java test/java/codebreaker GameSteps.java
  31. 31. Game.java package codebreaker; public class Game { public Game(String code) { } }
  32. 32. Feature: code-breaker submits guess In order to make time pass when I'm alone As a player I want to play the against a machine Scenario: all correct # features/c..s.feature:6 Given the secret code is "r g y c" # public void theS..(..) When I guess "r g y c" # public void iGue..(..) TODO (Cucumber::Pending) f../c..s.feature:8:in `When I guess "r g y c"' Then the mark should be "bbbb" # public void theM..(..) 1 scenario (1 pending) 3 steps (1 skipped, 1 pending, 1 passed) 0m0.112s $ mvn integration-test
  33. 33. Steps & Step Definitions Given the secret code is "r g y c" @Given("^the secret code is "([^"]*)"$") public void theSecretCodeIs(String code) { game = new Game(code); } Step == Method invocation
  34. 34. Steps & Step Definitions Given the secret code is "r g y c" @Given("^the secret code is "([^"]*)"$") public void theSecretCodeIs(String code) { game = new Game(code); }
  35. 35. Feature: code-breaker submits guess In order to make time pass when I'm alone As a player I want to play the against a machine Scenario: all correct # features/c..s.feature:6 Given the secret code is "r g y c" # public void theS..(..) When I guess "r g y c" # public void iGue..(..) Then the mark should be "bbbb" # public void theM..(..) 1 scenario (1 passed) 3 steps (3 passed) 0m0.121s $ mvn integration-test
  36. 36. Scenario: all correct Given the secret code is "r g y c" When I guess "r g y c" Then the mark should be "bbbb" Scenario: 2 wrong pos, 2 correct Given the secret code is "r g y c" When I guess "r g c y" Then the mark should be "bbww" More Scenarios
  37. 37. Scenario: all correct # features/c..s.feature:6 Given the secret code is "r g y c" # public void theS..(..) When I guess "r g y c" # public void iGue..(..) Then the mark should be "bbbb" # public void theM..(..) Scenario: all correct # features/c..s.feature:6 Given the secret code is "r g y c" # public void theS..(..) When I guess "r g y c" # public void iGue..(..) Then the mark should be "bbbb" # public void theM..(..) org.junit.ComparisonFailure: expected:<bb[bb]> but was:<bb[ww]> (NativeException) codebreaker/CodeBreakerSteps.java:20:in `theMarkShouldBe' features/codebreaker_submits_guess.feature:14:in `Then the mark should be "bbww"' 1 scenario (1 failed, 1 passed) 3 steps (1 failed, 3 passed) 0m0.121s
  38. 38. Time to write the algorithm...
  39. 39. Scenario: all correct Given the secret code is "r g y c" When I guess "r g y c" Then the mark should be "bbbb" Scenario: 2 wrong pos, 2 correct Given the secret code is "r g y c" When I guess "r g c y" Then the mark should be "bbww" DRY?
  40. 40. Scenario Outline: submit guess Given the secret code is "<code>" When I guess "<guess>" Then the mark should be "<mark>" Examples: | code | guess | mark | | r g y c | r g y c | bbbb | | r g y c | r g c y | bbww | | r g y c | y r g c | bwww | | r g y c | c r g y | wwww | Scenario Outline
  41. 41. Gherkin
  42. 42. OH HAI: STUFFING MISHUN: CUCUMBR I CAN HAZ IN TEH BEGINNIN "3" CUCUMBRZ WEN I EAT "2" CUCUMBRZ DEN I HAZ "2" CUCUMBERZ IN MAH BELLY AN IN TEH END "1" CUCUMBRZ KTHXBAI!
  43. 43. Multiline args (String) Then aslak.hellesoy@gmail.com should get email """ Hi aslak.hellesoy@gmail.com Congratulations, Cucumberer was accepted. See you at JavaZone! """ @Then("^(.*) should get email$") public void email(String email, String body) { }
  44. 44. Multiline args (Tables) Given the following proposals | email | title | | aslak.hellesoy@gmail.com | Cucumber | | bryan@brynary.com | Webrat | @Given("^the following proposals$") public void proposals(cuke4duke.Table proposals) { }
  45. 45. Hooks @Before @After
  46. 46. Feature: Notification emails Background: Given the following proposals | email | title | | aslak.hellesoy@gmail.com | Cucumber | | bryan@brynary.com | Webrat | Scenario: Approve all Scenario: Reject Webrat Background
  47. 47. Tagged Hooks @Before("@im_special,@me_too") @me_too Feature: Lorem Scenario: Ipsum Scenario: Dolor Feature: Sit @im_special Scenario: Amet Scenario: Consec
  48. 48. Feature: Take over the world I want it all @spanish @french @english Scenario: Take over Europe @spanish @english Scenario: Take over America @english Scenario: Take over Australia Tagged Execution
  49. 49. Feature: Take over the world I want it all @spanish @french @english Scenario: Take over Europe @spanish @english Scenario: Take over America @english Scenario: Take over Australia cucumber -t spanish doit.feature Tagged Execution
  50. 50. Feature: Take over the world I want it all @spanish @french @english Scenario: Take over Europe @spanish @english Scenario: Take over America @english Scenario: Take over Australia Tagged Execution
  51. 51. Feature: Take over the world I want it all @spanish @french @english Scenario: Take over Europe @spanish @english Scenario: Take over America @english Scenario: Take over Australia cucumber -t ~french doit.feature Tagged Execution
  52. 52. Formatters Pretty Progress Profile HTML JUnit Rerun Your Own
  53. 53. Then /^I should have "(d+)" cukes my belly$/ do |cukes| end Ruby Groovy Then "^I should have "(d+)" cukes my belly$" { int cukes -> } Scala (coming soon) Then("^I should have "(d+)" cukes my belly$") { cukes:int => } Python, C#, F# (coming later - wire protocol) Flex (via FunFX) - alive and kicking!

×