SlideShare a Scribd company logo
1 of 100
Download to read offline
Make Everyone a Tester
   Natural Language Acceptance Testing
PM
      Design
               UX

Dev
QA



QA
why test?
ensure quality
communicate
goals

• developer & PM pairing
• tests written first
• drive a web browser
start with a story
Users can register for an account

Requires the following information:

*   Email
*   Password
*   Password Confirmation
*   Acceptance of terms / conditions

Acceptance Criteria

* Try with a duplicate email address
* Try with a password less than 6 characters
image: papazimouris @ flickr
discuss
Users can register for an account

Requires the following information:

*   Email
*   Password
*   Password Confirmation
*   Acceptance of terms / conditions

Acceptance Criteria

* Try with a duplicate email address
* Try with a password less than 6 characters
discuss
Users can register for an account

Requires the following information:

*   Email                       form with data fields
*   Password
*   Password Confirmation
*   Acceptance of terms / conditions

Acceptance Criteria

* Try with a duplicate email address
* Try with a password less than 6 characters
discuss                  success state

Users can register for an account

Requires the following information:

*   Email                       form with data fields
*   Password
*   Password Confirmation
*   Acceptance of terms / conditions

Acceptance Criteria

* Try with a duplicate email address
* Try with a password less than 6 characters
discuss                  success state

Users can register for an account

Requires the following information:

*   Email                       form with data fields
*   Password
*   Password Confirmation
*   Acceptance of terms / conditions

Acceptance Criteria                     error states

* Try with a duplicate email address
* Try with a password less than 6 characters
define behavior

• locations
• page state
• message content
State:

    * No users exist in the system

    Steps:

    1. Visit the registration page
    2. Enter valid registration information
    3. Submit the form

    Expectation:

    * I should be redirected to the home page
    * I should see a success message displayed




where am I starting from?
State:

 * No users exist in the system

 Steps:

 1. Visit the registration page
 2. Enter valid registration information
 3. Submit the form

 Expectation:

 * I should be redirected to the home page
 * I should see a success message displayed




what are the inputs?
State:

  * No users exist in the system

  Steps:

  1. Visit the registration page
  2. Enter valid registration information
  3. Submit the form

  Expectation:

  * I should be redirected to the home page
  * I should see a success message displayed




what is the behavior?
manual
problems

• time consuming
• prone to error
• no regressions
automate!
done.
but...
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-
strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head profile="http://selenium-ide.openqa.org/profiles/test-case">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="selenium.base" href="http://spasibo.com/" />
<title>spasibo-test</title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="3">spasibo-test</td></tr>
</thead><tbody>
<tr>
  <td>open</td>
  <td>/</td>
  <td></td>
</tr>
<tr>
  <td>clickAndWait</td>
  <td>link=Register</td>
  <td></td>
</tr>
<tr>
  <td>type</td>
  <td>user_email</td>
  <td>user@host.com</td>
</tr>
<tr>
  <td>type</td>
  <td>user_password</td>
  <td>password</td>
</tr>
problems

• not maintainable
• not reusable
• not understandable
Selenium
Remote Control
write automated web
 application tests in a familiar
language and have them run in
          the browser
$ java -jar selenium-server.jar
12:51:31.262 INFO - Java: Apple Inc. 1.5.0_16-133
12:51:31.263 INFO - OS: Mac OS X 10.5.6 i386
12:51:31.270 INFO - v1.0-beta-2 [2571], with Core v1.0-beta-2 [2330]
12:51:31.394 INFO - Version Jetty/5.1.x
12:51:31.395 INFO - Started HttpContext[/,/]
12:51:31.396 INFO - Started HttpContext[/selenium-server,/selenium-server]
12:51:31.397 INFO - Started HttpContext[/selenium-server/driver,/selenium-server/driver]
12:51:31.408 INFO - Started SocketListener on 0.0.0.0:4444
12:51:31.408 INFO - Started org.mortbay.jetty.Server@bc887b
class NewTest < Test::Unit::TestCase

 ...

  def test_new
    @selenium.open "/"
    @selenium.click "link=Register"
    @selenium.wait_for_page_to_load "30000"
    @selenium.type "user_email", "user@host.com"
    @selenium.type "user_password", "password"
    @selenium.type "user_password_confirmation", "password"
    @selenium.click "user_terms"
    @selenium.click "user_submit"
    @selenium.wait_for_page_to_load "30000"
    @selenium.wait_for_page_to_load "5000"
    begin
        assert @selenium.is_text_present("Welcome to Spasibo. A winner is you!")
    rescue Test::Unit::AssertionFailedError
        @verification_errors << $!
    end
    begin
        assert_equal "http://spasibo.com/", @selenium.get_location
    rescue Test::Unit::AssertionFailedError
        @verification_errors << $!
    end
  end
end
$ gem install Selenium
export the test
require "selenium"
require "test/unit"
require "open-uri"

class NewTest < Test::Unit::TestCase
  def setup
    base_url = "http://spasibo.com/"
    open("#{base_url}setup/clean_slate")

    @verification_errors = []
    if $selenium
      @selenium = $selenium
    else
      @selenium = Selenium::SeleniumDriver.new("localhost", 4444, "*chrome", base_url, 10000);
      @selenium.start
    end
    @selenium.set_context("test_new")
  end

  def teardown
    @selenium.stop unless $selenium
    assert_equal [], @verification_errors
  end

  def test_new
    @selenium.open "/"
    @selenium.click "link=Register"
    @selenium.wait_for_page_to_load "30000"
    @selenium.type "user_email", "user@host.com"
    @selenium.type "user_password", "password"
    @selenium.type "user_password_confirmation", "password"
    @selenium.click "user_terms"
    @selenium.click "user_submit"
    @selenium.wait_for_page_to_load "30000"
    @selenium.wait_for_page_to_load "5000"
    begin
        assert @selenium.is_text_present("Welcome to Spasibo. A winner is you!")
    rescue Test::Unit::AssertionFailedError
        @verification_errors << $!
    end
    begin
        assert_equal "http://spasibo.com/", @selenium.get_location
    rescue Test::Unit::AssertionFailedError
        @verification_errors << $!
    end
  end
end
def setup                                              port           start URL
  ...

  @selenium = Selenium::SeleniumDriver.new("localhost", 4444, "*chrome", base_url, 10000);
  @selenium.start

  ...
                                            host              browser           timeout
end




                                     setup
def setup
  base_url = "http://spasibo.com/"
  open("#{base_url}setup/clean_slate")

  ...

end




 no users exist in the system
don’t do this in production




def setup
  base_url = "http://spasibo.com/"
  open("#{base_url}setup/clean_slate")

  ...

end




 no users exist in the system
def test_new
  @selenium.open "/"
  @selenium.click "link=Register"
  @selenium.wait_for_page_to_load "30000"
  @selenium.type "user_email", "user@host.com"
  @selenium.type "user_password", "password"
  @selenium.type "user_password_confirmation", "password"
  @selenium.click "user_terms"
  @selenium.click "user_submit"
  @selenium.wait_for_page_to_load "30000"
  @selenium.wait_for_page_to_load "5000"

  ...

end




1. visit the registration page
def test_new
  @selenium.open "/"
  @selenium.click "link=Register"
  @selenium.wait_for_page_to_load "30000"
  @selenium.type "user_email", "user@host.com"
  @selenium.type "user_password", "password"
  @selenium.type "user_password_confirmation", "password"
  @selenium.click "user_terms"
  @selenium.click "user_submit"
  @selenium.wait_for_page_to_load "30000"
  @selenium.wait_for_page_to_load "5000"

  ...

end




      2. enter valid information
def test_new
  @selenium.open "/"
  @selenium.click "link=Register"
  @selenium.wait_for_page_to_load "30000"
  @selenium.type "user_email", "user@host.com"
  @selenium.type "user_password", "password"
  @selenium.type "user_password_confirmation", "password"
  @selenium.click "user_terms"
  @selenium.click "user_submit"
  @selenium.wait_for_page_to_load "30000"
  @selenium.wait_for_page_to_load "5000"

  ...

end




              3. submit the form
def test_new

 ...

  begin
      assert @selenium.is_text_present("Welcome to Spasibo. A winner is you!")
  rescue Test::Unit::AssertionFailedError
      @verification_errors << $!
  end
  begin
      assert_equal "http://spasibo.com/", @selenium.get_location
  rescue Test::Unit::AssertionFailedError
      @verification_errors << $!
  end
end




  success message displayed
def test_new

  ...

  begin
      assert @selenium.is_text_present("Welcome to Spasibo. A winner is you!")
  rescue Test::Unit::AssertionFailedError
      @verification_errors << $!
  end
  begin
      assert_equal "http://spasibo.com/", @selenium.get_location
  rescue Test::Unit::AssertionFailedError
      @verification_errors << $!
  end
end




               user is redirected
$ ruby -rubygems spasibo_test.rb
Loaded suite spasibo_test
Started
.
Finished in 10.559078 seconds.

1 tests, 3 assertions, 0
failures, 0 errors
problems


• dependent on a developer
• still not understandable
State:

* No users exist in the system

Steps:

1. Visit the registration page
2. Enter valid registration information
3. Submit the form

Expectation:

* I should be redirected to the home page
* I should see a success message displayed
can I make that
  executable?
Behavior-Driven Development
 tool that speaks to domain
experts first and code second
$ gem install cucumber
tweak the language
State:

* No users exist in the system

Steps:

1. Visit the registration page
2. Enter valid registration information
3. Submit the form

Expectation:

* I should be redirected to the home page
* I should see a success message displayed
State:

* Given no users exist in the system

Steps:

1. Visit the registration page
2. Enter valid registration information
3. Submit the form

Expectation:

* I should be redirected to the home page
* I should see a success message displayed
State:

* Given no users exist in the system

Steps:

1. When I visit the registration page
2. And I enter valid registration information
3. And I submit the form

Expectation:

* I should be redirected to the home page
* I should see a success message displayed
State:

* Given no users exist in the system

Steps:

1. When I visit the registration page
2. And I enter valid registration information
3. And I submit the form

Expectation:

* Then I should be redirected to the home page
* And I should see a success message displayed
State:

* Given no users exist in the system

Steps:

1. When I visit the registration page
2. And I enter valid registration information
3. And I submit the form

Expectation:

* Then I should be redirected to the home page
* And I should see a success message displayed
create a feature
# features/registration.feature

Feature: User Registration
  In order to identify users in the system
  Users must be able to log in

  Scenario: Successful Registration
    Given no users exist in the system
    When I visit the registration page
    And I enter valid registration information
    And I submit the form
    Then I should be redirected to the home page
    And I should see a success message displayed
$ cucumber registration.feature
You can implement step definitions for undefined steps with
these snippets:

Given /^no users exist in the system$/ do
  pending
end

When /^I visit the registration page$/ do
  pending
end

When /^I enter valid registration information$/ do
  pending
end

When /^I submit the form$/ do
  pending
end

Then /^I should be redirected to the home page$/ do
  pending
end

Then /^I should see a success message displayed$/ do
  pending
end
# steps/registration_steps.rb

Given /^no users exist in the system$/ do
  pending
end

When /^I visit the registration page$/ do
  pending
end

When /^I enter valid registration information$/ do
  pending
end

When /^I submit the form$/ do
  pending
end

Then /^I should be redirected to the home page$/ do
  pending
end

Then /^I should see a success message displayed$/ do
  pending
end




        definitions
# steps/registration_steps.rb

Given /^no users exist in the system$/ do
  open "#{BASE_URL}/setup/clean_slate"
end

When /^I visit the registration page$/ do
  pending
end

When /^I enter valid registration information$/ do
  pending
end

When /^I submit the form$/ do
  pending
end

Then /^I should be redirected to the home page$/ do
  pending
end

Then /^I should see a success message displayed$/ do
  pending
end




                  state
# steps/registration_steps.rb

Given /^no users exist in the system$/ do
  open "#{BASE_URL}/setup/clean_slate"
end

When /^I visit the registration page$/ do
  @browser.open "/register"
end

When /^I enter valid registration information$/ do
  @browser.type "user_email", "user@host.com"
  @browser.type "user_password", "password"
  @browser.type "user_password_confirmation", "password"
  @browser.click "user_terms"
end

When /^I submit the form$/ do
  @browser.click "user_submit"
  @browser.wait_for_page_to_load
end

Then /^I should be redirected to the home page$/ do
  pending
end

Then /^I should see a success message displayed$/ do
  pending
end




                 steps
# steps/registration_steps.rb

Given /^no users exist in the system$/ do
  open "#{BASE_URL}/setup/clean_slate"
end

When /^I visit the registration page$/ do
  @browser.open "/register"
end

When /^I enter valid registration information$/ do
  @browser.type "user_email", "user@host.com"
  @browser.type "user_password", "password"
  @browser.type "user_password_confirmation", "password"
  @browser.click "user_terms"
end

When /^I submit the form$/ do
  @browser.click "user_submit"
  @browser.wait_for_page_to_load
end

Then /^I should be redirected to the home page$/ do
  assert_equal "#{BASE_URL}/", @browser.get_location
end

Then /^I should see a success message displayed$/ do
  assert @browser.is_text_present("Welcome to Spasibo. A winner is you!")
end




      expectation
$ cucumber registration.feature
Feature: User Registration
  In order to identify users in the system
  Users must be able to log in

 Scenario: Successful registration                #   registration.feature:5
   Given no users exist in the system             #   steps/registration_steps.rb:1
   When I visit the registration page             #   steps/registration_steps.rb:5
   And I enter valid registration information     #   steps/registration_steps.rb:9
   And I submit the form                          #   steps/registration_steps.rb:16
   Then I should be redirected to the home page   #   steps/registration_steps.rb:21
   And I should see a success message displayed   #   steps/registration_steps.rb:25

1 scenario (1 passed)
6 steps (6 passed)
problems


• dependent on a developer
• no control over input data
# registration.feature

Feature: User Registration
  In order to identify users in the system
  Users must be able to log in

  Scenario: Successful registration
    Given no users exist in the system
    When I visit "/register"
    And I enter "user@host.com" for "user_email"
    And I enter "password" for "user_password"
    And I enter "password" for "user_password_confirmation"
    And I check the "user_terms" box
    And I click the "user_submit" button
    Then I should be redirected to "/"
    And I should see the message "Welcome to Spasibo. A winner is you!"
You can implement step definitions for undefined steps with these
snippets:

Given /^no users exist in the system$/ do
  pending
end

When /^I visit "([^"]*)"$/ do |arg1|
  pending
end

When /^I enter "([^"]*)" for "([^"]*)"$/ do |arg1, arg2|
  pending
end

When /^I check the "([^"]*)" box$/ do |arg1|
  pending
end

When /^I click the "([^"]*)" button$/ do |arg1|
  pending
end

Then /^I should be redirected to "([^"]*)"$/ do |arg1|
  pending
end

Then /^I should see the message "([^"]*)"$/ do |arg1|
  pending
end
# steps/registration_steps.rb

Given /^no users exist in the system$/ do
  pending
end

When /^I visit "([^"]*)"$/ do |arg1|
  pending
end

When /^I enter "([^"]*)" for "([^"]*)"$/ do |arg1, arg2|
  pending
end

When /^I check the "([^"]*)" box$/ do |arg1|
  pending
end

When /^I click the "([^"]*)" button$/ do |arg1|
  pending
end

Then /^I should be redirected to "([^"]*)"$/ do |arg1|
  pending
end

Then /^I should see the message "([^"]*)"$/ do |arg1|
  pending
end




                definitions
# steps/registration_steps.rb

Given /^no users exist in the system$/ do
  open "#{BASE_URL}/setup/clean_slate"
end

When /^I visit "([^"]*)"$/ do |arg1|
  pending
end

When /^I enter "([^"]*)" for "([^"]*)"$/ do |arg1, arg2|
  pending
end

When /^I check the "([^"]*)" box$/ do |arg1|
  pending
end

When /^I click the "([^"]*)" button$/ do |arg1|
  pending
end

Then /^I should be redirected to "([^"]*)"$/ do |arg1|
  pending
end

Then /^I should see the message "([^"]*)"$/ do |arg1|
  pending
end




                          state
# steps/registration_steps.rb

Given /^no users exist in the system$/ do
  open "#{BASE_URL}/setup/clean_slate"
end

When /^I visit "([^"]*)"$/ do |path|
  @browser.open path
end

When /^I enter "([^"]*)" for "([^"]*)"$/ do |value, text_field_id|
  @browser.type text_field_id, value
end

When /^I check the "([^"]*)" box$/ do |checkbox_id|
  @browser.check checkbox_id
end

When /^I click the "([^"]*)" button$/ do |submit_button_id|
  @browser.click submit_button_id
  @browser.wait_for_page_to_load
end

Then /^I should be redirected to "([^"]*)"$/ do |arg1|
  pending
end

Then /^I should see the message "([^"]*)"$/ do |arg1|
  pending
end


                         steps
# steps/registration_steps.rb

Given /^no users exist in the system$/ do
  open "#{BASE_URL}/setup/clean_slate"
end

When /^I visit "([^"]*)"$/ do |path|
  @browser.open path
end

When /^I enter "([^"]*)" for "([^"]*)"$/ do |value, text_field_id|
  @browser.type text_field_id, value
end

When /^I check the "([^"]*)" box$/ do |checkbox_id|
  @browser.check checkbox_id
end

When /^I click the "([^"]*)" button$/ do |submit_button_id|
  @browser.click submit_button_id
  @browser.wait_for_page_to_load
end

Then /^I should be redirected to "([^"]*)"$/ do |path|
  assert_equal "#{BASE_URL}#{path}", @browser.get_location
end

Then /^I should see the message "([^"]*)"$/ do |message|
  assert @browser.is_text_present(message)
end


              expectation
$ cucumber registration.feature
Feature: User Registration
  In order to identify users in the system
  Users must be able to log in

 Scenario: Successful registration                                       #   registration.feature:7
   Given no users exist in the system                                    #   steps/registration_steps.rb:1
   When I visit "/register"                                              #   steps/registration_steps.rb:5
   And I enter "user@host.com" for "user_email"                          #   steps/registration_steps.rb:9
   And I enter "password" for "user_password"                            #   steps/registration_steps.rb:9
   And I enter "password" for "user_password_confirmation"               #   steps/registration_steps.rb:9
   And I check the "user_terms" box                                      #   steps/registration_steps.rb:13
   And I click the "user_submit" button                                  #   steps/registration_steps.rb:17
   Then I should be redirected to "/"                                    #   steps/registration_steps.rb:22
   And I should see the message "Welcome to Spasibo. A winner is you!"   #   steps/registration_steps.rb:26

1 scenario (1 passed)
9 steps (9 passed)
extend
Scenario: No data supplied
  Given no users exist in the system
  When I visit "/register"
  And I click the "user_submit" button
  Then I should be redirected to "/register"
  And I should see the message "NYET! A FAIL IS YOU"
  And I should see the message "Email can't be blank"
  And I should see the message "Terms must be accepted"

Scenario: Password not confirmed
  Given no users exist in the system
  When I visit "/register"
  And I enter "user@host.com" for "user_email"
  And I enter "password" for "user_password"
  And I enter "drowssap" for "user_password_confirmation"
  And I check the "user_terms" box
  And I click the "user_submit" button
  Then I should be redirected to "/register"
  And I should see the message "NYET! A FAIL IS YOU"
  And I should see the message "Password doesn't match confirmation"
Scenario: Successful registration with alternate data
  Given no users exist in the system
  When I visit "/register"
  And I enter "patrick@viget.com" for "user_email"
  And I enter "password123" for "user_password"
  And I enter "password123" for "user_password_confirmation"
  And I check the "user_terms" box
  And I click the "user_submit" button
  Then I should be redirected to "/"
  And I should see the message "Welcome to Spasibo. A winner is you!"
remove duplication
                image: haakseth @ flickr
Scenario: Successful registration
  Given no users exist in the system
  When I visit "/register"
  And I enter "user@host.com" for "user_email"
  And I enter "password" for "user_password"
  And I enter "password" for "user_password_confirmation"
  And I check the "user_terms" box
  And I click the "user_submit" button
  Then I should be redirected to "/"
  And I should see the message "Welcome to Spasibo. A winner is you!"
Scenario Outline: Successful registration
  Given no users exist in the system
  When I visit "/register"
  And I enter "user@host.com" for "user_email"
  And I enter "password" for "user_password"
  And I enter "password" for "user_password_confirmation"
  And I check the "user_terms" box
  And I click the "user_submit" button
  Then I should be redirected to "/"
  And I should see the message "Welcome to Spasibo. A winner is you!"
Scenario Outline: Successful registration
  Given no users exist in the system
  When I visit "/register"
  And I enter "<email>" for "user_email"
  And I enter "<password>" for "user_password"
  And I enter "<password_confirmation>" for "user_password_confirmation"
  And I check the "user_terms" box
  And I click the "user_submit" button
  Then I should be redirected to "/"
  And I should see the message "Welcome to Spasibo. A winner is you!"
Scenario Outline: Successful registration
  Given no users exist in the system
  When I visit "/register"
  And I enter "<email>" for "user_email"
  And I enter "<password>" for "user_password"
  And I enter "<password_confirmation>" for "user_password_confirmation"
  And I check the "user_terms" box
  And I click the "user_submit" button
  Then I should be redirected to "/"
  And I should see the message "Welcome to Spasibo. A winner is you!"

 Examples:
   | email             | password    | password_confirmation |
   | user@host.com     | password    | password              |
   | patrick@viget.com | password123 | password123           |
$ cucumber registration.feature
Feature: User registration
  In order to identify users in the system
  Users must be able to log in

 Scenario Outline: Successful Registration                                  #   registration.feature:7
   Given no users exist in the system                                       #   steps/registration_steps.rb:1
   When I visit "/register"                                                 #   steps/registration_steps.rb:5
   And I enter "<email>" for "user_email"                                   #   steps/registration_steps.rb:9
   And I enter "<password>" for "user_password"                             #   steps/registration_steps.rb:9
   And I enter "<password_confirmation>" for "user_password_confirmation"   #   steps/registration_steps.rb:9
   And I check the "user_terms" box                                         #   steps/registration_steps.rb:13
   And I click the "user_submit" button                                     #   steps/registration_steps.rb:17
   Then I should be redirected to "/"                                       #   steps/registration_steps.rb:22
   And I should see the message "Welcome to Spasibo. A winner is you!"      #   steps/registration_steps.rb:26

   Examples:
     | email             | password    | password_confirmation |
     | user@host.com     | password    | password              |
     | patrick@viget.com | password123 | password123           |

2 scenarios (2 passed)
18 steps (18 passed)
image: mediageek @ flickr
future
Scenario: Duplicate email address
  Given a user exists in the system with the email "user@host.com"
  When I visit "/register"
  And I enter valid registration information
  And I enter "user@host.com" for "user_email"
  And I click the "user_submit" button
  Then I should be redirected to "/register"
  And I should see the message "Email has already been taken"




                       refactor
Scenario: Duplicate email address
  Given a user exists in the system with the email "user@host.com"
  When I visit "/register"
  And I enter valid registration information
  And I enter "user@host.com" for "user_email"
  And I click the "user_submit" button
  Then I should be redirected to "/register"
  And I should see the message "Email has already been taken"




                       refactor
Given /^a user exists in the system with the email "([^"]*)"$/ do |email|
  Given 'no users exist in the system'
  When 'I visit "/register"'
  When 'I enter valid registration information'
  When 'I enter "' + email + '" for "user_email"'
  When 'I click the "user_submit" button'
end

When /^I enter valid registration information$/ do
  When 'I enter "user@host.com" for "user_email"'
  When 'I enter "password" for "user_password"'
  When 'I enter "password" for "user_password_confirmation"'
  When 'I check the "user_terms" box'
end




                            refactor
Scenario: Duplicate email address                                    #   registration.feature:51
  Given a user exists in the system with the email "user@host.com"   #   steps/registration_steps.rb:30
  When I visit "/register"                                           #   steps/registration_steps.rb:5
  And I enter valid registration information                         #   steps/registration_steps.rb:38
  And I enter "user@host.com" for "user_email"                       #   steps/registration_steps.rb:9
  And I click the "user_submit" button                               #   steps/registration_steps.rb:17
  Then I should be redirected to "/register"                         #   steps/registration_steps.rb:22
  And I should see the message "Email has already been taken"        #   steps/registration_steps.rb:26
$ cucumber registration.feature --name "Success"
Feature: User Registration
  In order to identify users in the system
  Users must be able to log in

  Scenario: Successful registration                                       #   registration.feature:7
    Given no users exist in the system                                    #   steps/registration_steps.rb:1
    When I visit "/register"                                              #   steps/registration_steps.rb:5
    And I enter "user@host.com" for "user_email"                          #   steps/registration_steps.rb:9
    And I enter "password" for "user_password"                            #   steps/registration_steps.rb:9
    And I enter "password" for "user_password_confirmation"               #   steps/registration_steps.rb:9
    And I check the "user_terms" box                                      #   steps/registration_steps.rb:13
    And I click the "user_submit" button                                  #   steps/registration_steps.rb:17
    Then I should be redirected to "/"                                    #   steps/registration_steps.rb:22
    And I should see the message "Welcome to Spasibo. A winner is you!"   #   steps/registration_steps.rb:26

  Scenario: Successful registration with alternate data                   #   registration.feature:18
    Given no users exist in the system                                    #   steps/registration_steps.rb:1
    When I visit "/register"                                              #   steps/registration_steps.rb:5
    And I enter "patrick@viget.com" for "user_email"                      #   steps/registration_steps.rb:9
    And I enter "password123" for "user_password"                         #   steps/registration_steps.rb:9
    And I enter "password123" for "user_password_confirmation"            #   steps/registration_steps.rb:9
    And I check the "user_terms" box                                      #   steps/registration_steps.rb:13
    And I click the "user_submit" button                                  #   steps/registration_steps.rb:17
    Then I should be redirected to "/"                                    #   steps/registration_steps.rb:22
    And I should see the message "Welcome to Spasibo. A winner is you!"   #   steps/registration_steps.rb:26

2 scenarios (2 passed)
18 steps (18 passed)




                                run by name
@slow
Scenario: Duplicate email address
  Given a user exists in the system with the email "user@host.com"
  When I visit "/register"
  And I enter valid registration information
  And I enter "user@host.com" for "user_email"
  And I click the "user_submit" button
  Then I should be redirected to "/register"
  And I should see the message "Email has already been taken"




                         tagging
$ cucumber registration.feature --tags @slow
Feature: User Registration
  In order to identify users in the system
  Users must be able to log in

  @slow
  Scenario: Duplicate email address                                    #   registration.feature:51
    Given a user exists in the system with the email "user@host.com"   #   steps/registration_steps.rb:30
    When I visit "/register"                                           #   steps/registration_steps.rb:5
    And I enter valid registration information                         #   steps/registration_steps.rb:38
    And I enter "user@host.com" for "user_email"                       #   steps/registration_steps.rb:9
    And I click the "user_submit" button                               #   steps/registration_steps.rb:17
    Then I should be redirected to "/register"                         #   steps/registration_steps.rb:22
    And I should see the message "Email has already been taken"        #   steps/registration_steps.rb:26

1 scenario (1 passed)
7 steps (7 passed)




                                 run by tag
$ cucumber registration.feature --tags ~@slow
cross platform
continuous integration
continuous integration
        integration?
Resources
 • Selenium: http://seleniumhq.org/
 • Cucumber: http://cukes.info/
 • Slides / Code: http://github.com/reagent/nlt
Contact
 • patrick.reagan@viget.com
 • http://twitter.com/reagent



                                                  image: nomeacuerdo @ flickr

More Related Content

What's hot

Building Quality with Foundations of Mud
Building Quality with Foundations of MudBuilding Quality with Foundations of Mud
Building Quality with Foundations of Mudseleniumconf
 
Turbogears Presentation
Turbogears PresentationTurbogears Presentation
Turbogears Presentationdidip
 
Testing Rapidly Changing Applications With Self-Testing Object-Oriented Selen...
Testing Rapidly Changing Applications With Self-Testing Object-Oriented Selen...Testing Rapidly Changing Applications With Self-Testing Object-Oriented Selen...
Testing Rapidly Changing Applications With Self-Testing Object-Oriented Selen...seleniumconf
 
What you can do In WatiR
What you can do In WatiRWhat you can do In WatiR
What you can do In WatiRWesley Chen
 
20160905 - BrisJS - nightwatch testing
20160905 - BrisJS - nightwatch testing20160905 - BrisJS - nightwatch testing
20160905 - BrisJS - nightwatch testingVladimir Roudakov
 
