SlideShare uma empresa Scribd logo
1 de 44
Cucumber and
                             Capybara
                            A commons case study




Dienstag, 14. Februar 12
old vs new

                                                 old           new

                              testing-
                                             test-unit v1    cucumber
                            framework


                           browser-driver pure selenium v1   capybara




Dienstag, 14. Februar 12
vs




Dienstag, 14. Februar 12
Plain text scenarios
                                       Step definitions
                    with features




                                        shamelessly stolen from cukes.info
Dienstag, 14. Februar 12
test-unit: naming



                                  +

     class Test999999CruftySessionSystemTest < Test::Unit::TestCase
     def test_00_bork
     ! ...
     end


Dienstag, 14. Februar 12
cucumber: naming

   Feature: Groups

   Scenario: As a user I can join an existing group

         ...




Dienstag, 14. Februar 12
test-unit: tagging

       Shared code


       Smoke tests
       System tests




Dienstag, 14. Februar 12
cucumber: tagging



Actual
 tags



Dienstag, 14. Februar 12
test-output: test-unit




Dienstag, 14. Februar 12
test-output: cucumber




Dienstag, 14. Februar 12
test-output: cucumber




Dienstag, 14. Februar 12
test-unit: setup

                     • setup/teardown
                     • in v2: self.startup / self.shutdown
                           (no easy access to instance variables)
                     • no predefined integration with selenium


Dienstag, 14. Februar 12
cucumber: setup
                     • Scenario backgrounds
                     • Scenario hooks
                      • Before/After/Around
                             (all of them can use tags)
                           • Fully integrated with capybara
                             (@selenium, @webkit, @...)


            https://github.com/cucumber/cucumber/wiki/Hooks
Dienstag, 14. Februar 12
test-unit: code

                def test_01_create_basic_webform
                    Log.logger.info("Starting test_01_create_basic_webform")
                    @browser.open('/')
                    login(@user.name, @user.password)
                    self.make_sure_webform_is_enabled()
                    webformmgr = WebformManager.new(@browser)
                    @browser.open("#{webformmgr.create_webform_url}")




Dienstag, 14. Februar 12
cucumber code:
                                features
      Feature: Blog

          Background:
            Given a fresh commons installation
            Given a user named "derpington" with the password "zomgbbq"
            Given I am logged in as "derpington" with the password "zomgbbq"
            Given I have joined the default group

          Scenario Outline: As a user I can create a blog post
            Given I create a blog entry with the title "<TitleText>" and the body "<BodyText>"
            Then I should see a blog entry with "<BodyText>" in it
            And I should see a headline with "<TitleText>" in it

              Examples:
                | TitleText       | BodyText                      |
                | test title uno | This is a test body            |
                | Nön ÄSCîî tïtlé | uʍop ǝpısdn ɯ,ı 'ǝɯ ʇɐ ʞoo‫ן‬    |




Dienstag, 14. Februar 12
cucumber code:
                                features
      Feature: Blog

          Background:
            Given a fresh commons installation
            Given a user named "derpington" with the password "zomgbbq"
            Given I am logged in as "derpington" with the password "zomgbbq"
            Given I have joined the default group

          Scenario Outline: As a user I can create a blog post
            Given I create a blog entry with the title "<TitleText>" and the body "<BodyText>"
            Then I should see a blog entry with "<BodyText>" in it
            And I should see a headline with "<TitleText>" in it

              Examples:
                | TitleText       | BodyText                      |
                | test title uno | This is a test body            |
                | Nön ÄSCîî tïtlé | uʍop ǝpısdn ɯ,ı 'ǝɯ ʇɐ ʞoo‫ן‬    |




Dienstag, 14. Februar 12
cucumber code:
                           step definitions




Dienstag, 14. Februar 12
cucumber code:
                           step definitions




Dienstag, 14. Februar 12
cucumber code:
                           step definitions
                               Simple ones


     And /^I edit the current content$/ do
       within(:css, 'div.content-tabs-inner'){ click_link('Edit') }
     end




