Benito Serna Tips and tools for Ruby on Rails developers

Refactoring my old cucumber tests

May 12, 2012

Like a year ago, my style to write cucumber test was to use the cucumber’s web steps, the most I can, and the results were some tests like this one.

Feature: Manage categories

  In order to clasify the brand products
  As an admin
  I want to assign categories to a product

  Background:
    Given the following brand records
      | name         | description              |
      | GP:50        | GP:50 description        |
      | Zenith Pumps | Zenith Pumps description |
    And the following product records of "GP:50"
      | name                    | description                 |
      | Medidor de Presion 311  | Descripcion del medidor     |
      | Medidor de Presion Melt | Descrpcion del medidor melt |
    And the following category records for the brand "GP:50"
      | name          |
      | Melt Pressure |
      | Industrial    |
    And the following category record
      | name                |
      | Pressure Transducer |
    And I add the category "Melt Pressure" to the product "Medidor de Presion Melt"
    And I add the category "Pressure Transducer" to the product "Medidor de Presion Melt"

  Scenario: Watching the product categories
    Given I am an admin
    When I go to admin dashboard
    And I follow "Marcas"
    And I follow "GP:50"
    And I follow "Productos" within "#admin-brand-menu"
    And I follow "Medidor de Presion Melt"
    And I follow "Categorías" within "#admin-product-menu"
    Then I should see "Melt Pressure" within "#brand-categories"
    And I should see "Pressure Transducer" within "#jazz-categories"

  Scenario: Add a brand category
    Given I am an admin
    When I go to admin dashboard
    And I follow "Marcas"
    And I follow "GP:50"
    And I follow "Productos" within "#admin-brand-menu"
    And I follow "Medidor de Presion 311"
    And I follow "Categorías" within "#admin-product-menu"
    And I follow "Add Brand Category"
    And I select "Industrial" from "Category"
    And I press "Add brand category"
    Then I should see "Industrial" within "#brand-categories"

  Scenario: Remove a category
    Given I am an admin
    When I go to admin dashboard
    And I follow "Marcas"
    And I follow "GP:50"
    And I follow "Productos" within "#admin-brand-menu"
    And I follow "Medidor de Presion Melt"
    And I follow "Categorías" within "#admin-product-menu"
    And I follow "Remove"
    Then I should not see "Melt Pressure"

At that time I thought this was cool, because it was very expresive. But today I return to this piece of code and I realize that this was not true. All that lines and all that repetition, can not be good. Also this Feature was pretty slow. After the rails load (that is so long), it spent 10.78 seconds of my life, now imagine the time for all the features :( ….

Today, my style is a little different, now I try to write the cucumber scenarios, thinking in a very high level. Because I write cucumber tests, to make me think in all the stuff that the feature needs.

Today I refactor this test, and the result is this.

Feature: Manage categories

  In order to clasify the brand products
  As an admin
  I want to assign categories to a product

  Scenario: Manage product categories
    Given a brand with a category and a product
    And I am an admin
    When I add the brand category to the product 
    Then I see the category in the product 
    When I remove the category of the product 
    Then I don't see the category in the product

Now the test run in 2.83 seconds (after the rails load), and this file has 46 lines less :).

The test is using a little more of capybara in the steps. So this are the steps.

Given "a brand with a category and a product" do
  @brand = Factory :brand_with_category_and_product
  @category = @brand.categories.first
  @product  = @brand.products.first
end

When "I add the brand category to the product" do
  visit new_product_category_path(@product)
  select @category.name, from: "Category"
  click_button "Add brand category"
end

Then "I see the category in the product" do
  within "#brand-categories" do 
    page.should have_content @category.name
  end
end

When "I remove the category of the product" do
  click_link "Remove"
end

Then "I don't see the category in the product" do
  page.should_not have_content @category.name
end

I dont’t know if this is the best way to make cucumber tests, but at this time, is what I normally do.

:)

Related articles

Weekly tips and tools for Ruby on Rails developers

I send an email each week, trying to share knowledge and fixes to common problems and struggles for ruby on rails developers, like How to fetch the latest-N-of-each record or How to test that an specific mail was sent or a Capybara cheatsheet. You can see more examples on Most recent posts or All post by topic.