8 Steps to Create a Simple Capybara Test

What’s Capybara?

Capybara is basically a library that helps you test web applications by simulating how a real user would interact with your app.

Capybara requires Ruby 1.9.3 or later. To install, type in your terminal:

1
gem install capybara

Capybara tests are often called feature tests or end-to-end testing. It was built on top of Nokogiri in order to discover the elements on a page using HTML and CSS. It is a DSL (Domain Specific Language) that is built on top of and Cucumber.

Capybara tests are like RSpec tests with Capybara flavoring (yum giant rodent). Some keywords:

Capybara DSL RSpec DSL
feature describe
background before
scenario it
given let

Capybara uses a web driver (in this example Selenium) to do some browser magic. It lets you control the browser through code and has the browser take actions on your behalf in order to make sure the website actually works as the user will experience. Normally a “headless browser” is used to save memory, but the example below will show it to you live…for funsies.

Examples of Capybara syntax:

Method What it does
visit ‘url’ goes to the given url
fill_in(locator, :with => option) finds text field by id and fills in with option
click_button(locator) finds button by id and clicks it

Capybara with Google and Youtube Searches.

You can download this code here.

Step 1

In your project folder, add Capybara and Selenium-WebDriver to your Gemfile. It should look like this:

1
2
3
4
5
6
7
8
9
source 'https://rubygems.org'

gem "sinatra"

group :test do
  gem "rspec"
  gem "capybara"
  gem 'selenium-webdriver'
end

Step 2

Don’t forget to bundle

1
bundle install

Step 3

Create a simple_app.rb file (it got mad at me if I didn’t include this file).

1
2
3
4
5
require_relative './environment'

get '/' do
  "hello capybara"
end

Step 4

Normally, there’d be more folders in your application, but this is a very simple example so everything is in the top level.

Your environment.rb should look like this:

1
2
3
4
require 'bundler/setup'
Bundler.require

require './simple_app'

Step 5

And your config.ru…

1
2
3
require './environment'

run SimpleApp

Step 6

Require Capybara in your spec_helper.rb file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
require 'capybara'
include Capybara::DSL
Capybara.default_driver = :selenium

def app
  Sinatra::Application
end

set :environment, :test
RSpec.configure do |config|
  config.treat_symbols_as_metadata_keys_with_true_values = true
  config.run_all_when_everything_filtered = true
  config.filter_run :focus
  config.order = 'random'
end

Step 7

Here’s what my features_spec.rb looks like. I’m using Capybara to search Google.com for “Flatiron School” and then visiting YouTube to look for cat videos. In each describe block, I tell Capybara to visit the website and fill in the text field with what I’m searching for and then click submit. The sleep 2 is there to slow down the process so you can see it better in Step 8.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
require_relative '../simple_app.rb'
require 'spec_helper.rb'

describe 'google search page', :js => true do
  it "should search the google for something" do
    visit 'http://google.com'
    fill_in("gbqfq", :with => "Flatiron School")
    sleep 2
    click_button("gbqfb")
    sleep 2
  end
end

describe 'youtube search page', :js => true do
  it "should search youtube for maru" do
    visit 'http://www.youtube.com/'
    fill_in("masthead-search-term", :with => "mugumogu")
    sleep 2
    click_button("search-btn")
    sleep 2
    page.should have_content("maru")
  end
end

Step 8

Now run rspec in your terminal and watch it do the searches and pass the tests.

What’s foo bar?

You’ve probably seen something like this before:

1
2
3
4
foo = "Chunky"
bar = "Bacon!"
puts foo + " " + bar
=> Chunky Bacon!

But what is the origin of using “foo,” “bar,” and “baz” as placeholder names in pseudocode (aka metasyntactic variables)? According to the interwebs, “foo” first emerged as a nonsense word in the 1930s in the comic Smokey Stover by Bill Holman and became popular in other cartoons at the time. From there, “foo” merged with the military acronym FUBAR, which arose in the armed forces during WWII. The use of “foo” in programming, however, is credited to MIT’s Tech Model Railroad Club (TMRC) in the 1960s.

Thomas and Friends

The TMRC is celebrated due to its developmental role in hacker culture. Foo’s first appearance in print was in a 1965 edition of MIT’s “Tech Engineering News.” In TMRC’s train model system, there were scram switches located at numerous places around the room that could be thrown if a train was going to crash into something. Another feature of the system was a digital clock on the dispatch board. When someone hit a scram switch, the clock stopped and would instead display the word “”foo”,“ thus why they were called ”“foo” switches”.

The train room also had two buttons by the door labeled “foo” and “bar”. They were often re-purposed for whatever fun idea the TMRC had at the time, hence the adoption of “foo” and “bar” as general purpose variable names. “Baz” exists simply because Stanford preferred “baz” over “bar”.

The terms were made popular through computer science circles in the 1960s and early 1970s by system manuals from the Digital Equipment Corporation and Fortran’s code for Colossal Cave Adventure.

Pseudocode in other countries:

  • UK: wibble, wobble, fred, flob
  • France: toto, tata, tutu, bidule, azerty (French keyboard’s asdf)
  • Japan: hoge, piyo, fuga, hogera
  • Isarael: chupchick, stam
  • Italy: pippo, pluto, paperino
  • Spain: fulano, mengano, zutano

TL;DR

  • “foo” is a nonsense word from 1930s comics.
  • FUBAR comes from US military slang during WWII.
  • MIT’s Tech Model Train Club popularized the terms for tinkering/hacking.
  • Use “foo”, bar, and baz to test out concepts so you don’t cause a SNAFU and make your code FUBAR.
  • What about “Hello, World”? It comes from The C Programming Language.
  • What about “Chunky Bacon”? It comes from why’s (poignant) Guide to Ruby.

Ruby Tricks and Oddities

Just looked through Julio Santos’ “Ruby Things” on Speaker Deck and learned some quirkly little things about Ruby.

Creating hashes from arrays. 2 different outcomes:

1
2
3
4
5
6
7
8
Hash[["one", 1], ["two", 2]]
=> {["one", 1]=>["two", 2]}

a=["one", 1], ["two",2]
=> [["one", 1], ["two", 2]]

Hash[a]
=> {"one"=>1, "two"=>2}

The zip method “converts any arguments to arrays, then merges elements of self with corresponding elements from each argument.” For example:

1
2
3
4
a = [2, 5, 8]
b = [3, 6, 9]
[1, 4, 7].zip(a, b)
=> [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

Santos demonstrates that you can use zip to create hashes:

1
2
3
4
5
6
keys = [:one, :two, :three]
values = [1, 2, 3]
zip = keys.zip(values)
=> [[:one, 1], [:two, 2], [:three, 3]]
Hash[zip]
=> {:one=>1, :two=>2, :three=>3}

And yesterday while wishing a collect_with_index method existed, my group discovered that you can combine each_with_index with collect!

1
2
3
4
5
6
7
8
9
10
11
class Array
  def make_list
    self.each_with_index.collect do |german, index|
      "#{index+1}. #{german}"
    end
  end
end

array = ["eins", "zwei", "drei"]
array.make_list
 => ["1. eins", "2. zwei", "3. drei"]