SlideShare a Scribd company logo
Acceptance Test Driven Development Bringing Testers and Developers Together John Ferguson Smart Wakaleo Consulting Ltd. http://www.wakaleo.com Email: john.smart@wakaleo.com Twitter: wakaleo
Introduction So what’s this talk about, anyway Acceptance tests as a communication tool Acceptance Test Driven Development BDD-style Acceptance Tests - easyb
Acceptance Tests Acceptance Tests - a key Agile practice A communication tool Owned by the customer Determine when a feature is ‘done’ Written together (customer, developer, tester) Focus on  What , not  How
Acceptance Tests Acceptance Tests - how far do you go? In depth tests or examples of system usage? Exhaustive Tests or Sample Stories?
Acceptance Tests Acceptance Tests - a key Agile practice So how do we know when this feature is done? Let’s write some Acceptance Criteria User Story 1 - Calculate my tax rate As a tax payer, I want to be able to calculate my tax online, so that I can put enough money aside. User Story 1 - Calculate my tax rate As a tax payer, I want to be able to calculate my tax online, so that I can put enough money aside. User Story 1 - Transfer funds As a bank client, I want to transfer funds from my current account to my savings account, so that I can earn more interest User Story 1 - Acceptance Tests - Client can transfer money between two accounts - Client can’t transfer negative amount - Client can’t transfer more than current account balance - Client can’t transfer from a blocked account
Acceptance Tests Acceptance Criteria Conditions that must be met before the story is complete Provided by the customer Some folks use a more formal notation How do I get my tests? Just add some examples! User Story 1 - Acceptance Tests - Client can transfer money between two accounts - Client can’t transfer negative amount - Client can’t transfer more than current account balance - Client can’t transfer from a blocked account
Acceptance Test-Driven Development Acceptance Tests drive work during the iteration Iteration n-1 Iteration n Iteration n+1 Pick a story card Write the acceptance tests Automate the acceptance tests Implement the user story
Acceptance Test-Driven Development Implementing/Automating the Acceptance Tests Acceptance Tests become ‘executable’ Focus is still on communication You don’t need to use the same language as the application
Tools for the job What tools exist? Two main approaches Narrative easyb, JBehave, rspec, Cucumber,... Table-based Fitnesse,...
So what is easyb, anyway? A BDD testing framework for Java Make testing clearer and easier to write Make tests self-documenting Help developers focus on the requirements Based on Groovy Java-like syntax Quick to write Full access to Java classes and APIs Well-suited to Acceptance Tests Introducing easyb BDD Acceptance Testing
Easyb supports Specifications and Stories Specifications express requirements as simple statements Stories use the “given-when-then” approach Easyb in Action
Writing Easyb Specifications Simple and informal Easy to write Very similar to acceptance criteria Easyb Specifications
Easyb Specifications Writing Easyb Specifications Start off with our acceptance criteria description  "A client should be able to transfer money between accounts" it  "should let a client transfer money from a current to a savings a/c" it  "should not allow a client to transfer a negative amount" it  "should not allow a client to transfer more than the current balance" it  "should not allow a client to transfer from a blocked account" Express these in Easyb AccountTransfer.specifications User Story 1 - Acceptance Tests - Client can transfer money between two accounts - Client can’t transfer negative amount - Client can’t transfer more than current account balance - Client can’t transfer from a blocked account
Easyb Specifications Writing Easyb Specifications Executable Requirements description  "A client should be able to transfer money between accounts" it  "should let a client transfer money from a current to a savings a/c" it  "should not allow a client to transfer a negative amount" it  "should not allow a client to transfer more than the current balance" it  "should not allow a client to transfer from a blocked account" This code will run! The tests are marked as ‘PENDING’
Easyb Specifications Writing Easyb Specifications HTML Progress reports
Easyb Specifications Writing Easyb Specifications Implementing the tests package  com.wakaleo.accounts.domain description  "A client should be able to transfer money between accounts" it  "should let a client transfer money from a current to a savings a/c" , { current =  new  Account(200) savings =  new  Account(300) current.transferTo(savings, 50) savings.balance.shouldBe 350 current.balance.shouldBe 150  } it  "should not allow a client to transfer a negative amount" it  "should not allow a client to transfer more than the current balance" it  "should not allow a client to transfer from a blocked account" A developer implements the test in Groovy No longer pending Still pending...
Writing Easyb Stories Use a narrative approach Describe a precise requirement Can be understood by a stakeholder Usually made up of a set of scenarios Use an easy-to-understand structure: Given [a context]... When [something happens]... Then [something else happens]... Easyb Stories
Easyb Stories Building an easyb story A story is made up of scenarios Scenarios validate specific behaviour scenario  "A client can transfer money from a current to a savings a/c" scenario  "A client is not allowed to transfer a negative amount" scenario  "A client is not allowed to transfer more than the current balance" scenario  "A client is not allowed to transfer from a blocked account" AccountTransfer.story User Story 1 - Acceptance Tests - Client can transfer money between two accounts - Client can’t transfer negative amount - Client can’t transfer more than current account balance - Client can’t transfer from a blocked account
Easyb Stories Anatomy of an easyb story “Scenario”: corresponds to precise requirement “Given”: the context in which this requirement applies “When”: An event or action “Then”: The expected results of this action scenario  "A client can transfer money from a current to a savings a/c" , { given  'a current a/c with $200 and a savings a/c with $300' when  'you transfer $50 from the current a/c to the savings a/c' then  'the savings a/c should have $350 and the current a/c $150' }
Implementing the scenario Easyb Stories package  com.wakaleo.accounts.domain scenario   "A client can transfer money from a current to a savings a/c" , { given   'a current a/c with $200 and a savings a/c with $300' , { current =  new  Account(200) savings =  new  Account(300) } when   'you transfer $50 from the current a/c to the savings a/c' , { current . transferTo ( savings , 50) } then   'the savings a/c should have $350 and the current a/c $150' , { savings . balance . shouldBe  350 current . balance . shouldBe  150  } } scenario   "A client is not allowed to transfer a negative amount" scenario   "A client is not allowed to transfer more than the current balance" scenario   "A client is not allowed to transfer from a blocked account"
Implementing the scenario - an alternative solution Easyb Stories package  com.wakaleo.accounts.domain scenario   "A client can transfer money from a current to a savings a/c" , { given   'a current a/c with $200' , { current =  new  Account(200) }  and   'a savings a/c with $300' , { savings =  new  Account(300) }  when   'you transfer $50 from the current a/c to the savings a/c' , { current . transferTo ( savings , 50) } then   'the savings a/c should have $350 and the current a/c $150' , { savings . balance . shouldBe  350 }  and   'the current a/c should have $150' , { current . balance . shouldBe  150  } } scenario   "A client is not allowed to transfer a negative amount" scenario   "A client is not allowed to transfer more than the current balance" scenario   "A client is not allowed to transfer from a blocked account" Using ‘and’ for more clarity
Ensuring what should be The shouldBe syntax: Intuitive, readable and flexible Comes in many flavors Easyb assertions account.balance.shouldBe initialAmount account.balance.shouldBeEqualTo initialAmount account.balance.shouldNotBe 0 account.balance.shouldBeGreaterThan 0 account.shouldHave(balance:initialAmount)
Implementing another scenario - error conditions Easyb Stories package  com.wakaleo.accounts.domain scenario  "A client can transfer money from a current to a savings a/c" , { ... } scenario  "A client is not allowed to transfer a negative amount" , { given  'a current a/c with $200' , { current =  new  Account(200) }  and  'a savings a/c with $300' , { savings =  new  Account(300) }  when  "you try to transfer a negative amount" , { transferNegativeAmount = { current.transferTo(savings, -50) } } then  "an IllegalTransferException should be thrown" , { ensureThrows(IllegalTransferException. class ) { transferNegativeAmount() } } } scenario  "A client is not allowed to transfer more than the current balance" scenario  "A client is not allowed to transfer from a blocked account" Create a closure representing this operation Fail if the exception is not thrown
Easyb fixtures Structuring your tests...fixtures in easyb Setting up the test environment... Similar to JUnit fixtures @Before and @BeforeClass before  is run at the start of the whole story before_each  is run before each scenario Useful for setting up databases, test servers, etc.
Refactoring our scenarios - before and before_each Easyb fixtures before_each   "setup the test accounts" , { given   'a current a/c with $200' , { current =  new  Account(200) }  and   'a savings a/c with $300' , { savings =  new  Account(300) }  } scenario   "A client can transfer money from a current to a savings a/c" , { when   'you transfer $50 from the current a/c to the savings a/c' , { current . transferTo ( savings , 50) } then   'the savings a/c should have $350 and the current a/c $150' , { savings . balance . shouldBe  350 }  and   'the current a/c should have $150' , { current . balance . shouldBe  150  } } scenario   "A client is not allowed to transfer a negative amount" , { when   "you try to transfer a negative amount" , { transferNegativeAmount = { current . transferTo ( savings , -50) } } then   "an IllegalTransferException should be thrown" , { ensureThrows (IllegalTransferException. class ) { transferNegativeAmount () } } } This will be done before each scenario
Easyb fixtures Shared behaviour Refactor common code in easyb scenarios shared_behavior  "shared behaviors" ,   {    given  "a string" ,   {      var   =   ""    }    when   "the string is hello world" ,   {      var   =   "hello world"    } } scenario  "first scenario" ,   {    it_behaves_as  "shared behaviors"       then   "the string should start with hello" ,   {      var . shouldStartWith  "hello"    } } scenario  "second scenario" ,   {    it_behaves_as  "shared behaviors"       then   "the string should end with world" ,   {      var . shouldEndWith  "world"    } } Common behavior (‘shared_behavior’) Reused here (‘it_behaves_as’)... ...and here
Web testing with easyb Easyb is convenient for web testing BDD/Functional tests Run against a test server, or use Jetty Use your choice of web testing frameworks Selenium JWebUnit ...
Web testing with easyb Many options - let’s look at two Selenium Runs  in a browser High-level API Runs slower and more work to set up JWebUnit Simulates a browser Runs faster, easy to set up API slightly lower level
Web testing with easyb An example - writing functional tests with JWebUnit import  net.sourceforge.jwebunit.junit.WebTester before_each   "initialize a web test client" , { given   "we have a web test client" , { tester =  new  WebTester() tester.setBaseUrl( "http://localhost:8080/tweeter-web" ) } } scenario   "User signup should add a new user" , { when   "I click on the sign up button on the home page" , { tester.beginAt( "/home" ) tester.clickLinkWithText( "Sign up now!" ) } and   "I enter a new username and password" , { tester.setTextField( "username" ,  "jane" ) tester.setTextField( "password" ,  "tiger" ) tester.submit() } then   "the application should log me on as the new user and show a welcome message" , { tester.assertTextPresent( "Hi jane!" ) } } Set up a JWebUnit client Click on a link Enter some values Check the results
The easyb HTML report Easyb reports Test results summary Failed stories Unimplemented stories
The easyb HTML report Easyb reports Test results summary Test failure details Unimplemented stories
How does easyb compare with other tools? Cucumber, RSpec (Ruby) - very similar to easyb FitNesse - wikis and tables Concordion - marked-up HTML Other Approaches
FitNesse - wiki-based acceptance tests Test data is written at tables on a Wiki Java classes implement the tests behind the scenes FitNesse
FitNesse - wiki-based acceptance tests FitNesse Test data and scenarios as a table Test data Expected results
FitNesse - wiki-based acceptance tests FitNesse Testers can write/edit the Wiki pages You can also import to and from Excel
FitNesse - wiki-based acceptance tests FitNesse public   class  TransferMoneyBetweenAccounts { private  BigDecimal  savingsBalance ; private  BigDecimal  currentBalance ; private  BigDecimal  transfer ; private  BigDecimal  finalSavingsBalance ; private  BigDecimal  finalCurrentBalance ; private   boolean   exceptionThrown ; public   void  setSavingsBalance(BigDecimal savingsBalance) {...} public   void  setCurrentBalance(BigDecimal currentBalance) {...} public   void  setTransfer(BigDecimal transfer) {...} public  BigDecimal finalCurrentBalance() {...}  public  BigDecimal finalSavingsBalance() {...} public   boolean  exceptionThrown() {...} public   void  execute() { Account currentAccount =  new  Account( currentBalance ); Account savingsAccount =  new  Account( savingsBalance ); exceptionThrown  =  false ; try  { currentAccount.transferTo(savingsAccount,  transfer ); finalCurrentBalance  = currentAccount.getBalance(); finalSavingsBalance  = savingsAccount.getBalance(); }  catch  (IllegalTransferException e) { exceptionThrown  =  true ; } } } Tests are implemented by Java classes Each column has a field in the class Expected results have getters Performing the test
There are also some commercial tools out there... GreenPepper Supports tables and BDD-style Nice tool integration (Confluence, Maven,...) Twixt Thoughtworks product, focus on web testing Others? Commercial options?
Thank You John Ferguson Smart Wakaleo Consulting Ltd. http://www.wakaleo.com Email: john.smart@wakaleo.com Twitter: wakaleo