Entry-level PHP for WordPress
Entry-level PHP for WordPressEntry-level PHP for WordPress
Entry-level PHP for WordPresssprclldr
 
Unit Testing for Great Justice
Unit Testing for Great JusticeUnit Testing for Great Justice
Unit Testing for Great JusticeDomenic Denicola
 
Jest: Frontend Testing richtig gemacht @WebworkerNRW
Jest: Frontend Testing richtig gemacht @WebworkerNRWJest: Frontend Testing richtig gemacht @WebworkerNRW
Jest: Frontend Testing richtig gemacht @WebworkerNRWHolger Grosse-Plankermann
 
Experience Manager 6 Developer Features - Highlights
Experience Manager 6 Developer Features - HighlightsExperience Manager 6 Developer Features - Highlights
Experience Manager 6 Developer Features - HighlightsCédric Hüsler
 
How to Un-Flake Flaky Tests - A New Hire's Toolkit
How to Un-Flake Flaky Tests - A New Hire's ToolkitHow to Un-Flake Flaky Tests - A New Hire's Toolkit
How to Un-Flake Flaky Tests - A New Hire's ToolkitZachary Attas
 
A journey beyond the page object pattern
A journey beyond the page object patternA journey beyond the page object pattern
A journey beyond the page object patternRiverGlide
 
Web API Test Automation using Frisby & Node.js
Web API Test Automation using Frisby  & Node.jsWeb API Test Automation using Frisby  & Node.js
Web API Test Automation using Frisby & Node.jsChi Lang Le Vu Tran
 
watir-webdriver
watir-webdriverwatir-webdriver
watir-webdriverjariba
 
How to Un-Flake Flaky Tests - A New Hire's Toolkit
How to Un-Flake Flaky Tests - A New Hire's ToolkitHow to Un-Flake Flaky Tests - A New Hire's Toolkit
How to Un-Flake Flaky Tests - A New Hire's ToolkitZachary Attas
 
Keyword Driven Framework using WATIR
Keyword Driven Framework using WATIRKeyword Driven Framework using WATIR
Keyword Driven Framework using WATIRNivetha Padmanaban
 
OpenERP and Perl
OpenERP and PerlOpenERP and Perl
OpenERP and PerlOpusVL
 
Laravel - Website Development in Php Framework.
Laravel - Website Development in Php Framework.Laravel - Website Development in Php Framework.
Laravel - Website Development in Php Framework.SWAAM Tech
 
Watir Presentation Sumanth Krishna. A
Watir Presentation   Sumanth Krishna. AWatir Presentation   Sumanth Krishna. A
Watir Presentation Sumanth Krishna. ASumanth krishna
 
Lessons from a year of building apps with React Native
Lessons from a year of building apps with React NativeLessons from a year of building apps with React Native
Lessons from a year of building apps with React NativeRyan Boland
 
Powershell to the People #suguk
Powershell to the People #sugukPowershell to the People #suguk
Powershell to the People #sugukChris McKinley
 

What's hot (20)

Building Quality with Foundations of Mud
Building Quality with Foundations of MudBuilding Quality with Foundations of Mud
Building Quality with Foundations of Mud
 
Turbogears Presentation
Turbogears PresentationTurbogears Presentation
Turbogears Presentation
 
Testing Rapidly Changing Applications With Self-Testing Object-Oriented Selen...
Testing Rapidly Changing Applications With Self-Testing Object-Oriented Selen...Testing Rapidly Changing Applications With Self-Testing Object-Oriented Selen...
Testing Rapidly Changing Applications With Self-Testing Object-Oriented Selen...
 
What you can do In WatiR
What you can do In WatiRWhat you can do In WatiR
What you can do In WatiR
 
20160905 - BrisJS - nightwatch testing
20160905 - BrisJS - nightwatch testing20160905 - BrisJS - nightwatch testing
20160905 - BrisJS - nightwatch testing
 
Entry-level PHP for WordPress
Entry-level PHP for WordPressEntry-level PHP for WordPress
Entry-level PHP for WordPress
 
Unit Testing for Great Justice
Unit Testing for Great JusticeUnit Testing for Great Justice
Unit Testing for Great Justice
 
Jest: Frontend Testing richtig gemacht @WebworkerNRW
Jest: Frontend Testing richtig gemacht @WebworkerNRWJest: Frontend Testing richtig gemacht @WebworkerNRW
Jest: Frontend Testing richtig gemacht @WebworkerNRW
 
Experience Manager 6 Developer Features - Highlights
Experience Manager 6 Developer Features - HighlightsExperience Manager 6 Developer Features - Highlights
Experience Manager 6 Developer Features - Highlights
 
How to Un-Flake Flaky Tests - A New Hire's Toolkit
How to Un-Flake Flaky Tests - A New Hire's ToolkitHow to Un-Flake Flaky Tests - A New Hire's Toolkit
How to Un-Flake Flaky Tests - A New Hire's Toolkit
 
A journey beyond the page object pattern
A journey beyond the page object patternA journey beyond the page object pattern
A journey beyond the page object pattern
 
Web API Test Automation using Frisby & Node.js
Web API Test Automation using Frisby  & Node.jsWeb API Test Automation using Frisby  & Node.js
Web API Test Automation using Frisby & Node.js
 
watir-webdriver
watir-webdriverwatir-webdriver
watir-webdriver
 
How to Un-Flake Flaky Tests - A New Hire's Toolkit
How to Un-Flake Flaky Tests - A New Hire's ToolkitHow to Un-Flake Flaky Tests - A New Hire's Toolkit
How to Un-Flake Flaky Tests - A New Hire's Toolkit
 
Keyword Driven Framework using WATIR
Keyword Driven Framework using WATIRKeyword Driven Framework using WATIR
Keyword Driven Framework using WATIR
 
OpenERP and Perl
OpenERP and PerlOpenERP and Perl
OpenERP and Perl
 
Laravel - Website Development in Php Framework.
Laravel - Website Development in Php Framework.Laravel - Website Development in Php Framework.
Laravel - Website Development in Php Framework.
 
Watir Presentation Sumanth Krishna. A
Watir Presentation   Sumanth Krishna. AWatir Presentation   Sumanth Krishna. A
Watir Presentation Sumanth Krishna. A
 
Lessons from a year of building apps with React Native
Lessons from a year of building apps with React NativeLessons from a year of building apps with React Native
Lessons from a year of building apps with React Native
 
Powershell to the People #suguk
Powershell to the People #sugukPowershell to the People #suguk
Powershell to the People #suguk
 

Viewers also liked

Viewers also liked (7)

google amp pages
google amp pagesgoogle amp pages
google amp pages
 
User acceptance testing checklist (uat)
User acceptance testing checklist (uat)User acceptance testing checklist (uat)
User acceptance testing checklist (uat)
 
55993161 te040-r12-cash-management-test-scripts
55993161 te040-r12-cash-management-test-scripts55993161 te040-r12-cash-management-test-scripts
55993161 te040-r12-cash-management-test-scripts
 
Getting Ready for UAT
Getting Ready for UATGetting Ready for UAT
Getting Ready for UAT
 
UAT Kickoff Presentation 10 29 09
UAT Kickoff Presentation 10 29 09UAT Kickoff Presentation 10 29 09
UAT Kickoff Presentation 10 29 09
 
5 Types of USER ACCEPTANCE TESTING (UAT)
5 Types of USER ACCEPTANCE TESTING (UAT)5 Types of USER ACCEPTANCE TESTING (UAT)
5 Types of USER ACCEPTANCE TESTING (UAT)
 
Specification-By-Example with Gherkin
Specification-By-Example with GherkinSpecification-By-Example with Gherkin
Specification-By-Example with Gherkin
 

Similar to Make Everyone a Tester: Natural Language Acceptance Testing

Make Everyone a Tester: Natural Language Acceptance Testing
Make Everyone a Tester: Natural Language Acceptance TestingMake Everyone a Tester: Natural Language Acceptance Testing
Make Everyone a Tester: Natural Language Acceptance TestingViget Labs
 
Test Design Essentials for Great Test Automation - Titus
Test Design Essentials for Great Test Automation - TitusTest Design Essentials for Great Test Automation - Titus
Test Design Essentials for Great Test Automation - TitusSauce Labs
 
full-stack-webapp-testing-with-selenium-and-rails.pdf
full-stack-webapp-testing-with-selenium-and-rails.pdffull-stack-webapp-testing-with-selenium-and-rails.pdf
full-stack-webapp-testing-with-selenium-and-rails.pdfBrian Takita
 
Cypress - Best Practices
Cypress - Best PracticesCypress - Best Practices
Cypress - Best PracticesBrian Mann
 
Easy logins for JavaScript web applications
Easy logins for JavaScript web applicationsEasy logins for JavaScript web applications
Easy logins for JavaScript web applicationsFrancois Marier
 
You're still using passwords on your site?
You're still using passwords on your site?You're still using passwords on your site?
You're still using passwords on your site?Francois Marier
 
Easy logins for Ruby web applications
Easy logins for Ruby web applicationsEasy logins for Ruby web applications
Easy logins for Ruby web applicationsFrancois Marier
 
EWD 3 Training Course Part 10: QEWD Sessions and User Authentication
EWD 3 Training Course Part 10: QEWD Sessions and User AuthenticationEWD 3 Training Course Part 10: QEWD Sessions and User Authentication
EWD 3 Training Course Part 10: QEWD Sessions and User AuthenticationRob Tweed
 
When Securing Access to Data is About Life and Death
When Securing Access to Data is About Life and DeathWhen Securing Access to Data is About Life and Death
When Securing Access to Data is About Life and DeathHostedbyConfluent
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I thinkWim Godden
 
