How to send HTTP requests using cURL

  • Reading a URL via GET:

    curl http://example.com/
    
  • Defining any HTTP method (like POST or PUT):

    curl http://example.com/users/1 -XPUT
    
  • Sending data with a request:

    curl http://example.com/users -d"first_name=Bruce&last_name=Wayne"
    

    If you use -d and do not set an HTTP request method it automatically defaults to POST.

  • Performing basic authentication:

    curl http://user:password@example.com/users/1
    
  • All together now:

    curl http://user:password@example.com/users/1 -XPUT -d"screen_name=batman"
    

...

Imperative vs Declarative Scenarios in User Stories

Bryan talked about the differences between imperative and declarative scenarios. In my opinion, both styles have benefits and should be used appropriately based on the situation. The majority of examples on rspec's story runner currently on the web, including mine, are of the imperative type. Since the declarative type has many advantages I thought it would be worth while to present some examples and contrast the differences between the two styles.

Where to put custom RSpec matchers

When you write a custom RSpec matcher a good place to store them is to create one file per matcher in spec/support/matchers:

spec/support/matchers/be_same_numbers_as.rb
spec/support/matchers/be_same_second_as.rb
spec/support/matchers/exist_in_database.rb
spec/support/matchers/include_hash.rb

You can include all matchers in the support directory by adding the following line to your spec_helper.rb:

Dir[File.expand_path(File.join(File.dirname(__FI...

Different CSS for IE using Sass

At times, it might be unavoidable to have different CSS rules for Internet Explorer than for sane browsers. Using Sass, this can be achieved in a relatively non-hackish way without CSS hacks.

Step 1

Move your current Sass file into a partial. Let's assume it was called screen.sass. Rename it _screen.sass.

Step 2

Create two new Sass files:

Call this one screen.sass:
$ie = false
@import screen

Call this one screen_for_ie.sass:
$ie = true
@import screen

Step 3

Change y...

Acceptance testing using Capybara's new RSpec DSL

Back when Steak was first released, Capybara didn’t have any of the nice RSpec helpers it does now. A lot has changed since. Besides the helpers, it got its own RSpec acceptance testing DSL recently, essentially eating Steak’s functionality and turning it into a complete acceptance testing solution (on top of RSpec).

Upgrading Cucumber and Capybara to the latest versions available for Rails 2

Specify these gem versions in your Gemfile:

gem 'cucumber', '~> 1.3.0'
gem 'cucumber-rails', '= 0.3.2' # max version for Rails 2
gem 'capybara', '< 2' # capybara 2+ requires Rails 3
gem 'mime-types', '< 2' # dependeny of capybara
gem 'nokogiri', '< 1.6' # dependency of capybara
gem 'rubyzip', '< 1' # dependency of selenium-webdriver, rubyzip 1+ requires Ruby 1.9
gem 'cucumber_factory'
gem 'database_cleaner', '< 1'
gem 'cucumber_spinner', '~> 0.2.5'
gem 'launchy', '~> 2.1.2'

With these versions set, `...

Skip Selenium scenarios in a Cucumber run

Cucumber scenarios that are tagged with @javascript so they run with Selenium are very slow. You might not want to run them every time.

In order to skip all Selenium scenarios, call Cucumber like this:

cucumber --tags ~@javascript

Note that you should still run all the scenarios, including the Selenium ones, before you push a change.

Prohibit Git from merging .po-files

Merging .po-files with Git is painful.

There have been attempts of making Git more clever when trying to merge .po-files. I believe however that this is not enough as it can still produce invalid .pos (usually due to double definitions), which can seriously confuse gettext afterwards.

Lacking any more secure solution, I think you should avoid editing po files in different branches at the same time. In order to not accidentally produce invalid merges I additionally ...

Mocks and stubs in Test::Unit when you are used to RSpec

We are maintaining some vintage projects with tests written in Test::Unit instead of RSpec. Mocks and stubs are not features of Test::Unit, but you can use the Mocha gem to add those facilities.

The following is a quick crash course to using mocks and stubs in Mocha, written for RSpec users:

|---------------------------------------------------------|
| RSpec | Mocha |
|---------------------------------------------------------|
| obj = double() | obj = mock() |
| obj.stub(:method => 'value') | `obj.stubs...

Delete all MySQL records while keeping the database schema

You will occasionally need to clean out your database while keeping the schema intact, e.g. when someone inserted data in a migration or when you had to kill -9 a frozen test process.

Old Capybara versions already have the Database Cleaner gem as dependency. Otherwise add database_cleaner to your *Gemfile`. This lets you say this from the Rails console:

DatabaseCleaner.strategy = :truncation
DatabaseCleaner.cl...

Synchronize a Selenium-controlled browser with Capybara

When you click a link or a press a button on a Selenium-controlled browser, the call will return control to your test before the next page is loaded. This can lead to concurrency issues when a Cucumber step involves a Selenium action and a Ruby call which both change the same resources.

Take the following step which signs in a user through the browser UI and then sets a flag on the user that was just signed in:

Given /^the user "([^"]*)" signed in (\d) days ago$/ do |name, days|
  visit new_session_path
  fill_in 'Username', :w...

Check that an element is hidden via CSS with Spreewald

If you have content inside a page that is hidden by CSS, the following will work with Selenium, but not when using the Rack::Test driver. The Selenium driver correctly only considers text that is actually visible to a user.

Then I should not see "foobear"

This is because the Rack::Test driver does not know if an element is visible, and only looks at the DOM.

Spreewald offers steps to check that an element is hidden by CSS:

Then "foo" should be hidden

You can also check that an el...

Configuring User Agents with Capybara + Selenium Webdriver

A while ago we were working on an application that had an entire version specially created for mobiles, such as the iPhone. This specific application was entirely tested with Capybara, Steak and Selenium Webdriver. Although the test suite wasn’t the fastest one in the world, the web application was very well tested, and to guarantee that we would also be testing the mobile version, we would have to simulate an iPhone user agent accessing the application.

But wait, you might be thinking that we are not able to change browser headers while ...

Escaping of quotation marks in Cucumber steps and step definitions

Issue

When you have a Cucumber step like

Then I should see "Did you see those \"quotation marks\" over there?"

you'll run into trouble. Cucumber won't take your escaped quotation marks.

Workarounds

One workaround is to write the step as regex (since there is a step taking a regex):

Then I should see /Did you see those "quotation marks" over there\?/

Keep in mind it’s a regex – escape regex characters like '?'.

When you have a Cucumber step like

Then I should fill in "query" with "\"some phrase\""

The fo...

Cucumber fails without giving error message

To improve your chances to get proper error messages, you can try
^

  • to start cucumber with the -b option, so it shows a full backtrace
  • to start cucumber with the -f pretty option to get a more verbose formatter
  • to start cucumber with the -d option to show debug information

Test that a select field contains an option with Cucumber

This note describes a Cucumber step definition that lets you say:

Then "Mow lawn" should be an option for "Activity"
But "Reply support mail" should not be an option for "Activity"

Note that this step checks whether an option is available, not that it is selected. There is a separate step to test that an option is selected.

Capybara (0.4.1 or higher)

Then /^"([^"]*)" should( not)? be an option for "([^"]*)"(?: within "([^\...

Test the status code of a response in Cucumber

Webrat

Then /^I should get a response with status (\d+)$/ do |status|
  response.status.should include(status)
end

Capybara

Then /^I should get a response with status (\d+)$/ do |status|
  page.status_code.should include(status.to_i)
end

Perform HTTP basic authentication in Cucumber (with or without Selenium)

This card describes a Cucumber step that lets you say:

When I perform basic authentication as "username/password" and I visit the admin area

The path component ("... the admin area") is parsed through your path_to helper in features/support/paths.rb.

Capybara

The step definition is part of Spreewald. The step has been tested with multiple versions of Capybara, Rack::Test and Selenium.

Webrat (legacy)

This is a simpler version of the step above:

When /...

Always show the page if there is an error in Cucumber

Are you adding a "Then show me the page" and re-run Cucumber whenever there is a failing scenario? Don't be that guy!

Save time with the shiny new version of our cucumber_spinner gem. It comes with a Cucumber formatter that not only displays an awesome progress bar, and shows failing scenarios immediately, it will also open the current page in your browser whenever a scenario step fails.

After you installed the gem, use the formatter like this:

cucumber --format CucumberSpinner::Curiou...

Speed up RSpec by deferring garbage collection

Update: This trick probably isn't very useful anymore in Ruby 2.x. The Ruby GC has improved a lot over the years.


Joe Van Dyk discovered that running the Ruby garbage collector only every X seconds can speed up your tests. I found that deferring garbage collection would speed up my RSpec examples by about 15%, but it probably depends on the nature of your tests. I also tried applying it to Cucumber f...

Iterate over every n-th element of a Range in Ruby

If you want to iterate over a Range, but only look at every n-th element, use the step method:

(0..10).step(5).each do |i|
  puts i
end

# Prints three lines:
# 0
# 5
# 10

This is useful e.g. to iterate over every Monday in a range of Dates.

If you are using Rails or ActiveSupport, calling step without a block will return an array of matching elements:

(0..10).step(5) 
# => [0, 5, 10]

Test a download's filename with Cucumber

These steps are now part of Spreewald.

The step definitions below allow you to test the filename suggested by the server:

When I follow "Export as ZIP"
Then I should get a download with the filename "contacts_20110203.zip"

Capybara

Then /^I should get a download with the filename "([^\"]*)"$/ do |filename|
  page.driver.response.headers['Content-Disposition'].should include("filename=\"#{filename}\"")
end

Webrat

Then /...

Test the content-type of a response in Cucumber

The step definitions below allow you to write this in both Webrat and Capybara:

When I follow "Download as PDF"
Then I should get a response with content-type "application/pdf"

Capybara

Then /^I should get a response with content-type "([^"]*)"$/ do |content_type|
  page.response_headers['Content-Type'].should == content_type
end

Webrat

Then /^I should get a response with content-type "([^"]*)"$/ do |content_type|
  response.content_type.should == content_type
end

Unfortunatly this do...

Cucumber steps to test input fields for equality (with wildcard support)

Our collection of the most useful Cucumber steps, Spreewald, now supports exact matching of form fields and lets you use wildcards.

Examples:

And the "Money" field should contain "134"
# -> Only is green if that field contains the exact string "134", neither "134,50" nor "1000134"

And the "Name" field should contain "*Peter*"
# -> Accepts if the field contains "Peter" or "Anton Peter" or "Peter Schödl" etc.

And the "Comment" field should contain "Dear*bye"
# -> Accepts if the field contains "De...