More Related Content

PDF
Acceptance Test Driven Development
PPTX
Droidcon: Al Sutton: Android beyond the phone; Tablets, eReaders, and more- 2...
ODP
Ikenna Okpala: Scala's Lift Web Framework - 03/11/2010
PDF
Livefoldersasfeeds
PDF
Coreyhaines
PDF
Krestan Krab Thorup Erjang Erlang
PPTX
Production Operations An Architect And Developers Perspective (Without Notes)
PDF
Eyes Free Android Julian Harty
Acceptance Test Driven Development
Droidcon: Al Sutton: Android beyond the phone; Tablets, eReaders, and more- 2...
Ikenna Okpala: Scala's Lift Web Framework - 03/11/2010
Livefoldersasfeeds
Coreyhaines
Krestan Krab Thorup Erjang Erlang
Production Operations An Architect And Developers Perspective (Without Notes)
Eyes Free Android Julian Harty

Similar to Acceptance Test Driven Development (20)

PDF
Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...
PDF
Growing software from examples
PDF
Invoicing Gem - Sales & Payments In Your App
PPTX
My Portfolio
PDF
Agile Acceptance Criteria How To
DOCX
Fusion recivables
PPT
Inbound BUSINESS Process Refresher(MP Cricle)
PPTX
Defining tasks for User Stories
PDF
INVEST in good user stories
PDF
Finance-Presentation-CRP1.pdf
PDF
Effective User Stories.pdf
PPTX
eCheck Verification A Step-by-Step Process for Businesses.pptx
PDF
Building a powerful double entry accounting system
PDF
2 ivan pashko - fake it 'til you make it
PPTX
Cash Receipts in SAP ERP
PDF
Zen and the Art of Automated Acceptance Test Suite Maintenance
PPTX
Order to Cash Overview - Training
PDF
Fake it til you make it. Ivan Pashko
PPTX
How Long Does it Take for an eCheck to Clear.pptx
PPTX
Accounting and M.O.M.7i
Beyond Given/When/Then - why diving into Cucumber is the wrong approach to ad...
Growing software from examples
Invoicing Gem - Sales & Payments In Your App
My Portfolio
Agile Acceptance Criteria How To
Fusion recivables
Inbound BUSINESS Process Refresher(MP Cricle)
Defining tasks for User Stories
INVEST in good user stories
Finance-Presentation-CRP1.pdf
Effective User Stories.pdf
eCheck Verification A Step-by-Step Process for Businesses.pptx
Building a powerful double entry accounting system
2 ivan pashko - fake it 'til you make it
Cash Receipts in SAP ERP
Zen and the Art of Automated Acceptance Test Suite Maintenance
Order to Cash Overview - Training
Fake it til you make it. Ivan Pashko
How Long Does it Take for an eCheck to Clear.pptx
Accounting and M.O.M.7i
Ad