Power Automate Techniques that "Saved Our Bacon"
Power Automate Techniques that "Saved Our Bacon"Power Automate Techniques that "Saved Our Bacon"
Power Automate Techniques that "Saved Our Bacon"Thomas Duff
 
2017 Secure360 - Hacking SQL Server on Scale with PowerShell
2017 Secure360 - Hacking SQL Server on Scale with PowerShell2017 Secure360 - Hacking SQL Server on Scale with PowerShell
2017 Secure360 - Hacking SQL Server on Scale with PowerShellScott Sutherland
 
Kohana 3.2 documentation
Kohana 3.2 documentationKohana 3.2 documentation
Kohana 3.2 documentationdmthuan1
 
Story Driven Development With Cucumber
Story Driven Development With CucumberStory Driven Development With Cucumber
Story Driven Development With CucumberSean Cribbs
 
Building Better Applications with Data::Manager
Building Better Applications with Data::ManagerBuilding Better Applications with Data::Manager
Building Better Applications with Data::ManagerJay Shirley
 
Building sustainable RESTFul services
Building sustainable RESTFul servicesBuilding sustainable RESTFul services
Building sustainable RESTFul servicesOrtus Solutions, Corp
 
Join the darkside: Selenium testing with Nightwatch.js
Join the darkside: Selenium testing with Nightwatch.jsJoin the darkside: Selenium testing with Nightwatch.js
Join the darkside: Selenium testing with Nightwatch.jsSeth McLaughlin
 

Similar to Make Everyone a Tester: Natural Language Acceptance Testing (20)

Make Everyone a Tester: Natural Language Acceptance Testing
Make Everyone a Tester: Natural Language Acceptance TestingMake Everyone a Tester: Natural Language Acceptance Testing
Make Everyone a Tester: Natural Language Acceptance Testing
 
Test Design Essentials for Great Test Automation - Titus
Test Design Essentials for Great Test Automation - TitusTest Design Essentials for Great Test Automation - Titus
Test Design Essentials for Great Test Automation - Titus
 
full-stack-webapp-testing-with-selenium-and-rails.pdf
full-stack-webapp-testing-with-selenium-and-rails.pdffull-stack-webapp-testing-with-selenium-and-rails.pdf
full-stack-webapp-testing-with-selenium-and-rails.pdf
 
Cypress - Best Practices
Cypress - Best PracticesCypress - Best Practices
Cypress - Best Practices
 
Easy logins for JavaScript web applications
Easy logins for JavaScript web applicationsEasy logins for JavaScript web applications
Easy logins for JavaScript web applications
 
You're still using passwords on your site?
You're still using passwords on your site?You're still using passwords on your site?
You're still using passwords on your site?
 
Easy logins for Ruby web applications
Easy logins for Ruby web applicationsEasy logins for Ruby web applications
Easy logins for Ruby web applications
 
EWD 3 Training Course Part 10: QEWD Sessions and User Authentication
EWD 3 Training Course Part 10: QEWD Sessions and User AuthenticationEWD 3 Training Course Part 10: QEWD Sessions and User Authentication
EWD 3 Training Course Part 10: QEWD Sessions and User Authentication
 
ApacheCon 2005
ApacheCon 2005ApacheCon 2005
ApacheCon 2005
 
When Securing Access to Data is About Life and Death
When Securing Access to Data is About Life and DeathWhen Securing Access to Data is About Life and Death
When Securing Access to Data is About Life and Death
 
My app is secure... I think
My app is secure... I thinkMy app is secure... I think
My app is secure... I think
 
Power Automate Techniques that "Saved Our Bacon"
Power Automate Techniques that "Saved Our Bacon"Power Automate Techniques that "Saved Our Bacon"
Power Automate Techniques that "Saved Our Bacon"
 
2017 Secure360 - Hacking SQL Server on Scale with PowerShell
2017 Secure360 - Hacking SQL Server on Scale with PowerShell2017 Secure360 - Hacking SQL Server on Scale with PowerShell
2017 Secure360 - Hacking SQL Server on Scale with PowerShell
 
Selenium
SeleniumSelenium
Selenium
 
Kohana 3.2 documentation
Kohana 3.2 documentationKohana 3.2 documentation
Kohana 3.2 documentation
 
Story Driven Development With Cucumber
Story Driven Development With CucumberStory Driven Development With Cucumber
Story Driven Development With Cucumber
 
Building Better Applications with Data::Manager
Building Better Applications with Data::ManagerBuilding Better Applications with Data::Manager
Building Better Applications with Data::Manager
 
Building sustainable RESTFul services
Building sustainable RESTFul servicesBuilding sustainable RESTFul services
Building sustainable RESTFul services
 
Join the darkside: Selenium testing with Nightwatch.js
Join the darkside: Selenium testing with Nightwatch.jsJoin the darkside: Selenium testing with Nightwatch.js
Join the darkside: Selenium testing with Nightwatch.js
 
Selenium testing - Handle Elements in WebDriver
Selenium testing - Handle Elements in WebDriver Selenium testing - Handle Elements in WebDriver
Selenium testing - Handle Elements in WebDriver
 

Recently uploaded

Cyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptx
Cyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptxCyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptx
Cyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptxMasterG
 
2024 May Patch Tuesday
2024 May Patch Tuesday2024 May Patch Tuesday
2024 May Patch TuesdayIvanti
 
The Zero-ETL Approach: Enhancing Data Agility and Insight
The Zero-ETL Approach: Enhancing Data Agility and InsightThe Zero-ETL Approach: Enhancing Data Agility and Insight
The Zero-ETL Approach: Enhancing Data Agility and InsightSafe Software
 
Introduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDMIntroduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDMKumar Satyam
 
Navigating the Large Language Model choices_Ravi Daparthi
Navigating the Large Language Model choices_Ravi DaparthiNavigating the Large Language Model choices_Ravi Daparthi
Navigating the Large Language Model choices_Ravi DaparthiRaviKumarDaparthi
 
Event-Driven Architecture Masterclass: Engineering a Robust, High-performance...
Event-Driven Architecture Masterclass: Engineering a Robust, High-performance...Event-Driven Architecture Masterclass: Engineering a Robust, High-performance...
Event-Driven Architecture Masterclass: Engineering a Robust, High-performance...ScyllaDB
 
State of the Smart Building Startup Landscape 2024!
State of the Smart Building Startup Landscape 2024!State of the Smart Building Startup Landscape 2024!
State of the Smart Building Startup Landscape 2024!Memoori
 
Event-Driven Architecture Masterclass: Challenges in Stream Processing
Event-Driven Architecture Masterclass: Challenges in Stream ProcessingEvent-Driven Architecture Masterclass: Challenges in Stream Processing
Event-Driven Architecture Masterclass: Challenges in Stream ProcessingScyllaDB
 
Portal Kombat : extension du réseau de propagande russe
Portal Kombat : extension du réseau de propagande russePortal Kombat : extension du réseau de propagande russe
Portal Kombat : extension du réseau de propagande russe中 央社
 
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)Samir Dash
 
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...Skynet Technologies
 
AI in Action: Real World Use Cases by Anitaraj
AI in Action: Real World Use Cases by AnitarajAI in Action: Real World Use Cases by Anitaraj
AI in Action: Real World Use Cases by AnitarajAnitaRaj43
 
Top 10 CodeIgniter Development Companies
Top 10 CodeIgniter Development CompaniesTop 10 CodeIgniter Development Companies
Top 10 CodeIgniter Development CompaniesTopCSSGallery
 
CORS (Kitworks Team Study 양다윗 발표자료 240510)
CORS (Kitworks Team Study 양다윗 발표자료 240510)CORS (Kitworks Team Study 양다윗 발표자료 240510)
CORS (Kitworks Team Study 양다윗 발표자료 240510)Wonjun Hwang
 
Design and Development of a Provenance Capture Platform for Data Science
Design and Development of a Provenance Capture Platform for Data ScienceDesign and Development of a Provenance Capture Platform for Data Science
Design and Development of a Provenance Capture Platform for Data SciencePaolo Missier
 
ADP Passwordless Journey Case Study.pptx
ADP Passwordless Journey Case Study.pptxADP Passwordless Journey Case Study.pptx
ADP Passwordless Journey Case Study.pptxFIDO Alliance
 
UiPath manufacturing technology benefits and AI overview
UiPath manufacturing technology benefits and AI overviewUiPath manufacturing technology benefits and AI overview
UiPath manufacturing technology benefits and AI overviewDianaGray10
 
الأمن السيبراني - ما لا يسع للمستخدم جهله
الأمن السيبراني - ما لا يسع للمستخدم جهلهالأمن السيبراني - ما لا يسع للمستخدم جهله
الأمن السيبراني - ما لا يسع للمستخدم جهلهMohamed Sweelam
 
Generative AI Use Cases and Applications.pdf
Generative AI Use Cases and Applications.pdfGenerative AI Use Cases and Applications.pdf
Generative AI Use Cases and Applications.pdfalexjohnson7307
 
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)Paige Cruz
 

Recently uploaded (20)

Cyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptx
Cyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptxCyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptx
Cyber Insurance - RalphGilot - Embry-Riddle Aeronautical University.pptx
 
2024 May Patch Tuesday
2024 May Patch Tuesday2024 May Patch Tuesday
2024 May Patch Tuesday
 
The Zero-ETL Approach: Enhancing Data Agility and Insight
The Zero-ETL Approach: Enhancing Data Agility and InsightThe Zero-ETL Approach: Enhancing Data Agility and Insight
The Zero-ETL Approach: Enhancing Data Agility and Insight
 
Introduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDMIntroduction to use of FHIR Documents in ABDM
Introduction to use of FHIR Documents in ABDM
 
Navigating the Large Language Model choices_Ravi Daparthi
Navigating the Large Language Model choices_Ravi DaparthiNavigating the Large Language Model choices_Ravi Daparthi
Navigating the Large Language Model choices_Ravi Daparthi
 
Event-Driven Architecture Masterclass: Engineering a Robust, High-performance...
Event-Driven Architecture Masterclass: Engineering a Robust, High-performance...Event-Driven Architecture Masterclass: Engineering a Robust, High-performance...
Event-Driven Architecture Masterclass: Engineering a Robust, High-performance...
 
State of the Smart Building Startup Landscape 2024!
State of the Smart Building Startup Landscape 2024!State of the Smart Building Startup Landscape 2024!
State of the Smart Building Startup Landscape 2024!
 
Event-Driven Architecture Masterclass: Challenges in Stream Processing
Event-Driven Architecture Masterclass: Challenges in Stream ProcessingEvent-Driven Architecture Masterclass: Challenges in Stream Processing
Event-Driven Architecture Masterclass: Challenges in Stream Processing
 
Portal Kombat : extension du réseau de propagande russe
Portal Kombat : extension du réseau de propagande russePortal Kombat : extension du réseau de propagande russe
Portal Kombat : extension du réseau de propagande russe
 
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
AI+A11Y 11MAY2024 HYDERBAD GAAD 2024 - HelloA11Y (11 May 2024)
 
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...
Human Expert Website Manual WCAG 2.0 2.1 2.2 Audit - Digital Accessibility Au...
 
AI in Action: Real World Use Cases by Anitaraj
AI in Action: Real World Use Cases by AnitarajAI in Action: Real World Use Cases by Anitaraj
AI in Action: Real World Use Cases by Anitaraj
 
Top 10 CodeIgniter Development Companies
Top 10 CodeIgniter Development CompaniesTop 10 CodeIgniter Development Companies
Top 10 CodeIgniter Development Companies
 
CORS (Kitworks Team Study 양다윗 발표자료 240510)
CORS (Kitworks Team Study 양다윗 발표자료 240510)CORS (Kitworks Team Study 양다윗 발표자료 240510)
CORS (Kitworks Team Study 양다윗 발표자료 240510)
 
Design and Development of a Provenance Capture Platform for Data Science
Design and Development of a Provenance Capture Platform for Data ScienceDesign and Development of a Provenance Capture Platform for Data Science
Design and Development of a Provenance Capture Platform for Data Science
 
ADP Passwordless Journey Case Study.pptx
ADP Passwordless Journey Case Study.pptxADP Passwordless Journey Case Study.pptx
ADP Passwordless Journey Case Study.pptx
 
UiPath manufacturing technology benefits and AI overview
UiPath manufacturing technology benefits and AI overviewUiPath manufacturing technology benefits and AI overview
UiPath manufacturing technology benefits and AI overview
 
الأمن السيبراني - ما لا يسع للمستخدم جهله
الأمن السيبراني - ما لا يسع للمستخدم جهلهالأمن السيبراني - ما لا يسع للمستخدم جهله
الأمن السيبراني - ما لا يسع للمستخدم جهله
 
Generative AI Use Cases and Applications.pdf
Generative AI Use Cases and Applications.pdfGenerative AI Use Cases and Applications.pdf
Generative AI Use Cases and Applications.pdf
 
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
Observability Concepts EVERY Developer Should Know (DevOpsDays Seattle)
 

