Acceptance Test Driven Development
 

Acceptance Test Driven Development

on

  • 5,671 views

Test-Driven Development (TDD) and Behaviour-Driven Development (BDD) are powerful techniques, helping developers write better designed, more maintainable and more reliable code, and stay focused on ...

Test-Driven Development (TDD) and Behaviour-Driven Development (BDD) are powerful techniques, helping developers write better designed, more maintainable and more reliable code, and stay focused on the real user requirements. But how does the rest of the team fit in to the picture?

In this talk, we will look at how BDD techniques, and tools such as easyb, FitNesse, and other BDD-related tools can also act as drivers for the overall development process, and also as communication tools, giving testers and end-users clear and unambiguous feedback on what is being developed and where it is at in terms of delivery and schedule.

Statistics

Views

Total Views
5,671
Views on SlideShare
4,887
Embed Views
784

Actions

Likes
9
Downloads
202
Comments
0

10 Embeds 784

http://weblogs.java.net 649
http://blog.jaffamonkey.com 38
http://www.slideshare.net 23
http://darkpower2.blogspot.com 21
http://jaffamonkey.com 17
http://blog.fasoulas.com 11
http://www.java.net 8
https://weblogs.java.net 8
http://jaffamonkey.wordpress.com 7
http://translate.googleusercontent.com 2
More...

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Acceptance Test Driven Development Acceptance Test Driven Development Presentation Transcript

    • 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 User Story 1 - Transfer funds User Story 11- -Calculate my tax rate User Story Calculate my tax rate As a bank client, I want to transfer funds from my current account to my savings account, so As a tax payer, I want to be able to calculate my that I a taxearn more interest able to calculate my As can payer, I want to be tax online, so that I can put enough money aside. tax online, so that I can put enough money aside. So how do we know when this feature is done?
    • Acceptance Tests Acceptance Tests - a key Agile practice User Story 11- ---Acceptance Testsrate User Story 11Calculate my tax User Story Transfer funds User Story Calculate my tax rate - As a bank client,money between two accounts from Client can transfer I want to transfer funds - my current account to my savings account, so Client can’t transfer negative amount - Client can’t transfer wantthan currentto calculate my As a tax payer, I more to be able account balance that I a taxearn more interest able to calculate my As can payer, I want to be - Client can’t transfer from a blocked accountmoney aside. tax online, so that I can put enough tax online, so that I can put enough money aside. So how do we know when this feature is done? Let’s write some Acceptance Criteria
    • 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 Pick a story card Write the acceptance tests Automate the acceptance tests Implement the user story Iteration n-1 Iteration n Iteration n+1
    • 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,...
    • Introducing easyb 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 BDD Acceptance Testing
    • Easyb in Action Easyb supports Specifications and Stories Specifications express requirements as simple statements Stories use the “given-when-then” approach
    • Easyb Specifications Writing Easyb Specifications Simple and informal Easy to write Very similar to acceptance criteria
    • Easyb Specifications Writing Easyb 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 Start off with our acceptance criteria AccountTransfer.specifications 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
    • 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) A developer implements the test in Groovy 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" No longer pending Still pending...
    • Easyb Stories 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 Building an easyb story A story is made up of scenarios Scenarios validate specific behaviour 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 AccountTransfer.story 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"
    • Easyb Stories Anatomy of an easyb story 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' } “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
    • Easyb Stories Implementing the scenario 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"
    • Easyb Stories Implementing the scenario - an alternative solution 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) Using ‘and’ for more clarity } 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', { 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"
    • Easyb assertions Ensuring what should be The shouldBe syntax: Intuitive, readable and flexible account.balance.shouldBe initialAmount Comes in many flavors account.balance.shouldBeEqualTo initialAmount account.balance.shouldNotBe 0 account.balance.shouldBeGreaterThan 0 account.shouldHave(balance:initialAmount)
    • Easyb Stories Implementing another scenario - error conditions 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", { Create a closure transferNegativeAmount = { representing this operation current.transferTo(savings, -50) } } then "an IllegalTransferException should be thrown", { ensureThrows(IllegalTransferException.class) { transferNegativeAmount() Fail if the exception is not } thrown } } 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"
    • 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.
    • Easyb fixtures Refactoring our scenarios - before and before_each before_each "setup the test accounts", { given 'a current a/c with $200', { current = new Account(200) This will be done before } and 'a savings a/c with $300', { each scenario 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() } } }
    • Easyb fixtures Shared behaviour Refactor common code in easyb scenarios shared_behavior "shared behaviors", {   given "a string", {     var = "" Common behavior (‘shared_behavior’)   }   when "the string is hello world", {     var = "hello world"   } } scenario "first scenario", {   it_behaves_as "shared behaviors"     then "the string should start with hello", { Reused here (‘it_behaves_as’)...     var.shouldStartWith "hello"   } } scenario "second scenario", {   it_behaves_as "shared behaviors"     then "the string should end with world", { ...and here     var.shouldEndWith "world"   } }
    • 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", { Set up a JWebUnit 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") Click on a link tester.clickLinkWithText("Sign up now!") } and "I enter a new username and password", { tester.setTextField("username", "jane") Enter some values 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!") } Check the results }
    • Easyb reports The easyb HTML report Test results summary Unimplemented stories Failed stories
    • Easyb reports The easyb HTML report Test results summary Test failure details Unimplemented stories
    • Other Approaches How does easyb compare with other tools? Cucumber, RSpec (Ruby) - very similar to easyb FitNesse - wikis and tables Concordion - marked-up HTML
    • FitNesse 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 Test data and scenarios as a table Test data Expected results
    • FitNesse FitNesse - wiki-based acceptance tests Testers can write/edit the Wiki pages You can also import to and from Excel
    • FitNesse FitNesse - wiki-based acceptance tests public class TransferMoneyBetweenAccounts { Tests are implemented by private BigDecimal savingsBalance; Java classes private BigDecimal currentBalance; private BigDecimal transfer; private BigDecimal finalSavingsBalance; Each column has a private BigDecimal finalCurrentBalance; private boolean exceptionThrown; field in the class public void setSavingsBalance(BigDecimal savingsBalance) {...} public void setCurrentBalance(BigDecimal currentBalance) {...} public void setTransfer(BigDecimal transfer) {...} public BigDecimal finalCurrentBalance() {...} Expected results have public BigDecimal finalSavingsBalance() {...} getters public boolean exceptionThrown() {...} public void execute() { Account currentAccount = new Account(currentBalance); Account savingsAccount = new Account(savingsBalance); exceptionThrown = false; try { currentAccount.transferTo(savingsAccount, transfer); Performing the test finalCurrentBalance = currentAccount.getBalance(); finalSavingsBalance = savingsAccount.getBalance(); } catch (IllegalTransferException e) { exceptionThrown = true; } }
    • Commercial options? 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?
    • Thank You John Ferguson Smart Wakaleo Consulting Ltd. http://www.wakaleo.com Email: john.smart@wakaleo.com Twitter: wakaleo