More from Skills Matter (20)

PDF
5 things cucumber is bad at by Richard Lawrence
ODP
Patterns for slick database applications
PDF
Scala e xchange 2013 haoyi li on metascala a tiny diy jvm
ODP
Oscar reiken jr on our success at manheim
ODP
Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...
PDF
Cukeup nyc ian dees on elixir, erlang, and cucumberl
PDF
Cukeup nyc peter bell on getting started with cucumber.js
PDF
Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...
ODP
Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...
ODP
Progressive f# tutorials nyc don syme on keynote f# in the open source world
PDF
Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...
PPTX
Dmitry mozorov on code quotations code as-data for f#
PDF
A poet's guide_to_acceptance_testing
PDF
Russ miles-cloudfoundry-deep-dive
KEY
Serendipity-neo4j
PDF
Simon Peyton Jones: Managing parallelism
PDF
Plug 20110217
PDF
Lug presentation
PPT
I went to_a_communications_workshop_and_they_t
PDF
Plug saiku
5 things cucumber is bad at by Richard Lawrence
Patterns for slick database applications
Scala e xchange 2013 haoyi li on metascala a tiny diy jvm
Oscar reiken jr on our success at manheim
Progressive f# tutorials nyc dmitry mozorov & jack pappas on code quotations ...
Cukeup nyc ian dees on elixir, erlang, and cucumberl
Cukeup nyc peter bell on getting started with cucumber.js
Agile testing & bdd e xchange nyc 2013 jeffrey davidson & lav pathak & sam ho...
Progressive f# tutorials nyc rachel reese & phil trelford on try f# from zero...
Progressive f# tutorials nyc don syme on keynote f# in the open source world
Agile testing & bdd e xchange nyc 2013 gojko adzic on bond villain guide to s...
Dmitry mozorov on code quotations code as-data for f#
A poet's guide_to_acceptance_testing
Russ miles-cloudfoundry-deep-dive
Serendipity-neo4j
Simon Peyton Jones: Managing parallelism
Plug 20110217
Lug presentation
I went to_a_communications_workshop_and_they_t
Plug saiku
Ad