Dienstag, 14. Februar 12
cucumber code:
                           step definitions
                               Variables

     Then /^I should see the image ['"](.*)['"]$/ do |image_url|
       page.should have_css("img[src='#{image_url}']")
     end

     And /I should see a link with the text ['"](.*)['"]/ do |text|
       page.should have_xpath("//a[contains(text(), text)]")
     end




Dienstag, 14. Februar 12
cucumber:
                           step definitions
                              Combining steps


      And /^I add the comment ["'](.*)["']$/ do |text|
        step "I click on 'Comment'"
        step 'I disable the rich-text editor'
        step "I fill in 'Comment' with '#{text}'"
        step "I press 'Save'"
      end




Dienstag, 14. Februar 12
cucumber:
                           step definitions
                                        Advanced steps
  #The ?: tells us that we don't want to capture that part in a variable
  When /^(?:I am|I'm|I) (?:on|viewing|looking at|look at|go to|visit|visiting) ['"]?([^"']*)["']?$/ do |path|
    translation_hash = {
      "the status report page" => '/admin/reports/status',
      "the blog posts page" => '/content/blogs',
      "the blog post page" => '/content/blogs',
      [...]
      'the bookmarks page' => '/bookmarks',
    }
    if translation_hash.key?(path)
      visit(translation_hash[path])
    else
      if path.start_with?("/")
        visit(path)
      else
        raise "I don't know how to go to this path: #{path.inspect}."
      end
    end
  end




Dienstag, 14. Februar 12
File Layout
                                      Features:
                                The test descriptions



                                    Step definitions:
                                  Mapping text to code

                                           env.rb:
                                Setting up the environment
                                      Gemfile: Which gems?
                                    Gemfile.lock Which versions?
                                       Rakefile: Misc tasks
Dienstag, 14. Februar 12
File Layout: env.rb?
                           env.rb does these things:

                 •         it loads Bundler

                 •         it loads Capybara

                            •   ... and sets the default driver

                 •         It loads the capybara-screenshot gem

                 •         it launches XVFB

                 •         it populates the $site_capabilities hash

                            •   determines weather or not we have the devel
                                module available
Dienstag, 14. Februar 12
General usage

                     • Run one feature:
                           $ cucumber features/blog.feature
                     • Run the specific scenario at line 42:
                           $ cucumber features/blog.feature:42




Dienstag, 14. Februar 12
Other nifty things
                     •     cucumber --dry-run:
                           Allows to check for missing step definitions

                     •     cucumber --format usage:
                           Allows to figure out which steps get called the most or
                           which steps don’t get called. Also tells you which steps take
                           the longest

                     •     cucumber --format rerun:
                           Saves failed tests to rerun.txt and allows to rerun just
                           those failed tests

                     •     cucumber --tags @wip:
                           Will only run tests tagged @wip.
                           Also possible: “--tags ~@wip” to NOT run them


Dienstag, 14. Februar 12
Code smells
                                          (we have some of those)


                     •     Try to abstract the actual implementation of the steps out
                           of the scenarios

                           •   Good:
                               “Given I am logged in as an administrator”

                           •   Bad:
                               Given I go to “/login”
                               And I enter “admin” in the “username” field
                               And I enter “foobar” in the “password” field
                               [...]




Dienstag, 14. Februar 12
Capybara
                               vs
                           Selenium




Dienstag, 14. Februar 12
Capybara and Selenium
                           Selenium
                           • An API
                           • Bindings for actual browsers (IE, Chrome, FF, ...)
                           Capybara:
                           • An API
                           • A big set of tests
                           Capybara drivers:
                           • Remote controls for browsers and browser
                             simulators that can be “plugged into”
                             Capybara, usually 3rd party projects
Dienstag, 14. Februar 12
Selenium: setup
                     • Selenium 1 needs:
                      • An installed browser
                      • A running Selenium RC (java app)
                      • An X server
                     • With Saucelabs it needs:
                      • A running Sauceconnect process
Dienstag, 14. Februar 12
Problems with
                              Selenium
                     • Slow: Launching Firefox with a new profile
                     • Slow: Adding Webdriver extension
                     • Slow: Communicates over JSON/REST
                     • Bad: No Console.log output
                     • Bad: JS Errors are invisible
                     • Bad: Selenium 1 has limitations
                     • Bad: No proper implicit waits
Dienstag, 14. Februar 12
Capybara: setup
                    Capybara needs:
                    • A driver
                    Capybara drivers need:
                    •      selenium webdriver: X Server
                    •      headless webkit: X Server, QT
                    •      poltergeist: X Server, the phantomjs binary
                    •      akephalos: java
                    •      mechanize: no dependencies
Dienstag, 14. Februar 12
Capybara: drivers
                             Javascript +
                                            Speed   Stability
                                DOM
          Webdriver               10         7          6
                                                     (recently)

            Headless
                                  9          9          9
            Webkit
          Poltergeist             9          8          5
                              (PhantomJS)


          Akephalos               6          6          8
                              (HTML Unit)

          Mechanize               0          10        10

Dienstag, 14. Februar 12
Capybara API: clicking

                            click_link('id-of-link')
                            click_link('Link Text')
                            click_button('Save')
                            click_on('Link Text')
                            click_on('Button Value')




Dienstag, 14. Februar 12
Capybara API: forms

     fill_in('First Name', :with => 'John')
     fill_in('Password', :with => 'Seekrit')
     fill_in('Description', :with => 'Really Long Text...')
     choose('A Radio Button')
     check('A Checkbox')
     uncheck('A Checkbox')
     attach_file('Image', '/path/to/image.jpg')
     select('Option', :from => 'Select Box')




Dienstag, 14. Februar 12
Capybara API: querying

             page.has_selector?('table tr')
             page.has_selector?(:xpath, '//table/tr')
             page.has_no_selector?(:content)

             page.has_xpath?('//table/tr')
             page.has_css?('table tr.foo')
             page.has_content?('foo')




Dienstag, 14. Februar 12
Capybara API: rspec
                               matchers
          page.should have_selector('table tr')
          page.should have_selector(:xpath, '//table/tr')
          page.should have_no_selector(:content)

          page.should have_xpath('//table/tr')
          page.should have_css('table tr.foo')
          page.should have_content('foo')




Dienstag, 14. Februar 12
Capybara API: finding

                      find_field('First Name').value
                      find_link('Hello').visible?
                      find_button('Send').click

                      find(:xpath, "//table/tr").click
                      find("#overlay").find("h1").click
                      all('a').each { |a| a[:href] }




Dienstag, 14. Februar 12
Capybara API: scoping

                      find('#navigation').click_link('Home')
                      find('#navigation').should have_button('Sign out')



                      within("li#employee") do
                        fill_in 'Name', :with => 'Jimmy'
                      end

                      within(:xpath, "//li[@id='employee']") do
                        fill_in 'Name', :with => 'Jimmy'
                      end




Dienstag, 14. Februar 12
Capybara API: AJAX?

                           Capybara.default_wait_time = 5


                           click_link('foo')
                           #Ajax stuff happens that adds “bar”
                           click_link('bar')
                           #Ajax stuff happens that adds “baz”
                           page.should have_content('baz')




Dienstag, 14. Februar 12
Capybara:
                           Heads up for Ajax!

           Bad               !page.has_xpath?('a')

       Good                  page.has_no_xpath?('a')




Dienstag, 14. Februar 12
In Selenium: AJAX :(

                 wait = Selenium::WebDriver::Wait.new(:timeout => 5)
                 btn = wait.until {
                     @browser.find_element(:xpath => @contmgr.sort_asc)
                 }




Dienstag, 14. Februar 12
Note: PHP
                                 Behat
                            Cucumber in PHP
                             http://behat.org/

                                   Mink
                             Capybara in PHP
                           http://mink.behat.org/

     Capybara Cucumber                       Behat   Mink

Dienstag, 14. Februar 12
Any questions?




Dienstag, 14. Februar 12

Mais conteúdo relacionado

Mais procurados

Design patterns revisited with PHP 5.3
Design patterns revisited with PHP 5.3Design patterns revisited with PHP 5.3
Design patterns revisited with PHP 5.3
Fabien Potencier
 

Mais procurados (20)

Migraine Drupal - syncing your staging and live sites
Migraine Drupal - syncing your staging and live sitesMigraine Drupal - syncing your staging and live sites
Migraine Drupal - syncing your staging and live sites
 
Testing in AngularJS
Testing in AngularJSTesting in AngularJS
Testing in AngularJS
 
Geb with spock
Geb with spockGeb with spock
Geb with spock
 
Acceptance testing with Geb
Acceptance testing with GebAcceptance testing with Geb
Acceptance testing with Geb
 
DevQA: make your testers happier with Groovy, Spock and Geb
DevQA: make your testers happier with Groovy, Spock and GebDevQA: make your testers happier with Groovy, Spock and Geb
DevQA: make your testers happier with Groovy, Spock and Geb
 
20160905 - BrisJS - nightwatch testing
20160905 - BrisJS - nightwatch testing20160905 - BrisJS - nightwatch testing
20160905 - BrisJS - nightwatch testing
 
Automated Testing with Ruby
Automated Testing with RubyAutomated Testing with Ruby
Automated Testing with Ruby
 
Taming Functional Web Testing with Spock and Geb
Taming Functional Web Testing with Spock and GebTaming Functional Web Testing with Spock and Geb
Taming Functional Web Testing with Spock and Geb
 
Night Watch with QA
Night Watch with QANight Watch with QA
Night Watch with QA
 
RSpec 2 Best practices
RSpec 2 Best practicesRSpec 2 Best practices
RSpec 2 Best practices
 
Django Introduction & Tutorial
Django Introduction & TutorialDjango Introduction & Tutorial
Django Introduction & Tutorial
 
Design patterns revisited with PHP 5.3
Design patterns revisited with PHP 5.3Design patterns revisited with PHP 5.3
Design patterns revisited with PHP 5.3
 
Jumping Into WordPress Plugin Programming
Jumping Into WordPress Plugin ProgrammingJumping Into WordPress Plugin Programming
Jumping Into WordPress Plugin Programming
 
Das Frontend richtig Testen – mit Jest @Developer Week 2018
Das Frontend richtig Testen – mit Jest @Developer Week 2018Das Frontend richtig Testen – mit Jest @Developer Week 2018
Das Frontend richtig Testen – mit Jest @Developer Week 2018
 
React Native - Workshop
React Native - WorkshopReact Native - Workshop
React Native - Workshop
 
JavaScript : A trending scripting language
JavaScript : A trending scripting languageJavaScript : A trending scripting language
JavaScript : A trending scripting language
 
Reliable acceptance testing
Reliable acceptance testingReliable acceptance testing
Reliable acceptance testing
 
Getting big without getting fat, in perl
Getting big without getting fat, in perlGetting big without getting fat, in perl
Getting big without getting fat, in perl
 
AngularJS Unit Testing
AngularJS Unit TestingAngularJS Unit Testing
AngularJS Unit Testing
 
Jest: Frontend Testing leicht gemacht @EnterJS2018
Jest: Frontend Testing leicht gemacht @EnterJS2018Jest: Frontend Testing leicht gemacht @EnterJS2018
Jest: Frontend Testing leicht gemacht @EnterJS2018
 

Destaque

Behavior Driven Development with Cucumber
Behavior Driven Development with CucumberBehavior Driven Development with Cucumber
Behavior Driven Development with Cucumber
Brandon Keepers
 

Destaque (20)

Automated Acceptance Tests & Tool choice
Automated Acceptance Tests & Tool choiceAutomated Acceptance Tests & Tool choice
Automated Acceptance Tests & Tool choice
 
Testing Microservices with a Citrus twist
Testing Microservices with a Citrus twistTesting Microservices with a Citrus twist
Testing Microservices with a Citrus twist
 
Bdd (Behavior Driven Development)
Bdd (Behavior Driven Development)Bdd (Behavior Driven Development)
Bdd (Behavior Driven Development)
 
Testing Java EE apps with Arquillian
Testing Java EE apps with ArquillianTesting Java EE apps with Arquillian
Testing Java EE apps with Arquillian
 
Arquillian & Citrus
Arquillian & CitrusArquillian & Citrus
Arquillian & Citrus
 
Workshop calabash appium
Workshop calabash appiumWorkshop calabash appium
Workshop calabash appium
 
Pruebas funcionales de Software
Pruebas funcionales de SoftwarePruebas funcionales de Software
Pruebas funcionales de Software
 
Rspec and Capybara Intro Tutorial at RailsConf 2013
Rspec and Capybara Intro Tutorial at RailsConf 2013Rspec and Capybara Intro Tutorial at RailsConf 2013
Rspec and Capybara Intro Tutorial at RailsConf 2013
 
Three Uses Of JIRA Beyond Bug Tracking
Three Uses Of JIRA Beyond Bug TrackingThree Uses Of JIRA Beyond Bug Tracking
Three Uses Of JIRA Beyond Bug Tracking
 
TestLink introduction
TestLink introductionTestLink introduction
TestLink introduction
 
Introduction To Confluence
Introduction To ConfluenceIntroduction To Confluence
Introduction To Confluence
 
Jira as a Tool for Test Management
Jira as a Tool for Test ManagementJira as a Tool for Test Management
Jira as a Tool for Test Management
 
Using JIRA Software for Issue Tracking
Using JIRA Software for Issue TrackingUsing JIRA Software for Issue Tracking
Using JIRA Software for Issue Tracking
 
Introduction To Jira
Introduction To JiraIntroduction To Jira
Introduction To Jira
 
Behavior Driven Development with Cucumber
Behavior Driven Development with CucumberBehavior Driven Development with Cucumber
Behavior Driven Development with Cucumber
 
Story Testing Approach for Enterprise Applications using Selenium Framework
Story Testing Approach for Enterprise Applications using Selenium FrameworkStory Testing Approach for Enterprise Applications using Selenium Framework
Story Testing Approach for Enterprise Applications using Selenium Framework
 
Next level of Appium
Next level of AppiumNext level of Appium
Next level of Appium
 
Automate you Appium test like a pro!
Automate you Appium test like a pro!Automate you Appium test like a pro!
Automate you Appium test like a pro!
 
Gerrit is Getting Native with RPM, Deb and Docker
Gerrit is Getting Native with RPM, Deb and DockerGerrit is Getting Native with RPM, Deb and Docker
Gerrit is Getting Native with RPM, Deb and Docker
 
Introduction to Bdd and cucumber
Introduction to Bdd and cucumberIntroduction to Bdd and cucumber
Introduction to Bdd and cucumber
 

Semelhante a Lunch and learn: Cucumber and Capybara

Gradle - time for a new build
Gradle - time for a new buildGradle - time for a new build
Gradle - time for a new build
Igor Khotin
 
Practicing Continuous Deployment
Practicing Continuous DeploymentPracticing Continuous Deployment
Practicing Continuous Deployment
zeeg
 

Semelhante a Lunch and learn: Cucumber and Capybara (20)

Disconnecting the Database with ActiveRecord
Disconnecting the Database with ActiveRecordDisconnecting the Database with ActiveRecord
Disconnecting the Database with ActiveRecord
 
Behat dpc12
Behat dpc12Behat dpc12
Behat dpc12
 
Gradle - time for another build
Gradle - time for another buildGradle - time for another build
Gradle - time for another build
 
Acceptance tests
Acceptance testsAcceptance tests
Acceptance tests
 
Standing on the shoulders of giants with JRuby
Standing on the shoulders of giants with JRubyStanding on the shoulders of giants with JRuby
Standing on the shoulders of giants with JRuby
 
Forget Grunt and Gulp! Webpack and NPM rule them all!
Forget Grunt and Gulp! Webpack and NPM rule them all!Forget Grunt and Gulp! Webpack and NPM rule them all!
Forget Grunt and Gulp! Webpack and NPM rule them all!
 
Unit Testing Lots of Perl
Unit Testing Lots of PerlUnit Testing Lots of Perl
Unit Testing Lots of Perl
 
A jar-nORM-ous Task
A jar-nORM-ous TaskA jar-nORM-ous Task
A jar-nORM-ous Task
 
Gradle talk, Javarsovia 2010
Gradle talk, Javarsovia 2010Gradle talk, Javarsovia 2010
Gradle talk, Javarsovia 2010
 
Sw install with_without_docker
Sw install with_without_dockerSw install with_without_docker
Sw install with_without_docker
 
How I hack on puppet modules
How I hack on puppet modulesHow I hack on puppet modules
How I hack on puppet modules
 
ASU DUG - SVN and CVS
ASU DUG - SVN and CVSASU DUG - SVN and CVS
ASU DUG - SVN and CVS
 
Gradle - time for a new build
Gradle - time for a new buildGradle - time for a new build
Gradle - time for a new build
 
Create ReactJS Component & publish as npm package
Create ReactJS Component & publish as npm packageCreate ReactJS Component & publish as npm package
Create ReactJS Component & publish as npm package
 
2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps
2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps
2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps
 
Automating WordPress Theme Development
Automating WordPress Theme DevelopmentAutomating WordPress Theme Development
Automating WordPress Theme Development
 
Ruby meetup 7_years_in_testing
Ruby meetup 7_years_in_testingRuby meetup 7_years_in_testing
Ruby meetup 7_years_in_testing
 
Cucumber testing
Cucumber testingCucumber testing
Cucumber testing
 
Cucumber testing
Cucumber testingCucumber testing
Cucumber testing
 
Practicing Continuous Deployment
Practicing Continuous DeploymentPracticing Continuous Deployment
Practicing Continuous Deployment
 

Mais de Marc Seeger

Communitygetriebe Android Systementwicklung
Communitygetriebe Android SystementwicklungCommunitygetriebe Android Systementwicklung
Communitygetriebe Android Systementwicklung
Marc Seeger
 
Eventdriven I/O - A hands on introduction
Eventdriven I/O - A hands on introductionEventdriven I/O - A hands on introduction
Eventdriven I/O - A hands on introduction
Marc Seeger
 
Key-Value Stores: a practical overview
Key-Value Stores: a practical overviewKey-Value Stores: a practical overview
Key-Value Stores: a practical overview
Marc Seeger
 
Security In Dect
Security In DectSecurity In Dect
Security In Dect
Marc Seeger
 

Mais de Marc Seeger (17)

DevOps Boston - Heartbleed at Acquia
DevOps Boston - Heartbleed at AcquiaDevOps Boston - Heartbleed at Acquia
DevOps Boston - Heartbleed at Acquia
 
The current state of anonymous filesharing
The current state of anonymous filesharingThe current state of anonymous filesharing
The current state of anonymous filesharing
 
NoSQL databases
NoSQL databasesNoSQL databases
NoSQL databases
 
building blocks of a scalable webcrawler
building blocks of a scalable webcrawlerbuilding blocks of a scalable webcrawler
building blocks of a scalable webcrawler
 
Communitygetriebe Android Systementwicklung
Communitygetriebe Android SystementwicklungCommunitygetriebe Android Systementwicklung
Communitygetriebe Android Systementwicklung
 
Eventdriven I/O - A hands on introduction
Eventdriven I/O - A hands on introductionEventdriven I/O - A hands on introduction
Eventdriven I/O - A hands on introduction
 
Alternative Infrastucture
Alternative InfrastuctureAlternative Infrastucture
Alternative Infrastucture
 
Communitygetriebene Android Systemerweiterungen
Communitygetriebene Android SystemerweiterungenCommunitygetriebene Android Systemerweiterungen
Communitygetriebene Android Systemerweiterungen
 
Key-Value Stores: a practical overview
Key-Value Stores: a practical overviewKey-Value Stores: a practical overview
Key-Value Stores: a practical overview
 
ZFS
ZFSZFS
ZFS
 
The Dirac Video CoDec
The Dirac Video CoDecThe Dirac Video CoDec
The Dirac Video CoDec
 
Anonimität - Konzepte und Werkzeuge
Anonimität - Konzepte und WerkzeugeAnonimität - Konzepte und Werkzeuge
Anonimität - Konzepte und Werkzeuge
 
Security In Dect
Security In DectSecurity In Dect
Security In Dect
 
Social Media in der Unternehmenskommunikation
Social Media in der UnternehmenskommunikationSocial Media in der Unternehmenskommunikation
Social Media in der Unternehmenskommunikation
 
xDSL, DSLAM & CO
xDSL, DSLAM & COxDSL, DSLAM & CO
xDSL, DSLAM & CO
 
Ruby Xml Mapping
Ruby Xml MappingRuby Xml Mapping
Ruby Xml Mapping
 
HdM Stuttgart Präsentationstag PPTP VPN WLAN Update
HdM Stuttgart Präsentationstag PPTP VPN WLAN UpdateHdM Stuttgart Präsentationstag PPTP VPN WLAN Update
HdM Stuttgart Präsentationstag PPTP VPN WLAN Update
 

Último

Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 

Último (20)

Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 

Lunch and learn: Cucumber and Capybara

  • 1. Cucumber and Capybara A commons case study Dienstag, 14. Februar 12
  • 2. old vs new old new testing- test-unit v1 cucumber framework browser-driver pure selenium v1 capybara Dienstag, 14. Februar 12
  • 4. Plain text scenarios Step definitions with features shamelessly stolen from cukes.info Dienstag, 14. Februar 12
  • 5. test-unit: naming + class Test999999CruftySessionSystemTest < Test::Unit::TestCase def test_00_bork ! ... end Dienstag, 14. Februar 12
  • 6. cucumber: naming Feature: Groups Scenario: As a user I can join an existing group ... Dienstag, 14. Februar 12
  • 7. test-unit: tagging Shared code Smoke tests System tests Dienstag, 14. Februar 12
  • 12. test-unit: setup • setup/teardown • in v2: self.startup / self.shutdown (no easy access to instance variables) • no predefined integration with selenium Dienstag, 14. Februar 12
  • 13. cucumber: setup • Scenario backgrounds • Scenario hooks • Before/After/Around (all of them can use tags) • Fully integrated with capybara (@selenium, @webkit, @...) https://github.com/cucumber/cucumber/wiki/Hooks Dienstag, 14. Februar 12
  • 14. test-unit: code def test_01_create_basic_webform     Log.logger.info("Starting test_01_create_basic_webform")     @browser.open('/')     login(@user.name, @user.password)     self.make_sure_webform_is_enabled()     webformmgr = WebformManager.new(@browser)     @browser.open("#{webformmgr.create_webform_url}") Dienstag, 14. Februar 12
  • 15. cucumber code: features Feature: Blog Background: Given a fresh commons installation Given a user named "derpington" with the password "zomgbbq" Given I am logged in as "derpington" with the password "zomgbbq" Given I have joined the default group Scenario Outline: As a user I can create a blog post Given I create a blog entry with the title "<TitleText>" and the body "<BodyText>" Then I should see a blog entry with "<BodyText>" in it And I should see a headline with "<TitleText>" in it Examples: | TitleText | BodyText | | test title uno | This is a test body | | Nön ÄSCîî tïtlé | uʍop ǝpısdn ɯ,ı 'ǝɯ ʇɐ ʞoo‫ן‬ | Dienstag, 14. Februar 12
  • 16. cucumber code: features Feature: Blog Background: Given a fresh commons installation Given a user named "derpington" with the password "zomgbbq" Given I am logged in as "derpington" with the password "zomgbbq" Given I have joined the default group Scenario Outline: As a user I can create a blog post Given I create a blog entry with the title "<TitleText>" and the body "<BodyText>" Then I should see a blog entry with "<BodyText>" in it And I should see a headline with "<TitleText>" in it Examples: | TitleText | BodyText | | test title uno | This is a test body | | Nön ÄSCîî tïtlé | uʍop ǝpısdn ɯ,ı 'ǝɯ ʇɐ ʞoo‫ן‬ | Dienstag, 14. Februar 12
  • 17. cucumber code: step definitions Dienstag, 14. Februar 12
  • 18. cucumber code: step definitions Dienstag, 14. Februar 12
  • 19. cucumber code: step definitions Simple ones And /^I edit the current content$/ do   within(:css, 'div.content-tabs-inner'){ click_link('Edit') } end Dienstag, 14. Februar 12
  • 20. cucumber code: step definitions Variables Then /^I should see the image ['"](.*)['"]$/ do |image_url|   page.should have_css("img[src='#{image_url}']") end And /I should see a link with the text ['"](.*)['"]/ do |text|   page.should have_xpath("//a[contains(text(), text)]") end Dienstag, 14. Februar 12
  • 21. cucumber: step definitions Combining steps And /^I add the comment ["'](.*)["']$/ do |text|   step "I click on 'Comment'"   step 'I disable the rich-text editor'   step "I fill in 'Comment' with '#{text}'"   step "I press 'Save'" end Dienstag, 14. Februar 12
  • 22. cucumber: step definitions Advanced steps #The ?: tells us that we don't want to capture that part in a variable When /^(?:I am|I'm|I) (?:on|viewing|looking at|look at|go to|visit|visiting) ['"]?([^"']*)["']?$/ do |path|   translation_hash = {     "the status report page" => '/admin/reports/status',     "the blog posts page" => '/content/blogs',     "the blog post page" => '/content/blogs',     [...]     'the bookmarks page' => '/bookmarks',   }   if translation_hash.key?(path)     visit(translation_hash[path])   else     if path.start_with?("/")       visit(path)     else       raise "I don't know how to go to this path: #{path.inspect}."     end   end end Dienstag, 14. Februar 12
  • 23. File Layout Features: The test descriptions Step definitions: Mapping text to code env.rb: Setting up the environment Gemfile: Which gems? Gemfile.lock Which versions? Rakefile: Misc tasks Dienstag, 14. Februar 12
  • 24. File Layout: env.rb? env.rb does these things: • it loads Bundler • it loads Capybara • ... and sets the default driver • It loads the capybara-screenshot gem • it launches XVFB • it populates the $site_capabilities hash • determines weather or not we have the devel module available Dienstag, 14. Februar 12
  • 25. General usage • Run one feature: $ cucumber features/blog.feature • Run the specific scenario at line 42: $ cucumber features/blog.feature:42 Dienstag, 14. Februar 12
  • 26. Other nifty things • cucumber --dry-run: Allows to check for missing step definitions • cucumber --format usage: Allows to figure out which steps get called the most or which steps don’t get called. Also tells you which steps take the longest • cucumber --format rerun: Saves failed tests to rerun.txt and allows to rerun just those failed tests • cucumber --tags @wip: Will only run tests tagged @wip. Also possible: “--tags ~@wip” to NOT run them Dienstag, 14. Februar 12
  • 27. Code smells (we have some of those) • Try to abstract the actual implementation of the steps out of the scenarios • Good: “Given I am logged in as an administrator” • Bad: Given I go to “/login” And I enter “admin” in the “username” field And I enter “foobar” in the “password” field [...] Dienstag, 14. Februar 12
  • 28. Capybara vs Selenium Dienstag, 14. Februar 12
  • 29. Capybara and Selenium Selenium • An API • Bindings for actual browsers (IE, Chrome, FF, ...) Capybara: • An API • A big set of tests Capybara drivers: • Remote controls for browsers and browser simulators that can be “plugged into” Capybara, usually 3rd party projects Dienstag, 14. Februar 12
  • 30. Selenium: setup • Selenium 1 needs: • An installed browser • A running Selenium RC (java app) • An X server • With Saucelabs it needs: • A running Sauceconnect process Dienstag, 14. Februar 12
  • 31. Problems with Selenium • Slow: Launching Firefox with a new profile • Slow: Adding Webdriver extension • Slow: Communicates over JSON/REST • Bad: No Console.log output • Bad: JS Errors are invisible • Bad: Selenium 1 has limitations • Bad: No proper implicit waits Dienstag, 14. Februar 12
  • 32. Capybara: setup Capybara needs: • A driver Capybara drivers need: • selenium webdriver: X Server • headless webkit: X Server, QT • poltergeist: X Server, the phantomjs binary • akephalos: java • mechanize: no dependencies Dienstag, 14. Februar 12
  • 33. Capybara: drivers Javascript + Speed Stability DOM Webdriver 10 7 6 (recently) Headless 9 9 9 Webkit Poltergeist 9 8 5 (PhantomJS) Akephalos 6 6 8 (HTML Unit) Mechanize 0 10 10 Dienstag, 14. Februar 12
  • 34. Capybara API: clicking click_link('id-of-link') click_link('Link Text') click_button('Save') click_on('Link Text') click_on('Button Value') Dienstag, 14. Februar 12
  • 35. Capybara API: forms fill_in('First Name', :with => 'John') fill_in('Password', :with => 'Seekrit') fill_in('Description', :with => 'Really Long Text...') choose('A Radio Button') check('A Checkbox') uncheck('A Checkbox') attach_file('Image', '/path/to/image.jpg') select('Option', :from => 'Select Box') Dienstag, 14. Februar 12
  • 36. Capybara API: querying page.has_selector?('table tr') page.has_selector?(:xpath, '//table/tr') page.has_no_selector?(:content) page.has_xpath?('//table/tr') page.has_css?('table tr.foo') page.has_content?('foo') Dienstag, 14. Februar 12
  • 37. Capybara API: rspec matchers page.should have_selector('table tr') page.should have_selector(:xpath, '//table/tr') page.should have_no_selector(:content) page.should have_xpath('//table/tr') page.should have_css('table tr.foo') page.should have_content('foo') Dienstag, 14. Februar 12
  • 38. Capybara API: finding find_field('First Name').value find_link('Hello').visible? find_button('Send').click find(:xpath, "//table/tr").click find("#overlay").find("h1").click all('a').each { |a| a[:href] } Dienstag, 14. Februar 12
  • 39. Capybara API: scoping find('#navigation').click_link('Home') find('#navigation').should have_button('Sign out') within("li#employee") do fill_in 'Name', :with => 'Jimmy' end within(:xpath, "//li[@id='employee']") do fill_in 'Name', :with => 'Jimmy' end Dienstag, 14. Februar 12
  • 40. Capybara API: AJAX? Capybara.default_wait_time = 5 click_link('foo') #Ajax stuff happens that adds “bar” click_link('bar') #Ajax stuff happens that adds “baz” page.should have_content('baz') Dienstag, 14. Februar 12
  • 41. Capybara: Heads up for Ajax! Bad !page.has_xpath?('a') Good page.has_no_xpath?('a') Dienstag, 14. Februar 12
  • 42. In Selenium: AJAX :( wait = Selenium::WebDriver::Wait.new(:timeout => 5) btn = wait.until { @browser.find_element(:xpath => @contmgr.sort_asc) } Dienstag, 14. Februar 12
  • 43. Note: PHP Behat Cucumber in PHP http://behat.org/ Mink Capybara in PHP http://mink.behat.org/ Capybara Cucumber Behat Mink Dienstag, 14. Februar 12