Recent RSpec features you might not know about

With its you can switch the subject of an example to a method value of the current subject:

describe Array do
  its(:length) { should == 0 }
end

stub_chain is the tie to go along with should_receive_chain's tux:

object.stub_chain(:first, :second, :third).and_return(:this)

You can restore the original implementation of stubbed methods with unstub:

object.stub(:foo => 'bar')
# ...
object.unstub(:foo)

In recent RSpecs ...

Check that a text field is empty with Cucumber

This will not work (it always passes):

Then the "Title" field should contain ""

The value is turned into a regular expression, and an empty regular expression matches any string!

Do this instead for Capybara:

Then the "Title" field should contain "^$"

And do this step for Webrat:

Then /^the "([^"]*)" field should( not)? be empty$/ do |field, negate|
  expectation = negate ? :should_not : :should
  field_labeled(field).value.send(expectation, be_blank)
end

Run a rake task in all environments

Use like this:

power-rake db:migrate VERSION=20100913132321

By default the environments development, test, cucumber and performance are considered. The script will not run rake on a production or staging environment.


This script is part of our geordi gem on github.

Using RSpec stubs and mocks in Cucumber

By default, Cucumber uses mocha. This note shows to use RSpec stubs and mocks instead.

Rspec 1 / Rails 2

Put the following into your env.rb:

require 'spec/stubs/cucumber'

Rspec 2 / Rails 3

Put the following into your env.rb:

require 'cucumber/rspec/doubles'

Note: Since Cucumber 4 it is important to require these lines in the env.rb and not any other file in support/* to register the hooks after any other After hook in support/*. Otherwise your doubles are removed, while other After steps requi...

Debug Ruby code

This is an awesome gadget in your toolbox, even if your test coverage is great.

  • gem install ruby-debug (Ruby 1.8) or gem install debugger (Ruby 1.9)
  • Start your server with script/server --debugger
  • Set a breakpoint by invoking debugger anywhere in your code
  • Open your application in the browser and run the code path that crosses the breakpoint
  • Once you reach the breakpoint, the page loading will seem to "hang".
  • Switch to the shell you started the server with. That shell will be running an irb session where you can step thr...

Bundler for Rails 2.3.x

Update RubyGems and Passenger

Bundler requires Rubygems >= 1.3.6. Run gem update --system if you have an older version.
It also is not compatible with older versions of passenger, so bring that up to date as well (2.2.15 works).

If you installed RubyGems through apt (which you should never do!), you may see a message giving you a hint to use apt to update.
Some people advise to install the 'rubygems-update-1.3.7' gem on Ubuntu systems if you used apt to install RubyGems.
I did that - and lost all...

Boolean attributes and pretty enumerations in Cucumber Factory 1.7

Boolean attributes can now be set by appending "which", "that" or "who" at the end:

Given there is a movie which is awesome
And there is a movie with the name "Sunshine" that is not a comedy
And there is a director who is popular

Instead of "and" you can now also use "but" and commas to join sentences:

Given there is a movie which is awesome, popular and successful but not science fiction
And there is a director with the income "500000" but with the account balance "-30000"

Update with `sudo gem install cucumber_facto...

Test e-mail dispatch in Cucumber

Spreewald has steps that let you test that e-mails have been sent, using arbitrary conditions in any combination.

The attached file is for legacy purposes only.

Regular Expressions - Cheat Sheet

You can write regular expressions some different ways, e.g. /regex/ and %r{regex}. For examples, look here.

Remember that it is always a good idea to match a regex visually first.

Characters

Literal Characters

[ ] \ ^ $ . | ? * + ( )

Character Classes

[ae]            matches a and e, e.g. gr[ae]y => grey or gray => but NOT graay or graey
[0-9]  ...

Multi-line step arguments in Cucumber

The following example is from the Cucumber wiki:

Given a blog post named "Random" with Markdown body
  """
  Some Title, Eh?
  ==============
  Here is the first paragraph of my blog post. Lorem ipsum dolor sit amet,
  consectetur adipiscing elit.
  """

That multi-line string will be given as the last block argument in your step definitions:

Given /^a blog post named "([^\"]*)" with Markdown body$/ do |title, markdown|
  Post.create!(:title =...

Change Paperclip secrets the hard way

So you screwed up and copied Paperclip secrets from one project to another. Here is a semi-automatic, painful way to migrate your existing attachment files to new locations.

You need to follow this step by step, do not just copy the whole thing into the console!

# 1. Get old paths by doing something like this on the console:
old_paths = ModelWithAttachment.all.collect { |m| [m.id, File.dirname(m.image.path(:original)).gsub(/original$/, '') ] if m.image.file? }.compact.uniq

# 2. Now change the Paperclip secret on the co...

Marry Capybara with SSL-enabled applications

Capybara does not play nice with sites that have some actions protected by SSL, some not. A popular way to implement this in Rails is using the ssl_requirement plugin by DHH, which redirects a requests from HTTP to HTTPS if the requested action requires SSL and vice versa.

Capybara follows the redirect, but seems to forget the changed protocol for the next request. The only hack-free workaround right now is to use URLs in lieu of paths everywhere (links, form actions).

For a hackful fi...

rspec_candy is now a gem

Our awesome collection of rspec helpers (formerly known as "spec_candy.rb") is now available as a gem. It works, it is tested and there will be updates.

Usage

Add rspec_candy to your Gemfile.

Add require 'rspec_candy/helpers' to your spec_helper.rb, after the rspec requires.

List of features

See on GitHub

Git: Merge a single commit from another branch

This is called "cherry-picking".

git cherry-pick commit-sha1

Note that since branches are nothing but commit pointers, cherry-picking the latest commit of a branch is as simple as

git cherry-pick my-feature-branch

Be aware that cherry-picking will make a copy of the picked commit, with its own hash. If you merge the branch later, the commit will appear in a history a second time (probably without a diff since there was nothing left to do).

Also see our advice for [cherry picking to production branches](https://makandraca...

Git: Revert one or more commits

Reverting a commit means creating a new commit that undoes the old changes.

Imagine the following commit history:

* commit_sha3 [Story-ID 1] Fixup for my feature 
* commit_sha2 [Story-ID 5] Other feature
* commit_sha1 [Story-ID 1] My feature 

You can revert a single commit using the following syntax:

git revert commit_sha2

To revert changes that are split across multiple commits, use the --no-commit flag.

git revert --no-commit commit_sha3
git revert --no-commit commit_sha1
git commit -m "Revert Story 1"

stefankroes's ancestry at master - GitHub

Ancestry is a gem/plugin that allows the records of a Ruby on Rails ActiveRecord model to be organised as a tree structure (or hierarchy). It uses a single, intuitively formatted database column, using a variation on the materialised path pattern. It exposes all the standard tree structure relations (ancestors, parent, root, children, siblings, descendants) and all of them can be fetched in a single sql query. Additional features are STI support, named_scopes, depth caching, depth constraints, easy migration from older plugins/gems, integrit...

Fixing Webrat after following an external link

When a Cucumber feature leaves your page through an external Link, Webrat has problems like "Could not find field: "E-mail" (Webrat::NotFoundError)" using your page afterwards. It will also have trouble following redirects.

Fix it with this step:

Given /^I am back on my page$/ do
  webrat_session.header("Host", "www.example.com")
end

Cucumber Webrat steps

Most of these will not work in newer projects because these use the Capybara/Rack::Test combo in lieu of Webrat.

Find input fields

Then /^there should be a "([^"]+)" field$/ do |name|
  lambda { webrat.current_scope.send(:locate_field, name) }.should_not raise_error(Webrat::NotFoundError)
end

Then /^there should be no "([^"]+)" field$/ do |name|
  lambda { webrat.current_scope.send(:locate_field, name) }.should raise_error(Webrat::NotFoundError)
end

Find html content

Then /^I should see "([^\"]*)...

Aggregated RSpec/Cucumber test coverage with RCov

With defaults, RCov doesn't work the way you how you would like it to. To create a nice test coverage report, copy the attached file to lib/tasks/rcov.rake. After that rake rcov:all will run all RSpec examples and Cucumber features. The report will be written RAILS_ROOT/coverage/index.html.

Here is what the task does in detail:

  • Generates aggregated coverage of both RSpec and Cucumber
  • Works with Rails 2 and Rails 3
  • Reports for app/**/*.rb and nothing else
  • If called with an environment variable IGNORE_SHARED_TRAITS=true it ...

