Glad You're Ready. Let's Get Started!

Let us know how we can contact you.

Thank you!

We'll respond shortly.

Cucumber: When to Use It, When to Lose It

I had really poor experiences with Cucumber. The annoyance with Cucumber comes nearly all from a case of indirection. If devs are writing the Cucumber tests and then writing all the regular expressions to implement the steps, then you often wonder why the heck you’re not just writing tests in Ruby. 

Read more »

How to write Well-Formed User Stories

Writing Well-Formed User Stories

I've worked closely with the Product team on about a dozen projects in the past few years, and rigorous story-writing is one of the most common areas for low-cost, high-gain improvement. I encourage every team to adopt (or at least consider) these techniques.

From customer requirements to releasable gem

One of the many pleasures of working at Pivotal Labs is that we are encouraged to release some of our work as open source. Often during the course of our engagements, we write code that might have wide-spread use. Due to the nature of our contracts, we can not unilaterally release such code. Those rights belong to the client. And rightly so. So, it is an even greater pleasure when one of our clients believes in "giving back" to the community, as well.

One such example is this modest gem, attribute_access_controllable which allows you to set read-only access at the attribute level, on a per-instance basis. For example, let's say that you have a model Person with an attribute birthday, which, for security purposes, cannot be changed once this attribute is set (except, perhaps, by an administrator with extraordinary privileges). Any future attempts to change this attribute will result in a validation error.


> alice = => '12/12/12')
=> #<Person id: nil, attr1: nil, created_at: nil, updated_at: nil, read_only_attributes: nil, birthday: "0012-12-12">
> alice.attr_read_only(:birthday)
=> #<Set: {"birthday"}>
=> true
> alice.birthday = "2012-12-12"
=> "2012-12-12"
ActiveRecord::RecordInvalid: Validation failed: Birthday is invalid, Birthday is read_only
>!(:skip_read_only => true)
=> true

Setting this up is trivial, thanks to a Rails generator which does most of the heavy lifting for you.

rails generate attribute_access Person

After that, you need only know about one new method added to your class:

#attr_read_only(*attributes) # Marks attributes as read-only

There are a few others, but this one, plus the new functionality added to #save and #save! will get you quite far.

And if that's all that you were looking for when you stumbled across this article, then there's no need to read any further. Go install the gem and have fun (and may your tests be green when you expect them to be).

Interacting with popup windows in Cucumber/Selenium

OAuth providers like LinkedIn often pop-up in a new browser window rather than in Javascript so that the user entering their credentials can see the location bar to be sure they are not being phished by the website requesting their credentials. This is great for security, but not so great for Cucumber testing.


Scenario: Sign Up with LinkedIn
  When I go to the home page
  And I follow "Sign Up"
  And I grant LinkedIn access
  Then I should be on the new user page

My application has a hyperlink that opens the OAuth login on the OAuth provider's website in a new window. Let's presume the simple matter of wiring this up is already coded in my view.

Testing this with Cucumber requires telling the Selenium web driver to interact with the new popup window. We can do this using page.driver.browser.window_handles to find the newest window handle and scoping out actions to that window.


When /^I grant LinkedIn access$/ do
    main, popup = page.driver.browser.window_handles
    within_window(popup) do
      fill_in("Email", :with => "")
      fill_in("Password", :with => "password")
      click_on("Ok, I'll Allow It")

And that's it!

Keep in mind that if you use this test as-is, you will be hitting LinkedIn on the real Internet. This is great if you want a test that will always verify the real API, but not so good for CI, since it is Internet connection-dependent and slow. Consider using something like VCR or Artifice to stub out your service calls.

[Standup][sf] 2011-05-16 Too much cowbell

Needful Things; Help

  • How to test command line applications? Use the old stand-by, expect, patch into the highline library, or the new hotness, aruba (CLI steps for Cucumber).

Very Interesting Things

  • fbAsyncInit does not fire when Facebook is really ready, only kind of sorta, maybe ready.

Waiting for jQuery Ajax calls to finish in Cucumber

You may be asking yourself why you'd want to do this in the first place. Well here's why I would want to do it.

We had some Webdriver based Cucumber tests that passed fine locally but kept failing on our CI box. Our CI box is a bit underpowered at the moment so I thought what might be happening is that our tests weren't waiting long enough for the Ajaxy stuff to happen because the Ajax responses were taking a long time.

After some poking around in the source code of jQuery, I found the $.active property. This property keeps track of the number of active Ajax requests that are going on and I thought this might help us out.

What I came up with was this gist:

I added this step right after my Cucumber step that caused the Ajax call so that Cucumber would wait to move on until I knew that everything was done.

This step solved our CI failures and all was good in our test suite again.

Testing OmniAuth based login via Cucumber

If you haven't looked at OmniAuth for authentication with sites like Google, Github and Facebook, then you should take a look. It is pretty killer.

This morning we needed to write a Cucumber scenario to test that a user could log into the system using Google Apps.

We did a quick spike on getting OminAuth integrated, which was a super simple process, and poked around in the browser to make sure it was working OK.

Thanks to Jose Valim for providing some guidance, via the Devise test suite, on how to get this all up and running.

The basics can be found in this Gist:

I put that code in /features/support/omniauth.rb and then all I need to do is label any scenarios that need to deal with login with an @omniauth_test tag and we are all set.

As our features count grows, I could see us doing this before/after all Cucumber scenarios.

Note: You need to be using 0.2.0.beta5 of OmniAuth to get this to work. Earlier versions don't have the testing functionality built in.

Also Note: This same functionality can be used in good, old RSpec integration tests or Steak tests as well.

Using Cucumber/Capybara with SauceLabs SauceOnDemand

SauceLabs is a cloud based way to test your site against different browsers.

Up until now, they only supported the older Selenium RC based tests.

For those of us using Capybara, we were out of luck because Capybara uses Webdriver.

Well that just changed, they now support Webdriver. Check out the instructions on how to get is set up here.

The one thing that I disagree with in that post is setting the default Capybara driver to :sauce (Capybara.default_driver = :sauce). This seems a little heavy handed to me since I may not want to run all of my scenarios through the Sauce driver.

Upon further review of the source code, it looks like after installing the sauce gem, they redirect any scenarios tagged with @selenium to the Sauce driver. I like this better so if you don't want to switch over all of your scenarios over to Sauce, you can just ignore the line mentioned above and simply tag the scenarios you want to run on Sauce with @selenium.

I haven't had a lot of time to play with this but at least it is a start in getting Capybara based Cucumber scenarios to run against Sauce Labs.

My next step is to figure out how to run one Cucumber scenario to run against multiple browsers on Sauce.

Another thing I'd like to figure out how to do is only run Selenium based tests on demand so they don't run on Sauce every time I run my Cucumber suite. That could run up a decent Sauce bill, especially if you had multiple developers running Cucumber scenarios multiple times a day.

Standup 2010-11-16

Interesting Things

  • Project Sprouts from Luke Bayes "an open-source, cross-platform project generation and configuration tool for ActionScript 2, ActionScript 3, Adobe AIR Flash and Flex projects"

"Project Sprouts was originally designed (as AsProject) to solve a specific set of problems and was later entirely refactored to become a modular set of libraries that are built on top of Ruby, RubyGems and Rake." -- Luke Bayes

"So how will Sencha monetize? The company plans to sell its tools, like Sencha Animator, at a premium. It’ll also offer premium support plans." -- Tech Crunch


"Does anyone have experience with (slower) performance on EC2 compared to Heroku"

Some suggestions:

  • Test network lag
  • The small instance, the default, is just too wimpy to run as an application server
  • Make sure your database instance is big enough, and has enough memory
  • Any experience with RDS?

"Can you run cucumber with its own database instance?"


  • By default, Cuke creates its own environment, but piggy-backs on the test database
  <<: *TEST
  • rake db:test:prepare is wired to :test and won't support a :cucumber in the database.yml without extra rake tasks that have continuing maintenance costs
  • I've used the parallel_tests gem in the past, which has managed to retrofit db:test:prepare to work with multiple test databases, but it did require an extra step after each migration (and it didn't play well with postgres text indexes).

Rails3, Caypbara, Cucumber, FakeWeb…oh my….

While helping client upgrade a Rails 2.3.10 site to Rails 3.0.1, I came across a very perplexing problem with our WebDriver based Cucumber tests that all worked fine under 2.3.10.

We were "randomly" getting some very strange errors from Cucumber having to do with timeout problems and other strangeness like Cucumber not being able to find form fields to fill in.

The solution: 1) require => false for the FakeWeb line in the Gemfile 2) add require 'fakeweb' to the top of the test_helper.rb file

or optionally scrap FakeWeb for either Artifice or WebMock

It has something to do with FakeWeb inserting it into the HTTP stack strangely even if you tell it to allow non-local HTTP requests. We weren't seeing it in 2.3.10 because we were using a cucumber environment to run the cucumber tests. Now under 3.0.1 we run the cucumber tests in the test environment.

I wish I had some more details but I was just happy to move past this strangeness so I didn't really look back.