Recently uploaded (20)

PDF
NewMind AI Weekly Chronicles - August'25 Week I
PDF
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PDF
Network Security Unit 5.pdf for BCA BBA.
PDF
Unlocking AI with Model Context Protocol (MCP)
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PDF
Approach and Philosophy of On baking technology
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PPT
Teaching material agriculture food technology
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PDF
Electronic commerce courselecture one. Pdf
PDF
Empathic Computing: Creating Shared Understanding
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PDF
Bridging biosciences and deep learning for revolutionary discoveries: a compr...
PPTX
Cloud computing and distributed systems.
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PPTX
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
NewMind AI Weekly Chronicles - August'25 Week I
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...
Per capita expenditure prediction using model stacking based on satellite ima...
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
Network Security Unit 5.pdf for BCA BBA.
Unlocking AI with Model Context Protocol (MCP)
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
20250228 LYD VKU AI Blended-Learning.pptx
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
Approach and Philosophy of On baking technology
Building Integrated photovoltaic BIPV_UPV.pdf
Teaching material agriculture food technology
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
Electronic commerce courselecture one. Pdf
Empathic Computing: Creating Shared Understanding
Advanced methodologies resolving dimensionality complications for autism neur...
Bridging biosciences and deep learning for revolutionary discoveries: a compr...
Cloud computing and distributed systems.
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication

Acceptance Test Driven Development

  • 1. Acceptance Test Driven Development Bringing Testers and Developers Together John Ferguson Smart Wakaleo Consulting Ltd. http://www.wakaleo.com Email: john.smart@wakaleo.com Twitter: wakaleo
  • 2. Introduction So what’s this talk about, anyway Acceptance tests as a communication tool Acceptance Test Driven Development BDD-style Acceptance Tests - easyb
  • 3. Acceptance Tests Acceptance Tests - a key Agile practice A communication tool Owned by the customer Determine when a feature is ‘done’ Written together (customer, developer, tester) Focus on What , not How
  • 4. Acceptance Tests Acceptance Tests - how far do you go? In depth tests or examples of system usage? Exhaustive Tests or Sample Stories?
  • 5. Acceptance Tests Acceptance Tests - a key Agile practice So how do we know when this feature is done? Let’s write some Acceptance Criteria User Story 1 - Calculate my tax rate As a tax payer, I want to be able to calculate my tax online, so that I can put enough money aside. User Story 1 - Calculate my tax rate As a tax payer, I want to be able to calculate my tax online, so that I can put enough money aside. User Story 1 - Transfer funds As a bank client, I want to transfer funds from my current account to my savings account, so that I can earn more interest User Story 1 - Acceptance Tests - Client can transfer money between two accounts - Client can’t transfer negative amount - Client can’t transfer more than current account balance - Client can’t transfer from a blocked account
  • 6. Acceptance Tests Acceptance Criteria Conditions that must be met before the story is complete Provided by the customer Some folks use a more formal notation How do I get my tests? Just add some examples! User Story 1 - Acceptance Tests - Client can transfer money between two accounts - Client can’t transfer negative amount - Client can’t transfer more than current account balance - Client can’t transfer from a blocked account
  • 7. Acceptance Test-Driven Development Acceptance Tests drive work during the iteration Iteration n-1 Iteration n Iteration n+1 Pick a story card Write the acceptance tests Automate the acceptance tests Implement the user story
  • 8. Acceptance Test-Driven Development Implementing/Automating the Acceptance Tests Acceptance Tests become ‘executable’ Focus is still on communication You don’t need to use the same language as the application
  • 9. Tools for the job What tools exist? Two main approaches Narrative easyb, JBehave, rspec, Cucumber,... Table-based Fitnesse,...
  • 10. So what is easyb, anyway? A BDD testing framework for Java Make testing clearer and easier to write Make tests self-documenting Help developers focus on the requirements Based on Groovy Java-like syntax Quick to write Full access to Java classes and APIs Well-suited to Acceptance Tests Introducing easyb BDD Acceptance Testing
  • 11. Easyb supports Specifications and Stories Specifications express requirements as simple statements Stories use the “given-when-then” approach Easyb in Action
  • 12. Writing Easyb Specifications Simple and informal Easy to write Very similar to acceptance criteria Easyb Specifications
  • 13. Easyb Specifications Writing Easyb Specifications Start off with our acceptance criteria description "A client should be able to transfer money between accounts" it "should let a client transfer money from a current to a savings a/c" it "should not allow a client to transfer a negative amount" it "should not allow a client to transfer more than the current balance" it "should not allow a client to transfer from a blocked account" Express these in Easyb AccountTransfer.specifications User Story 1 - Acceptance Tests - Client can transfer money between two accounts - Client can’t transfer negative amount - Client can’t transfer more than current account balance - Client can’t transfer from a blocked account
  • 14. Easyb Specifications Writing Easyb Specifications Executable Requirements description "A client should be able to transfer money between accounts" it "should let a client transfer money from a current to a savings a/c" it "should not allow a client to transfer a negative amount" it "should not allow a client to transfer more than the current balance" it "should not allow a client to transfer from a blocked account" This code will run! The tests are marked as ‘PENDING’
  • 15. Easyb Specifications Writing Easyb Specifications HTML Progress reports
  • 16. Easyb Specifications Writing Easyb Specifications Implementing the tests package com.wakaleo.accounts.domain description "A client should be able to transfer money between accounts" it "should let a client transfer money from a current to a savings a/c" , { current = new Account(200) savings = new Account(300) current.transferTo(savings, 50) savings.balance.shouldBe 350 current.balance.shouldBe 150 } it "should not allow a client to transfer a negative amount" it "should not allow a client to transfer more than the current balance" it "should not allow a client to transfer from a blocked account" A developer implements the test in Groovy No longer pending Still pending...
  • 17. Writing Easyb Stories Use a narrative approach Describe a precise requirement Can be understood by a stakeholder Usually made up of a set of scenarios Use an easy-to-understand structure: Given [a context]... When [something happens]... Then [something else happens]... Easyb Stories
  • 18. Easyb Stories Building an easyb story A story is made up of scenarios Scenarios validate specific behaviour scenario "A client can transfer money from a current to a savings a/c" scenario "A client is not allowed to transfer a negative amount" scenario "A client is not allowed to transfer more than the current balance" scenario "A client is not allowed to transfer from a blocked account" AccountTransfer.story User Story 1 - Acceptance Tests - Client can transfer money between two accounts - Client can’t transfer negative amount - Client can’t transfer more than current account balance - Client can’t transfer from a blocked account
  • 19. Easyb Stories Anatomy of an easyb story “Scenario”: corresponds to precise requirement “Given”: the context in which this requirement applies “When”: An event or action “Then”: The expected results of this action scenario "A client can transfer money from a current to a savings a/c" , { given 'a current a/c with $200 and a savings a/c with $300' when 'you transfer $50 from the current a/c to the savings a/c' then 'the savings a/c should have $350 and the current a/c $150' }
  • 20. Implementing the scenario Easyb Stories package com.wakaleo.accounts.domain scenario "A client can transfer money from a current to a savings a/c" , { given 'a current a/c with $200 and a savings a/c with $300' , { current = new Account(200) savings = new Account(300) } when 'you transfer $50 from the current a/c to the savings a/c' , { current . transferTo ( savings , 50) } then 'the savings a/c should have $350 and the current a/c $150' , { savings . balance . shouldBe 350 current . balance . shouldBe 150 } } scenario "A client is not allowed to transfer a negative amount" scenario "A client is not allowed to transfer more than the current balance" scenario "A client is not allowed to transfer from a blocked account"
  • 21. Implementing the scenario - an alternative solution Easyb Stories package com.wakaleo.accounts.domain scenario "A client can transfer money from a current to a savings a/c" , { given 'a current a/c with $200' , { current = new Account(200) } and 'a savings a/c with $300' , { savings = new Account(300) } when 'you transfer $50 from the current a/c to the savings a/c' , { current . transferTo ( savings , 50) } then 'the savings a/c should have $350 and the current a/c $150' , { savings . balance . shouldBe 350 } and 'the current a/c should have $150' , { current . balance . shouldBe 150 } } scenario "A client is not allowed to transfer a negative amount" scenario "A client is not allowed to transfer more than the current balance" scenario "A client is not allowed to transfer from a blocked account" Using ‘and’ for more clarity
  • 22. Ensuring what should be The shouldBe syntax: Intuitive, readable and flexible Comes in many flavors Easyb assertions account.balance.shouldBe initialAmount account.balance.shouldBeEqualTo initialAmount account.balance.shouldNotBe 0 account.balance.shouldBeGreaterThan 0 account.shouldHave(balance:initialAmount)
  • 23. Implementing another scenario - error conditions Easyb Stories package com.wakaleo.accounts.domain scenario "A client can transfer money from a current to a savings a/c" , { ... } scenario "A client is not allowed to transfer a negative amount" , { given 'a current a/c with $200' , { current = new Account(200) } and 'a savings a/c with $300' , { savings = new Account(300) } when "you try to transfer a negative amount" , { transferNegativeAmount = { current.transferTo(savings, -50) } } then "an IllegalTransferException should be thrown" , { ensureThrows(IllegalTransferException. class ) { transferNegativeAmount() } } } scenario "A client is not allowed to transfer more than the current balance" scenario "A client is not allowed to transfer from a blocked account" Create a closure representing this operation Fail if the exception is not thrown
  • 24. Easyb fixtures Structuring your tests...fixtures in easyb Setting up the test environment... Similar to JUnit fixtures @Before and @BeforeClass before is run at the start of the whole story before_each is run before each scenario Useful for setting up databases, test servers, etc.
  • 25. Refactoring our scenarios - before and before_each Easyb fixtures before_each "setup the test accounts" , { given 'a current a/c with $200' , { current = new Account(200) } and 'a savings a/c with $300' , { savings = new Account(300) } } scenario "A client can transfer money from a current to a savings a/c" , { when 'you transfer $50 from the current a/c to the savings a/c' , { current . transferTo ( savings , 50) } then 'the savings a/c should have $350 and the current a/c $150' , { savings . balance . shouldBe 350 } and 'the current a/c should have $150' , { current . balance . shouldBe 150 } } scenario "A client is not allowed to transfer a negative amount" , { when "you try to transfer a negative amount" , { transferNegativeAmount = { current . transferTo ( savings , -50) } } then "an IllegalTransferException should be thrown" , { ensureThrows (IllegalTransferException. class ) { transferNegativeAmount () } } } This will be done before each scenario
  • 26. Easyb fixtures Shared behaviour Refactor common code in easyb scenarios shared_behavior "shared behaviors" , {   given "a string" , {     var = ""   }   when "the string is hello world" , {     var = "hello world"   } } scenario "first scenario" , {   it_behaves_as "shared behaviors"     then "the string should start with hello" , {     var . shouldStartWith "hello"   } } scenario "second scenario" , {   it_behaves_as "shared behaviors"     then "the string should end with world" , {     var . shouldEndWith "world"   } } Common behavior (‘shared_behavior’) Reused here (‘it_behaves_as’)... ...and here
  • 27. Web testing with easyb Easyb is convenient for web testing BDD/Functional tests Run against a test server, or use Jetty Use your choice of web testing frameworks Selenium JWebUnit ...
  • 28. Web testing with easyb Many options - let’s look at two Selenium Runs in a browser High-level API Runs slower and more work to set up JWebUnit Simulates a browser Runs faster, easy to set up API slightly lower level
  • 29. Web testing with easyb An example - writing functional tests with JWebUnit import net.sourceforge.jwebunit.junit.WebTester before_each "initialize a web test client" , { given "we have a web test client" , { tester = new WebTester() tester.setBaseUrl( "http://localhost:8080/tweeter-web" ) } } scenario "User signup should add a new user" , { when "I click on the sign up button on the home page" , { tester.beginAt( "/home" ) tester.clickLinkWithText( "Sign up now!" ) } and "I enter a new username and password" , { tester.setTextField( "username" , "jane" ) tester.setTextField( "password" , "tiger" ) tester.submit() } then "the application should log me on as the new user and show a welcome message" , { tester.assertTextPresent( "Hi jane!" ) } } Set up a JWebUnit client Click on a link Enter some values Check the results
  • 30. The easyb HTML report Easyb reports Test results summary Failed stories Unimplemented stories
  • 31. The easyb HTML report Easyb reports Test results summary Test failure details Unimplemented stories
  • 32. How does easyb compare with other tools? Cucumber, RSpec (Ruby) - very similar to easyb FitNesse - wikis and tables Concordion - marked-up HTML Other Approaches
  • 33. FitNesse - wiki-based acceptance tests Test data is written at tables on a Wiki Java classes implement the tests behind the scenes FitNesse
  • 34. FitNesse - wiki-based acceptance tests FitNesse Test data and scenarios as a table Test data Expected results
  • 35. FitNesse - wiki-based acceptance tests FitNesse Testers can write/edit the Wiki pages You can also import to and from Excel
  • 36. FitNesse - wiki-based acceptance tests FitNesse public class TransferMoneyBetweenAccounts { private BigDecimal savingsBalance ; private BigDecimal currentBalance ; private BigDecimal transfer ; private BigDecimal finalSavingsBalance ; private BigDecimal finalCurrentBalance ; private boolean exceptionThrown ; public void setSavingsBalance(BigDecimal savingsBalance) {...} public void setCurrentBalance(BigDecimal currentBalance) {...} public void setTransfer(BigDecimal transfer) {...} public BigDecimal finalCurrentBalance() {...} public BigDecimal finalSavingsBalance() {...} public boolean exceptionThrown() {...} public void execute() { Account currentAccount = new Account( currentBalance ); Account savingsAccount = new Account( savingsBalance ); exceptionThrown = false ; try { currentAccount.transferTo(savingsAccount, transfer ); finalCurrentBalance = currentAccount.getBalance(); finalSavingsBalance = savingsAccount.getBalance(); } catch (IllegalTransferException e) { exceptionThrown = true ; } } } Tests are implemented by Java classes Each column has a field in the class Expected results have getters Performing the test
  • 37. There are also some commercial tools out there... GreenPepper Supports tables and BDD-style Nice tool integration (Confluence, Maven,...) Twixt Thoughtworks product, focus on web testing Others? Commercial options?
  • 38. Thank You John Ferguson Smart Wakaleo Consulting Ltd. http://www.wakaleo.com Email: john.smart@wakaleo.com Twitter: wakaleo