Skip to content

Instantly share code, notes, and snippets.

@stepheneyer
Last active March 8, 2024 19:51
Show Gist options
  • Save stepheneyer/01be60c1ec6c004e0253 to your computer and use it in GitHub Desktop.
Save stepheneyer/01be60c1ec6c004e0253 to your computer and use it in GitHub Desktop.
BDD testing using Cucumber, Capybara, and Rails

#Cucumber and Capybara - Behavior Driven Development

##Overview

Cucumber allows software developers to describe how software should behave in plain text. The text is written in a business-readable, domain-specific language. This allows non-programmers to write specific feature requests that can be turned into automated tests that drive development of the project.

Capybara is the largest rodent known to man.

It is also software that helps you test web applications by simulating how a real user would interact with your app. It is agnostic about the driver running your tests and is built into Rails applications.

##Why is this technology useful? Cucumber allows tests to be more readable because they are written in what looks like plain English, although it is actualy Gherkin. Behavior-driven development (BDD) is partly about understanding what the client wants before you begin coding, so tests are written with plain text which makes it easier to read and understand the feature requests you'll be coding from the start. Each Cucumber test is written in a story format that includes a feature request and matching scenario.

###For example:

Feature: Welcome
  In order to read the page
  As a viewer
  I want to see the home page of my app

	Scenario: View welcome page
  		Given I am on the home page
  		Then I should see "Welcome to my site."

Each scenario can have up to three parts: Givens, Whens, and Thens:

Given: Given lines describe what pre-condition should exist.

When: When lines describe the actions you take.

Then: Then lines describe the result.

You can also add And lines, which do whatever the line above them does.

###Steps to implement Cucumber in Ruby on Rails:

Create a new Ruby on Rails project.

rails new cucumber -d postgresql
cd cucumber
rake db: create

Install the Cucumber-Rails gem in your project's Gemfile.

group :test, :development do
  gem 'cucumber-rails', :require => false
  # database_cleaner is not required, but highly recommended
  gem 'database_cleaner'
end

Remember to bundle install and then restart your Rails server.

bundle install

Install Cucumber, which will create a folder in your project called "features" with a sub-folder called "step_definitions"

rails g cucumber:install

Create a test file called "welcome.feature" in the "features" folder. Make sure to use the .feature extension. Use can use the example from above.

Feature: Welcome
  In order to read the page
  As a viewer
  I want to see the home page of my app

	Scenario: View welcome page
  		Given I am on the home page
  		Then I should see "Welcome to my site."

Then run your test.

cucumber features/welcome.feature

You'll see that your tests needs a step_definition.

Given(/^I am on the home page$/) do
  pending # express the regexp above with the code you wish you had
end

Then(/^I should see "(.*?)"$/) do |arg1|
  pending # express the regexp above with the code you wish you had
end

Create a "welcome_steps.rb" file inside the "step_definitions" subfolder in the "features" folder. Change the test code using the Capybara syntax to something like this:

Given(/^I am on the home page$/) do
  visit "/"
end

Then(/^I should see "(.*?)"$/) do |text|
  page.has_content?(text)
end

Like all good tests, it should fail the first time you run it. Make changes to your code so it will pass the test.

Hint: Create a Welcome controller, assign the root route to welcome#index, and create the index view with the content 'Welcome to my site'.

Run your test again. Does it pass? Once all your tests are green like a cucumber, you're good to go!

##What were the roadblocks?

###Testing is not easy The process of testing is not simple, no matter what tool you use. Although users are able to write Cucumber tests in plain text, it still requires development time to write the code to pass the tests. This can be as challenging or even more challening then just coding it upfront.

###Not familiar with DSL testing language It wasn't initally very clear how to write the test code needed pass the test. The documentation and tutorials for Cucumber are not great on their site. They would benefit from a basic step-by-step tutorial that walks you through exactly how to create your first test.

Of course, the best place to look is the docs. I included some resources below that might be helpful.

##What are the takeaways and lessons learned?

###The sexy thing to do is not necessarily the best thing Whle most developers know they should use BDD, it's never quite as fun or as sexy as just diving into the code. Making the time to do BDD when working on a project is like telling someone they need to skip dessert and eat broccoli instead. Only the most disciplined among us are likely to actually do it.

###Code first, then test? One recent suggestion I heard recently is that it might be more practical for developers and startups to code the first itiration of their idea, determine they have a good product-market fit and are going to keep the code they created (and are not going to toss it), and then write tests to make sure they have critical parts of their project protected from future refactoring, added features, etc.

###Get one test working first Sometimes it can be overwhelming to think about all the tests you might need to write for your project. By getting one test written and passing, it can provide the needed extra motivation to make more of them. Learning the syntax needed to pass one test helps provide the confidence to write and pass more of them.

##Resources

Cucumber - Simple, human collaboration

Capybara - Ruby docs with coding syntax

Business-Readable DSL - Martin Fowler's explanation

Ruby for Newbies: Testing Web Apps with Capybara and Cucumber - Tuts+ tutorial for Cucumber and Rails

Velocity - Meteor's testing application that uses Cucumber

@jonpoischen
Copy link

Overall very nice explanation, however I definitely wouldn't create separate step files like "welcome_steps.rb". Instead these 2 steps you have, visit a URL and I should see, should be in a common_steps.rb file to keep everything as DRY as possible. Those 2 steps would literally be used everywhere in your feature files...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment