Skip to content
This repository

Experiment Driven Development for Ruby

README.rdoc

Vanity

Build
Status

Vanity is an A/B testing framework for Rails that is datastore agnostic.

A/B Testing With Rails

Step 1: Start using Vanity in your Rails application

Step 1.1

Rails 3 & Rails 4 installation

Add to your Gemfile:

gem "vanity"
Rails 2.x installation
Rails::Initializer.run do |config|
  gem.config "vanity"

  config.after_initialize do
    require "vanity"
  end
end

Step 1.2

Choose a datastore that best fits your needs and preferences for storing experiment results. Choose one of: Redis, MongoDB or an SQL database. While Redis is usually faster, it may add additional complexity to your stack. Datastores should be configured using a config/vanity.yml.

Redis Setup

Add to your Gemfile:

gem "redis", ">= 2.1"
gem "redis-namespace", ">= 1.1.0"

By default Vanity is configured to use Redis on localhost port 6379 with database 0.

MongoDB Setup

Add to your Gemfile:

gem "bson_ext"
gem "mongo"

A sample config/vanity.yml might look like:

development:
  adapter: mongodb
  database: analytics
test:
  collecting: false
production:
  adapter: mongodb
  database: analytics
SQL Database Setup

Vanity supports multiple SQL stores (like MySQL, MariaDB, Postgres, Sqlite, etc.) using ActiveRecord, which is built into Rails. If you're using DataMapper, Sequel or another persistence framework, add to your Gemfile:

gem "active_record"

A sample config/vanity.yml might look like:

development:
  adapter: active_record
  active_record_adapter: sqlite3
  database: db/development.sqlite3
test:
  collecting: false
production:
  adapter: active_record
  active_record_adapter: mysql
  database: vanity_test
  pool: 5
  timeout: 5000

If you're going to store data in the database, run the generator and migrations to create the database schema:

$ rails generate vanity
$ rake db:migrate

Step 1.3

Turn Vanity on, and pass a reference to a method that identifies a user. For example:

class ApplicationController < ActionController::Base
  use_vanity :current_user
  layout false  # exclude this if you want to use your application layout
end

For more information, please see the identity documentation.

Step 2: Define your first A/B test

This experiment goes in the file experiments/price_options.rb:

ab_test "Price options" do
  description "Mirror, mirror on the wall, who's the better price of all?"
  alternatives 19, 25, 29
  metrics :signups
end

If the experiment uses a metric as above (“signups”), there needs to be a corresponding ruby file for that metric, experiments/metrics/signups.rb.

metric "Signup (Activation)" do
  description "Measures how many people signed up for our awesome service."
end

Step 3: Present the different options to your users

<h2>Get started for only $<%= ab_test :price_options %> a month!</h2>

Step 4: Measure conversion

Conversions are created via the track! method. For example:

class SignupController < ApplicationController
  def signup
    @account = Account.new(params[:account])
    if @account.save
      track! :signups
      redirect_to @acccount
    else
      render action: :offer
    end
  end
end

Step 5: Check the report:

vanity report --output vanity.html

To view metrics and experiment results with the dashboard in Rails 3 & Rails 4:

rails generate controller --helper=false Vanity

In config/routes.rb, add:

match '/vanity(/:action(/:id(.:format)))', :controller => :vanity, :via => [:get, :post]

The controller should look like:

class VanityController < ApplicationController
  include Vanity::Rails::Dashboard
end

Registering participants with Javascript

If robots or spiders make up a significant portion of your sites traffic they can affect your conversion rate. Vanity can optionally add participants to the experiments using asynchronous javascript callbacks, which will keep many robots out. For those robots that do execute Javascript and are well-behaved (like Googlebot), Vanity filters out requests based on their user-agent string.

To set this up simply do the following:

  • Add Vanity.playground.use_js!

  • Set Vanity.playground.add_participant_path = '/path/to/vanity/action', this should point to the add_participant path that is added with Vanity::Rails::Dashboard, make sure that this action is accessible by all users (ie does not require authentication).

  • Add <%= vanity_js %> to any page that XX an ab_test. vanity_js needs to be included after your call to ab_test so that it knows which version of the experiment the participant is a member of. The helper will render nothing if the there are no ab_tests running on the current page, so adding vanity_js to the bottom of your layouts is a good option. Keep in mind that if you call use_js! and don't include vanity_js in your view no participants will be recorded.

Compatibility

Here's what's tested and known to work:

Ruby 1.8.7
  Persistence: Redis, Mongo, ActiveRecord
  Rails: 2.3, 3, 3.1, 3.2
Ruby 1.9.3
  Persistence: Redis, Mongo, ActiveRecord
  Rails: 3, 3.1, 3.2, 4.0
Ruby 2.0
  Persistence: Redis, Mongo, ActiveRecord
  Rails: 3.2, 4.0

Testing

For view tests/specs or integration testing, it's handy to set the outcome of an experiment. This may be done using the chooses method. For example:

Vanity.playground.experiment(:price_options).chooses(19)

Contributing

  • Fork the project

  • Please use a topic branch to make your changes, it's easier to test them that way

  • To set up the test suite run bundler, then run `rake appraisal:install` to prepare the test suite to run against multiple versions of Rails

  • Fix, patch, enhance, document, improve, sprinkle pixie dust

  • At minimum run `rake appraisal test`, if possible, please run rake test:all

  • Tests. Please. Run rake test, of if you can, rake test:all

  • Send a pull request on GitHub

Credits/License

Original code, copyright of Assaf Arkin, released under the MIT license.

Documentation available under the Creative Commons Attribution license.

For full list of credits and licenses: vanity.labnotes.org/credits.html.

Something went wrong with that request. Please try again.