Better output for Cucumber

We built cucumber_spinner to have a progress bar for Cucumber features, which also outputs failing scenarios as soon as they fail.

Installation

gem install cucumber_spinner

Usage

cucumber --format CucumberSpinner::ProgressBarFormatter

If you use CucumberSpinner::CuriousProgressBarFormatter and a feature fails, the according page will show up in your browser.


Note that if you run your Cucumber tests using the [cuc](https://makandracards.com/makandra/1277-a-nicer-way-to-...

Concurrent Tests

Install gem and plugin

sudo gem install parallel
script/plugin install git://github.com/grosser/parallel_tests.git

Adapt config/database.yml

test:
  database: xxx_test<%= ENV['TEST_ENV_NUMBER'] %>

Create test databases

script/dbconsole -p
CREATE DATABASE `xxx_test2`;
...

Generate RSpec files

script/generate rspec

(you'll probably only let it overwrite files in script/)

Prepare test databases...

Run a single Cucumber feature

script/cucumber features/feature_name.feature

Or, if you don't care about speed, you can use rake:

rake features FEATURE=features/feature_name.feature

Squashing several Git commits into a single commit

This note shows how to merge an ugly feature branch with multiple dirty WIP commits back into the master as one pretty commit.

Squashing commits with git rebase

What we are describing here will destroy commit history and can go wrong. For this reason, do the squashing on a separate branch:

git checkout -b squashed_feature

This way, if you screw up, you can go back to your original branch, make another branch for squashing and try again.

Tip

If you didn't make a backup branch and something ...

Typical .gitignore

log/*
tmp/*
storage/*
db/*.sqlite3
db/schema.rb
db/structure.sql
public/system
.project
.idea/
public/javascripts/all*
public/stylesheets/all*
public/stylesheets/*.css
config/database.yml
*~
*#*
.#*
.DS_Store
webrat-*.html
capybara-*.html
rerun.txt
coverage.data
coverage/*
dump_for_download.dump
.~lock.*
.*.swp
C:\\nppdf32Log\\debuglog.txt