Make Everyone a Tester: Natural Language Acceptance Testing

  • 1. Make Everyone a Tester Natural Language Acceptance Testing
  • 2.
  • 3. PM Design UX Dev
  • 8. goals • developer & PM pairing • tests written first • drive a web browser
  • 9. start with a story Users can register for an account Requires the following information: * Email * Password * Password Confirmation * Acceptance of terms / conditions Acceptance Criteria * Try with a duplicate email address * Try with a password less than 6 characters
  • 11. discuss Users can register for an account Requires the following information: * Email * Password * Password Confirmation * Acceptance of terms / conditions Acceptance Criteria * Try with a duplicate email address * Try with a password less than 6 characters
  • 12. discuss Users can register for an account Requires the following information: * Email form with data fields * Password * Password Confirmation * Acceptance of terms / conditions Acceptance Criteria * Try with a duplicate email address * Try with a password less than 6 characters
  • 13. discuss success state Users can register for an account Requires the following information: * Email form with data fields * Password * Password Confirmation * Acceptance of terms / conditions Acceptance Criteria * Try with a duplicate email address * Try with a password less than 6 characters
  • 14. discuss success state Users can register for an account Requires the following information: * Email form with data fields * Password * Password Confirmation * Acceptance of terms / conditions Acceptance Criteria error states * Try with a duplicate email address * Try with a password less than 6 characters
  • 15. define behavior • locations • page state • message content
  • 16. State: * No users exist in the system Steps: 1. Visit the registration page 2. Enter valid registration information 3. Submit the form Expectation: * I should be redirected to the home page * I should see a success message displayed where am I starting from?
  • 17. State: * No users exist in the system Steps: 1. Visit the registration page 2. Enter valid registration information 3. Submit the form Expectation: * I should be redirected to the home page * I should see a success message displayed what are the inputs?
  • 18. State: * No users exist in the system Steps: 1. Visit the registration page 2. Enter valid registration information 3. Submit the form Expectation: * I should be redirected to the home page * I should see a success message displayed what is the behavior?
  • 20. problems • time consuming • prone to error • no regressions
  • 22.
  • 23.
  • 24. done.
  • 26. <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1- strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head profile="http://selenium-ide.openqa.org/profiles/test-case"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <link rel="selenium.base" href="http://spasibo.com/" /> <title>spasibo-test</title> </head> <body> <table cellpadding="1" cellspacing="1" border="1"> <thead> <tr><td rowspan="1" colspan="3">spasibo-test</td></tr> </thead><tbody> <tr> <td>open</td> <td>/</td> <td></td> </tr> <tr> <td>clickAndWait</td> <td>link=Register</td> <td></td> </tr> <tr> <td>type</td> <td>user_email</td> <td>user@host.com</td> </tr> <tr> <td>type</td> <td>user_password</td> <td>password</td> </tr>
  • 27.
  • 28.
  • 29. problems • not maintainable • not reusable • not understandable
  • 31. write automated web application tests in a familiar language and have them run in the browser
  • 32.
  • 33.
  • 34. $ java -jar selenium-server.jar 12:51:31.262 INFO - Java: Apple Inc. 1.5.0_16-133 12:51:31.263 INFO - OS: Mac OS X 10.5.6 i386 12:51:31.270 INFO - v1.0-beta-2 [2571], with Core v1.0-beta-2 [2330] 12:51:31.394 INFO - Version Jetty/5.1.x 12:51:31.395 INFO - Started HttpContext[/,/] 12:51:31.396 INFO - Started HttpContext[/selenium-server,/selenium-server] 12:51:31.397 INFO - Started HttpContext[/selenium-server/driver,/selenium-server/driver] 12:51:31.408 INFO - Started SocketListener on 0.0.0.0:4444 12:51:31.408 INFO - Started org.mortbay.jetty.Server@bc887b
  • 35. class NewTest < Test::Unit::TestCase ... def test_new @selenium.open "/" @selenium.click "link=Register" @selenium.wait_for_page_to_load "30000" @selenium.type "user_email", "user@host.com" @selenium.type "user_password", "password" @selenium.type "user_password_confirmation", "password" @selenium.click "user_terms" @selenium.click "user_submit" @selenium.wait_for_page_to_load "30000" @selenium.wait_for_page_to_load "5000" begin assert @selenium.is_text_present("Welcome to Spasibo. A winner is you!") rescue Test::Unit::AssertionFailedError @verification_errors << $! end begin assert_equal "http://spasibo.com/", @selenium.get_location rescue Test::Unit::AssertionFailedError @verification_errors << $! end end end
  • 36.
  • 37. $ gem install Selenium
  • 39. require "selenium" require "test/unit" require "open-uri" class NewTest < Test::Unit::TestCase def setup base_url = "http://spasibo.com/" open("#{base_url}setup/clean_slate") @verification_errors = [] if $selenium @selenium = $selenium else @selenium = Selenium::SeleniumDriver.new("localhost", 4444, "*chrome", base_url, 10000); @selenium.start end @selenium.set_context("test_new") end def teardown @selenium.stop unless $selenium assert_equal [], @verification_errors end def test_new @selenium.open "/" @selenium.click "link=Register" @selenium.wait_for_page_to_load "30000" @selenium.type "user_email", "user@host.com" @selenium.type "user_password", "password" @selenium.type "user_password_confirmation", "password" @selenium.click "user_terms" @selenium.click "user_submit" @selenium.wait_for_page_to_load "30000" @selenium.wait_for_page_to_load "5000" begin assert @selenium.is_text_present("Welcome to Spasibo. A winner is you!") rescue Test::Unit::AssertionFailedError @verification_errors << $! end begin assert_equal "http://spasibo.com/", @selenium.get_location rescue Test::Unit::AssertionFailedError @verification_errors << $! end end end
  • 40. def setup port start URL ... @selenium = Selenium::SeleniumDriver.new("localhost", 4444, "*chrome", base_url, 10000); @selenium.start ... host browser timeout end setup
  • 41. def setup base_url = "http://spasibo.com/" open("#{base_url}setup/clean_slate") ... end no users exist in the system
  • 42. don’t do this in production def setup base_url = "http://spasibo.com/" open("#{base_url}setup/clean_slate") ... end no users exist in the system
  • 43. def test_new @selenium.open "/" @selenium.click "link=Register" @selenium.wait_for_page_to_load "30000" @selenium.type "user_email", "user@host.com" @selenium.type "user_password", "password" @selenium.type "user_password_confirmation", "password" @selenium.click "user_terms" @selenium.click "user_submit" @selenium.wait_for_page_to_load "30000" @selenium.wait_for_page_to_load "5000" ... end 1. visit the registration page
  • 44. def test_new @selenium.open "/" @selenium.click "link=Register" @selenium.wait_for_page_to_load "30000" @selenium.type "user_email", "user@host.com" @selenium.type "user_password", "password" @selenium.type "user_password_confirmation", "password" @selenium.click "user_terms" @selenium.click "user_submit" @selenium.wait_for_page_to_load "30000" @selenium.wait_for_page_to_load "5000" ... end 2. enter valid information
  • 45. def test_new @selenium.open "/" @selenium.click "link=Register" @selenium.wait_for_page_to_load "30000" @selenium.type "user_email", "user@host.com" @selenium.type "user_password", "password" @selenium.type "user_password_confirmation", "password" @selenium.click "user_terms" @selenium.click "user_submit" @selenium.wait_for_page_to_load "30000" @selenium.wait_for_page_to_load "5000" ... end 3. submit the form
  • 46. def test_new ... begin assert @selenium.is_text_present("Welcome to Spasibo. A winner is you!") rescue Test::Unit::AssertionFailedError @verification_errors << $! end begin assert_equal "http://spasibo.com/", @selenium.get_location rescue Test::Unit::AssertionFailedError @verification_errors << $! end end success message displayed
  • 47. def test_new ... begin assert @selenium.is_text_present("Welcome to Spasibo. A winner is you!") rescue Test::Unit::AssertionFailedError @verification_errors << $! end begin assert_equal "http://spasibo.com/", @selenium.get_location rescue Test::Unit::AssertionFailedError @verification_errors << $! end end user is redirected
  • 48. $ ruby -rubygems spasibo_test.rb Loaded suite spasibo_test Started . Finished in 10.559078 seconds. 1 tests, 3 assertions, 0 failures, 0 errors
  • 49. problems • dependent on a developer • still not understandable
  • 50. State: * No users exist in the system Steps: 1. Visit the registration page 2. Enter valid registration information 3. Submit the form Expectation: * I should be redirected to the home page * I should see a success message displayed
  • 51. can I make that executable?
  • 52.
  • 53. Behavior-Driven Development tool that speaks to domain experts first and code second
  • 54. $ gem install cucumber
  • 56. State: * No users exist in the system Steps: 1. Visit the registration page 2. Enter valid registration information 3. Submit the form Expectation: * I should be redirected to the home page * I should see a success message displayed
  • 57. State: * Given no users exist in the system Steps: 1. Visit the registration page 2. Enter valid registration information 3. Submit the form Expectation: * I should be redirected to the home page * I should see a success message displayed
  • 58. State: * Given no users exist in the system Steps: 1. When I visit the registration page 2. And I enter valid registration information 3. And I submit the form Expectation: * I should be redirected to the home page * I should see a success message displayed
  • 59. State: * Given no users exist in the system Steps: 1. When I visit the registration page 2. And I enter valid registration information 3. And I submit the form Expectation: * Then I should be redirected to the home page * And I should see a success message displayed
  • 60. State: * Given no users exist in the system Steps: 1. When I visit the registration page 2. And I enter valid registration information 3. And I submit the form Expectation: * Then I should be redirected to the home page * And I should see a success message displayed
  • 62. # features/registration.feature Feature: User Registration In order to identify users in the system Users must be able to log in Scenario: Successful Registration Given no users exist in the system When I visit the registration page And I enter valid registration information And I submit the form Then I should be redirected to the home page And I should see a success message displayed
  • 64. You can implement step definitions for undefined steps with these snippets: Given /^no users exist in the system$/ do pending end When /^I visit the registration page$/ do pending end When /^I enter valid registration information$/ do pending end When /^I submit the form$/ do pending end Then /^I should be redirected to the home page$/ do pending end Then /^I should see a success message displayed$/ do pending end
  • 65. # steps/registration_steps.rb Given /^no users exist in the system$/ do pending end When /^I visit the registration page$/ do pending end When /^I enter valid registration information$/ do pending end When /^I submit the form$/ do pending end Then /^I should be redirected to the home page$/ do pending end Then /^I should see a success message displayed$/ do pending end definitions
  • 66. # steps/registration_steps.rb Given /^no users exist in the system$/ do open "#{BASE_URL}/setup/clean_slate" end When /^I visit the registration page$/ do pending end When /^I enter valid registration information$/ do pending end When /^I submit the form$/ do pending end Then /^I should be redirected to the home page$/ do pending end Then /^I should see a success message displayed$/ do pending end state
  • 67. # steps/registration_steps.rb Given /^no users exist in the system$/ do open "#{BASE_URL}/setup/clean_slate" end When /^I visit the registration page$/ do @browser.open "/register" end When /^I enter valid registration information$/ do @browser.type "user_email", "user@host.com" @browser.type "user_password", "password" @browser.type "user_password_confirmation", "password" @browser.click "user_terms" end When /^I submit the form$/ do @browser.click "user_submit" @browser.wait_for_page_to_load end Then /^I should be redirected to the home page$/ do pending end Then /^I should see a success message displayed$/ do pending end steps
  • 68. # steps/registration_steps.rb Given /^no users exist in the system$/ do open "#{BASE_URL}/setup/clean_slate" end When /^I visit the registration page$/ do @browser.open "/register" end When /^I enter valid registration information$/ do @browser.type "user_email", "user@host.com" @browser.type "user_password", "password" @browser.type "user_password_confirmation", "password" @browser.click "user_terms" end When /^I submit the form$/ do @browser.click "user_submit" @browser.wait_for_page_to_load end Then /^I should be redirected to the home page$/ do assert_equal "#{BASE_URL}/", @browser.get_location end Then /^I should see a success message displayed$/ do assert @browser.is_text_present("Welcome to Spasibo. A winner is you!") end expectation
  • 69. $ cucumber registration.feature Feature: User Registration In order to identify users in the system Users must be able to log in Scenario: Successful registration # registration.feature:5 Given no users exist in the system # steps/registration_steps.rb:1 When I visit the registration page # steps/registration_steps.rb:5 And I enter valid registration information # steps/registration_steps.rb:9 And I submit the form # steps/registration_steps.rb:16 Then I should be redirected to the home page # steps/registration_steps.rb:21 And I should see a success message displayed # steps/registration_steps.rb:25 1 scenario (1 passed) 6 steps (6 passed)
  • 70. problems • dependent on a developer • no control over input data
  • 71. # registration.feature Feature: User Registration In order to identify users in the system Users must be able to log in Scenario: Successful registration Given no users exist in the system When I visit "/register" And I enter "user@host.com" for "user_email" And I enter "password" for "user_password" And I enter "password" for "user_password_confirmation" And I check the "user_terms" box And I click the "user_submit" button Then I should be redirected to "/" And I should see the message "Welcome to Spasibo. A winner is you!"
  • 72. You can implement step definitions for undefined steps with these snippets: Given /^no users exist in the system$/ do pending end When /^I visit "([^"]*)"$/ do |arg1| pending end When /^I enter "([^"]*)" for "([^"]*)"$/ do |arg1, arg2| pending end When /^I check the "([^"]*)" box$/ do |arg1| pending end When /^I click the "([^"]*)" button$/ do |arg1| pending end Then /^I should be redirected to "([^"]*)"$/ do |arg1| pending end Then /^I should see the message "([^"]*)"$/ do |arg1| pending end
  • 73. # steps/registration_steps.rb Given /^no users exist in the system$/ do pending end When /^I visit "([^"]*)"$/ do |arg1| pending end When /^I enter "([^"]*)" for "([^"]*)"$/ do |arg1, arg2| pending end When /^I check the "([^"]*)" box$/ do |arg1| pending end When /^I click the "([^"]*)" button$/ do |arg1| pending end Then /^I should be redirected to "([^"]*)"$/ do |arg1| pending end Then /^I should see the message "([^"]*)"$/ do |arg1| pending end definitions
  • 74. # steps/registration_steps.rb Given /^no users exist in the system$/ do open "#{BASE_URL}/setup/clean_slate" end When /^I visit "([^"]*)"$/ do |arg1| pending end When /^I enter "([^"]*)" for "([^"]*)"$/ do |arg1, arg2| pending end When /^I check the "([^"]*)" box$/ do |arg1| pending end When /^I click the "([^"]*)" button$/ do |arg1| pending end Then /^I should be redirected to "([^"]*)"$/ do |arg1| pending end Then /^I should see the message "([^"]*)"$/ do |arg1| pending end state
  • 75. # steps/registration_steps.rb Given /^no users exist in the system$/ do open "#{BASE_URL}/setup/clean_slate" end When /^I visit "([^"]*)"$/ do |path| @browser.open path end When /^I enter "([^"]*)" for "([^"]*)"$/ do |value, text_field_id| @browser.type text_field_id, value end When /^I check the "([^"]*)" box$/ do |checkbox_id| @browser.check checkbox_id end When /^I click the "([^"]*)" button$/ do |submit_button_id| @browser.click submit_button_id @browser.wait_for_page_to_load end Then /^I should be redirected to "([^"]*)"$/ do |arg1| pending end Then /^I should see the message "([^"]*)"$/ do |arg1| pending end steps
  • 76. # steps/registration_steps.rb Given /^no users exist in the system$/ do open "#{BASE_URL}/setup/clean_slate" end When /^I visit "([^"]*)"$/ do |path| @browser.open path end When /^I enter "([^"]*)" for "([^"]*)"$/ do |value, text_field_id| @browser.type text_field_id, value end When /^I check the "([^"]*)" box$/ do |checkbox_id| @browser.check checkbox_id end When /^I click the "([^"]*)" button$/ do |submit_button_id| @browser.click submit_button_id @browser.wait_for_page_to_load end Then /^I should be redirected to "([^"]*)"$/ do |path| assert_equal "#{BASE_URL}#{path}", @browser.get_location end Then /^I should see the message "([^"]*)"$/ do |message| assert @browser.is_text_present(message) end expectation
  • 77. $ cucumber registration.feature Feature: User Registration In order to identify users in the system Users must be able to log in Scenario: Successful registration # registration.feature:7 Given no users exist in the system # steps/registration_steps.rb:1 When I visit "/register" # steps/registration_steps.rb:5 And I enter "user@host.com" for "user_email" # steps/registration_steps.rb:9 And I enter "password" for "user_password" # steps/registration_steps.rb:9 And I enter "password" for "user_password_confirmation" # steps/registration_steps.rb:9 And I check the "user_terms" box # steps/registration_steps.rb:13 And I click the "user_submit" button # steps/registration_steps.rb:17 Then I should be redirected to "/" # steps/registration_steps.rb:22 And I should see the message "Welcome to Spasibo. A winner is you!" # steps/registration_steps.rb:26 1 scenario (1 passed) 9 steps (9 passed)
  • 79. Scenario: No data supplied Given no users exist in the system When I visit "/register" And I click the "user_submit" button Then I should be redirected to "/register" And I should see the message "NYET! A FAIL IS YOU" And I should see the message "Email can't be blank" And I should see the message "Terms must be accepted" Scenario: Password not confirmed Given no users exist in the system When I visit "/register" And I enter "user@host.com" for "user_email" And I enter "password" for "user_password" And I enter "drowssap" for "user_password_confirmation" And I check the "user_terms" box And I click the "user_submit" button Then I should be redirected to "/register" And I should see the message "NYET! A FAIL IS YOU" And I should see the message "Password doesn't match confirmation"
  • 80. Scenario: Successful registration with alternate data Given no users exist in the system When I visit "/register" And I enter "patrick@viget.com" for "user_email" And I enter "password123" for "user_password" And I enter "password123" for "user_password_confirmation" And I check the "user_terms" box And I click the "user_submit" button Then I should be redirected to "/" And I should see the message "Welcome to Spasibo. A winner is you!"
  • 81. remove duplication image: haakseth @ flickr
  • 82. Scenario: Successful registration Given no users exist in the system When I visit "/register" And I enter "user@host.com" for "user_email" And I enter "password" for "user_password" And I enter "password" for "user_password_confirmation" And I check the "user_terms" box And I click the "user_submit" button Then I should be redirected to "/" And I should see the message "Welcome to Spasibo. A winner is you!"
  • 83. Scenario Outline: Successful registration Given no users exist in the system When I visit "/register" And I enter "user@host.com" for "user_email" And I enter "password" for "user_password" And I enter "password" for "user_password_confirmation" And I check the "user_terms" box And I click the "user_submit" button Then I should be redirected to "/" And I should see the message "Welcome to Spasibo. A winner is you!"
  • 84. Scenario Outline: Successful registration Given no users exist in the system When I visit "/register" And I enter "<email>" for "user_email" And I enter "<password>" for "user_password" And I enter "<password_confirmation>" for "user_password_confirmation" And I check the "user_terms" box And I click the "user_submit" button Then I should be redirected to "/" And I should see the message "Welcome to Spasibo. A winner is you!"
  • 85. Scenario Outline: Successful registration Given no users exist in the system When I visit "/register" And I enter "<email>" for "user_email" And I enter "<password>" for "user_password" And I enter "<password_confirmation>" for "user_password_confirmation" And I check the "user_terms" box And I click the "user_submit" button Then I should be redirected to "/" And I should see the message "Welcome to Spasibo. A winner is you!" Examples: | email | password | password_confirmation | | user@host.com | password | password | | patrick@viget.com | password123 | password123 |
  • 86. $ cucumber registration.feature Feature: User registration In order to identify users in the system Users must be able to log in Scenario Outline: Successful Registration # registration.feature:7 Given no users exist in the system # steps/registration_steps.rb:1 When I visit "/register" # steps/registration_steps.rb:5 And I enter "<email>" for "user_email" # steps/registration_steps.rb:9 And I enter "<password>" for "user_password" # steps/registration_steps.rb:9 And I enter "<password_confirmation>" for "user_password_confirmation" # steps/registration_steps.rb:9 And I check the "user_terms" box # steps/registration_steps.rb:13 And I click the "user_submit" button # steps/registration_steps.rb:17 Then I should be redirected to "/" # steps/registration_steps.rb:22 And I should see the message "Welcome to Spasibo. A winner is you!" # steps/registration_steps.rb:26 Examples: | email | password | password_confirmation | | user@host.com | password | password | | patrick@viget.com | password123 | password123 | 2 scenarios (2 passed) 18 steps (18 passed)
  • 89. Scenario: Duplicate email address Given a user exists in the system with the email "user@host.com" When I visit "/register" And I enter valid registration information And I enter "user@host.com" for "user_email" And I click the "user_submit" button Then I should be redirected to "/register" And I should see the message "Email has already been taken" refactor
  • 90. Scenario: Duplicate email address Given a user exists in the system with the email "user@host.com" When I visit "/register" And I enter valid registration information And I enter "user@host.com" for "user_email" And I click the "user_submit" button Then I should be redirected to "/register" And I should see the message "Email has already been taken" refactor
  • 91. Given /^a user exists in the system with the email "([^"]*)"$/ do |email| Given 'no users exist in the system' When 'I visit "/register"' When 'I enter valid registration information' When 'I enter "' + email + '" for "user_email"' When 'I click the "user_submit" button' end When /^I enter valid registration information$/ do When 'I enter "user@host.com" for "user_email"' When 'I enter "password" for "user_password"' When 'I enter "password" for "user_password_confirmation"' When 'I check the "user_terms" box' end refactor
  • 92. Scenario: Duplicate email address # registration.feature:51 Given a user exists in the system with the email "user@host.com" # steps/registration_steps.rb:30 When I visit "/register" # steps/registration_steps.rb:5 And I enter valid registration information # steps/registration_steps.rb:38 And I enter "user@host.com" for "user_email" # steps/registration_steps.rb:9 And I click the "user_submit" button # steps/registration_steps.rb:17 Then I should be redirected to "/register" # steps/registration_steps.rb:22 And I should see the message "Email has already been taken" # steps/registration_steps.rb:26
  • 93. $ cucumber registration.feature --name "Success" Feature: User Registration In order to identify users in the system Users must be able to log in Scenario: Successful registration # registration.feature:7 Given no users exist in the system # steps/registration_steps.rb:1 When I visit "/register" # steps/registration_steps.rb:5 And I enter "user@host.com" for "user_email" # steps/registration_steps.rb:9 And I enter "password" for "user_password" # steps/registration_steps.rb:9 And I enter "password" for "user_password_confirmation" # steps/registration_steps.rb:9 And I check the "user_terms" box # steps/registration_steps.rb:13 And I click the "user_submit" button # steps/registration_steps.rb:17 Then I should be redirected to "/" # steps/registration_steps.rb:22 And I should see the message "Welcome to Spasibo. A winner is you!" # steps/registration_steps.rb:26 Scenario: Successful registration with alternate data # registration.feature:18 Given no users exist in the system # steps/registration_steps.rb:1 When I visit "/register" # steps/registration_steps.rb:5 And I enter "patrick@viget.com" for "user_email" # steps/registration_steps.rb:9 And I enter "password123" for "user_password" # steps/registration_steps.rb:9 And I enter "password123" for "user_password_confirmation" # steps/registration_steps.rb:9 And I check the "user_terms" box # steps/registration_steps.rb:13 And I click the "user_submit" button # steps/registration_steps.rb:17 Then I should be redirected to "/" # steps/registration_steps.rb:22 And I should see the message "Welcome to Spasibo. A winner is you!" # steps/registration_steps.rb:26 2 scenarios (2 passed) 18 steps (18 passed) run by name
  • 94. @slow Scenario: Duplicate email address Given a user exists in the system with the email "user@host.com" When I visit "/register" And I enter valid registration information And I enter "user@host.com" for "user_email" And I click the "user_submit" button Then I should be redirected to "/register" And I should see the message "Email has already been taken" tagging
  • 95. $ cucumber registration.feature --tags @slow Feature: User Registration In order to identify users in the system Users must be able to log in @slow Scenario: Duplicate email address # registration.feature:51 Given a user exists in the system with the email "user@host.com" # steps/registration_steps.rb:30 When I visit "/register" # steps/registration_steps.rb:5 And I enter valid registration information # steps/registration_steps.rb:38 And I enter "user@host.com" for "user_email" # steps/registration_steps.rb:9 And I click the "user_submit" button # steps/registration_steps.rb:17 Then I should be redirected to "/register" # steps/registration_steps.rb:22 And I should see the message "Email has already been taken" # steps/registration_steps.rb:26 1 scenario (1 passed) 7 steps (7 passed) run by tag
  • 99. continuous integration integration?
  • 100. Resources • Selenium: http://seleniumhq.org/ • Cucumber: http://cukes.info/ • Slides / Code: http://github.com/reagent/nlt Contact • patrick.reagan@viget.com • http://twitter.com/reagent image: nomeacuerdo @ flickr