Purobu

Black-box integration test framework for components on the Heroku platform.

Installation

Install the gem

$ gem install purobu

Usage

Tests go through four phases:

  • Setup the context for the test by creating test fixtures that are required for the System Under Test (SUT) to expose the desired behavior.
  • Exercise the SUT
  • Verify the result to determine if the intended behavior was met.
  • Teardown the state of the system by removing all fixtures and test artifacts so that there are no state spills or interdependencies across tests.

Purobu recognizes and embraces this by defining these phases in implicit blocks within your tests.

For example:

# tests/test_can_create_crane_database.rb
test 'can create crane database' do
  setup do
    heroku "apps:create --name some-app"
  end

  exercise do
    heroku "addons:add heroku-postgresql:crane some-app"
  end

  verify do
    addons = heroku "addons --app some-app"
    addons.include?("heroku-postgresql:crane") #return true or false
  end

  teardown do
    heroku "apps:remove some-app"
  end
end

Then run it with 4 concurrent jobs:

$ purobu -j 4

Purobu will load any files that match /tests/test_.*\.rb/ recursively. An alternative is to specify files to run:

$ purobu -j 4 -f tests/test_one.rb,tests/test_two.rb

For more command line switches, try purobu -h

Global setup

It can be useful to have global setups, for example, to create an app to run a bunch of tests against.

You can create a ruby file called purobu_config.rb to set up a global context. The global context will run once before the entire suite. Be sure to create a global teardown as well:

# purobu_config.rb
Purobu::Configuration.run do |config|
  config.global_setup do
    heroku "apps:create harolds-test-app"
  end
  config.global_teardown do
    heroku "apps:destroy harolds-test-app --confirm harolds-test-app"
  end
end

Interacting with heroku

Access to heroku is facilitated in two ways:

  1. The heroku helper is a wrapper around the latest version of the heroku CLI. You give it a string, and it shells out to execute the given command. For example:
heroku "addons:add heroku-postgresql:dev"
  1. The heroku_api helper exposes the heroku api client for more convenient retreival of information on heroku such as an app's config vars.

Note: To use it, set the HEROKU_API_KEY environment variable or set it in a Purobu::Configuration.run block.

For example:

heroku_api.get_config_vars('some-app').body
  # {"HEROKU_POSTGRESQL_PURPLE_URL"=>"postgres://user:pass@host:5732/database"}
heroku_api.get_addons('some-app').body
  # [{"slug"=>"crane", "selective"=>false,
  #   "configured"=>true,
  #   "url"=>nil,
  #   "state"=>"public",
  #   "group_description"=>"Heroku Postgresql",
  #   "consumes_dyno_hours"=>false,
  #   "price"=>{"cents"=>0, "unit"=>"month"},
  #   "attachment_name"=>"HEROKU_POSTGRESQL_TEAL",
  #   "plan_description"=>"Crane",
  #   "name"=>"heroku-postgresql:crane",
  #   "beta"=>false,
  #   "attachable"=>false,
  #   "description"=>"Heroku Postgres Crane",
  #   "terms_of_service"=>false}]

Adding helpers

You can add helpers to be used across your tests via helpers:

helpers do
  def do_it
    # it does it
  end
end

test do
  verify do
     do_it # it does it
  end
end

Helpers can also be added via the configuration block:

Purobu::Configuration.run do |config|
  config.helpers do
    def do_it
      # it does it
    end
  end
end

A database_connection helper is included which can be used in your tests:

url = 'postgres://user:pass@host/database'
database_connection(url) do |conn|
  conn # a Sequel connection object
end

Running on Heroku

Running a purobu test suite on heroku is trivial.

Add a Gemfile to your project like so:

source :rubygems

ruby '1.9.3'

gem 'pg'
gem 'purobu', '0.0.4'
gem 'clockwork'
gem 'foreman'

And a clock.rb file:

require 'clockwork'
include Clockwork

require 'heroku-api'

every(1.hour, 'run_purobu') do
  Heroku::API.new.post_ps('purobu-dod', 'purobu -v')
end

exprd can be used to track status of the suite and maybe set alerts.

Meta

purobu was created by Harold Giménez