Succeeding with Behavior Driven Development (BDD) Testing and Automation Seattle Area Software Quality Assurance Group Oct 18, 2012 Alan Myrvold Google Google Confidential and Proprietary About me Feb 2011 - now Google Test Engineer, Ads 2005 - 2011 Microsoft SDET in Office Security + Outlook 1998 - 2005 Entrust Test manager, development manager, security assurance manager 1988 - 1998 Cognos Tester, developer, test manager, development manager Google Confidential and Proprietary More about me Google Confidential and Proprietary Buzzword bingo ATDD BDD Cucumber Cucumber - JVM Gherkin Jasmine SpecFlow Google Confidential and Proprietary Buzzword bingo ATDD - acceptance test driven development BDD - behavior driven development Cucumber - a Ruby tool that supports BDD Cucumber - JVM - a Java tool that supports BDD Gherkin - the language used by Cucumber Jasmine - a javascript tool for BDD SpecFlow - a .NET tool for BDD Google Confidential and Proprietary Cucumber Example Feature: Addition In order to avoid silly mistakes As a math idiot I want to be told the sum of two numbers Scenario: Add two numbers Given I have entered 50 into the calculator And I have entered 70 into the calculator When I press add Then the result should be 120 on the screen Google Confidential and Proprietary Given / When / Then Given - precondition When - action Then - assertion on expected result And - same action as before Google Confidential and Proprietary Cucumber step implementation @When("I have entered (.*) into the calculator") public void enterNumber(int number) { ... } Google Confidential and Proprietary Scenario Outline Example Scenario Outline: Add two numbers Given I have entered <x> into the calculator And I have entered <y> into the calculator When I press add Then the result should be <z> on the screen Examples: | x | y | 2 | 3 | 0 | -1 | z | 5 | -1 | | | Google Confidential and Proprietary Why BDD? Clarifying requirements by example Demystifying automated tests by using English Demystifying repeated manual tests by emphasizing why and what to verify. Google Confidential and Proprietary Some test types Google Confidential and Proprietary How I used BDD at Microsoft Clarifying requirements in my test plan. Google Confidential and Proprietary How we are using BDD at Google My group, DoubleClick Bid Manager, uses BDD for Java API-level system tests and repeated manual tests. Other groups use BDD tests for Java WebDriver tests. We share the same framework, developed internally. Google Confidential and Proprietary Tools support + Books Tools: o Cucumber - Ruby http://cukes.info o Cucumber JVM https://github.com/cucumber/cucumber-jvm o SpecFlow - Binding business requirements to .NET code http://specflow.org Books o The Cucumber Book o The RSpec Book o Cucumber Recipies (beta, scheduled 3/7/2013) All books from Pragmatic Programmers, http://pragprog.com Google Confidential and Proprietary When / Then elsewhere Mockito … a Java unit testing framework @Mock CalculationEngine engine; Calculator calculator = new Calculator(engine); when(engine.add(2, 2)).thenReturn(4); calculator.parse("2 + 2 ="); assertEquals("4", caclulator.getResult()); Compare the syntax to EasyMock: expect(engine.add(2, 2)).andReturn(4); Google Confidential and Proprietary describe / it Rspec … a Ruby unit testing framework describe Calculator, "#basics" do it "return 4 for 2+2" do calc = Caculator.new calc.add(2, 2) calc.result.should eq(4) end end Jasmine … a Javascript unit testing framework describe("calc", function() { it("2+2 is 4", function() { expect(calc(2, 2).toEqual(4); }); }); Google Confidential and Proprietary Failure mode #1 - Too implementation dependent BAD BETTER Given I have entered 50 into the calculator And I have entered 70 into the calculator When I press add Then the result should be 120 on the screen When I add 50 and 70 Then the result is 120 Google Confidential and Proprietary Failure mode #2 - Programmatic Scripts BAD BETTER When I set x to 1 And while x < 50 And set row x to "empty" Then set the first 50 rows to "empty" Google Confidential and Proprietary Failure mode #3 - Too low level BAD BETTER When I go to the login page And enter "bob" into the username field And enter "pass123" into the password field And click login Then I am logged in as "bob" When I log in as "bob" Google Confidential and Proprietary Failure mode #4 - Not exploring interesting cases BAD BETTER When I add 50 and 70 Then the result is 120 When I add 50 and 70 Then the result is 120 When I add 1e90, 0.1, and -1e90 Then the result is 0.1 Google Confidential and Proprietary Failure mode #5 - Not using regex BAD BETTER @When("Set the budget to 100") public void setBudget() { ... } @When("Set the budget to (.*)") public void setBudget(int amount) { ... } Google Confidential and Proprietary Failure mode #6 - Complex parsing logic BAD BETTER @When("(.*) the (.*) to (.*)") public void doAction(String action, String name, String value) { if (action.equals("set") && name.equals("budget") } @When("Set the budget to (.*)") public void setBudget(int amount) { ... } Google Confidential and Proprietary Failure mode #7 - Leaking code details BAD BETTER When I click the BTNREFRESH-ALL button When I refresh all Google Confidential and Proprietary Failure mode #8 - Bad test architecture BAD BETTER Calling entry points in code that are fragile, or disappear Using supported public or test API's Google Confidential and Proprietary Success tips from me Use BDD for a small set of tests Focus on human readability, as a domain expert using the feature would describe a test Google Confidential and Proprietary Success tips from The Cucumber Book, by Matt Wayne and Aslak Hellesoy DAMP beats DRY DAMP: Descriptive and meaningful phrases DRY: Don’t repeat yourself Declarative better than imperative Declarative: Given I am logged in Imperative: Log in as user “Bob” Google Confidential and Proprietary Questions? http://testapprentice.com amyrvold@google.com Google Confidential and Proprietary