Cucumber 🥒🥒🥒🥒🥒🥒
Cucumber lets you write test code as English statements that start with the Gherkin words: Given, When, and Then. Anki Books sometimes uses And to substitute for a consecutive Given, When, or Then. This means that Cucumber is a tool that enables nontechnical people to write feature tests or specify the interaction with the software from the point of view of a user that can accurately dictate the actions of the program. For this to work, the programmers must also set up a mapping between the patterns of the grammar in the statements starting with Given, When, and Then. The mapping between Gherkin statements and execution of the code in Cucumber code is specified using step definitions which are code.
Example: some step definitions
Note these step definitions do not and typically would not all be in the same file. Usually, they would be organized by the type of action or by domains and features of the software.
With a Ruby on Rails app that is using Cucumber step definitions to automate a web browser, it is common to use the domain specific language or API from the Capybara gem. Capybara provides a common API to automate the web browser whether Capybara is using Selenium Webdriver or :rack_test under the hood. Anki Books uses both of these drivers--:rack_text is faster but cannot execute JavaScript. The Capybara DSL is used to drive the web browser through the Anki Books test instance by clicking links, filling in and submitting forms, and dragging and dropping stuff around to prevent regressions in the user interface.
With a Ruby on Rails app that is using Cucumber step definitions to automate a web browser, it is common to use the domain specific language or API from the Capybara gem. Capybara provides a common API to automate the web browser whether Capybara is using Selenium Webdriver or :rack_test under the hood. Anki Books uses both of these drivers--:rack_text is faster but cannot execute JavaScript. The Capybara DSL is used to drive the web browser through the Anki Books test instance by clicking links, filling in and submitting forms, and dragging and dropping stuff around to prevent regressions in the user interface.
When "I visit the root path" do visit "/" end Given "there is a user with username {string}, email {string}, and password {string}" do |string, string2, string3| User.create!(username: string, email: string2, password: string3) end When "I click the {string} button" do |button| click_button button sleep 0.5 end
Some methods added by the Capybara API in the above step definitions are visit and click_button. A path is a part of a URL that many users of the web are familiar with. User in the code above is the Active Record model User in Anki Books.
Example: Cucumber test and step definition for visiting the homepage of Anki Books
An example Cucumber feature test:
Feature: The website homepage Scenario: Visiting the homepage When I visit the root path Then I should see the homepage
This is the step definition for the last Gherkin statement in the above:
Then "I should see the homepage" do expect(page).to have_content("This is the system article to serve as the homepage.") end
This syntax is also related to RSpec.
Example: Cucumber feature test dismissing a flash message
@javascript Feature: Flash messages Scenario: Dismissing an alert flash message Given I visit the root path And there is a user with username "test_user", email "test@example.com", and password "123abc777www" When I click the "Login" link And I fill in the "Email" field with "test@example.com" And I fill in the "Password" field with "wrong_password" And I click the "Log in" button And I click the "Dismiss" button Then I should not see "Invalid email or password"
The @javascript tag above the test indicates to Capybara that it should use the Selenium Webdriver API which supports JavaScript (:rack_test does not support JavaScript). This means that the feature tests without the @javascript tag will use :rack_test by default which is a little faster. This test may not even need JavaScript to execute but the performance cost of using Selenium WebDriver a couple times unnecessarily is not that much.
This example does also show what I meant with using And instead of repeating one of the other Gherkin words over and over.
I hope it's clear intuitively how the Ruby code in the step definitions corresponds to the Gherkin statements.
Article notes
What driver can Capybara use out of the box but cannot execute JavaScript (written as a Ruby symbol)?
:rack_test
What define how tests written in Cucumber/Gherkin are translated into Ruby code?
Step definitions
What is the driver supported by Capybara out of the box that cannot execute JavaScript?
:rack_test
What gem do you need to install (in addition to capybara) if you want to use Capybara with Selenium?
selenium-webdriver
What is the method in Capybara which takes a single string parameter and navigates to that path by making a GET request?
visit
What method in the Capybara API documentation can take a snapshot of the page as it currently is and then open it so you can take a look at it?
save_and_open_page
If you have required capybara/rails, what will Capybara.save_path default to?
tmp/capybara
Does Capybara locate non-visible elements, by default?
No
What tag is written over a Cucumber scenario (or feature) to switch to the Capybara.javascript_driver (:selenium by default)?
@javascript
What is the Capybara gem (the name of the gem to add to the Gemfile)?
capybara
In addition to creativity, the only ability a person needs to program computers is what according to John Ousterhout in APOSD?
Ability to organize thoughts