README.md in field_test-0.2.4 vs README.md in field_test-0.3.0
- old
+ new
@@ -1,15 +1,17 @@
# Field Test
:maple_leaf: A/B testing for Rails
- Designed for web and email
-- Comes with a [handy dashboard](https://fieldtest.dokkuapp.com/)
+- Comes with a [dashboard](https://fieldtest.dokkuapp.com/) to view results and update variants
- Seamlessly handles the transition from anonymous visitor to logged in user
Uses [Bayesian statistics](https://www.evanmiller.org/bayesian-ab-testing.html) to evaluate results so you don’t need to choose a sample size ahead of time.
+[![Build Status](https://travis-ci.org/ankane/field_test.svg?branch=master)](https://travis-ci.org/ankane/field_test)
+
## Installation
Add this line to your application’s Gemfile:
```ruby
@@ -17,20 +19,21 @@
```
Run:
```sh
-rails g field_test:install
+rails generate field_test:install
+rails db:migrate
```
And mount the dashboard in your `config/routes.rb`:
```ruby
mount FieldTest::Engine, at: "field_test"
```
-Be sure to [secure the dashboard](#security) in production.
+Be sure to [secure the dashboard](#dashboard-security) in production.
![Screenshot](https://ankane.github.io/field_test/screenshot6.png)
## Getting Started
@@ -43,16 +46,22 @@
- red
- green
- blue
```
-Refer to it in views, controllers, and mailers.
+Refer to it in controllers, views, and mailers.
```ruby
button_color = field_test(:button_color)
```
+To make testing easier, you can specify a variant with query parameters
+
+```
+http://localhost:3000/?field_test[button_color]=green
+```
+
When someone converts, record it with:
```ruby
field_test_converted(:button_color)
```
@@ -65,27 +74,65 @@
winner: green
```
All calls to `field_test` will now return the winner, and metrics will stop being recorded.
-## Features
+You can get the list of experiments and variants for a user with:
-You can specify a variant with query parameters to make testing easier
+```ruby
+field_test_experiments
+```
+## JavaScript and Native Apps
+
+For JavaScript and native apps, add calls to your normal endpoints.
+
+```ruby
+class CheckoutController < ActionController::API
+ def start
+ render json: {button_color: field_test(:button_color)}
+ end
+
+ def finish
+ field_test_converted(:button_color)
+ # ...
+ end
+end
```
-?field_test[button_color]=green
+
+For anonymous visitors in native apps, pass a `Field-Test-Visitor` header with a unique identifier.
+
+## Participants
+
+Any model or string can be a participant in an experiment.
+
+For web requests, it uses `current_user` (if it exists) and an anonymous visitor id to determine the participant. Set your own with:
+
+```ruby
+class ApplicationController < ActionController::Base
+ def field_test_participant
+ current_company
+ end
+end
```
-Assign a specific variant to a user with:
+For mailers, it tries `@user` then `params[:user]` to determine the participant. Set your own with:
```ruby
-experiment = FieldTest::Experiment.find(:button_color)
-experiment.variant(participant, variant: "green")
+class ApplicationMailer < ActionMailer::Base
+ def field_test_participant
+ @company
+ end
+end
```
-You can also change a user’s variant from the dashboard.
+You can also manually pass a participant with:
+```ruby
+field_test(:button_color, participant: company)
+```
+
## Config
By default, bots are returned the first variant and excluded from metrics. Change this with:
```yml
@@ -124,24 +171,39 @@
weights:
- 85
- 15
```
+To help with GDPR compliance, you can switch from cookies to [anonymity sets](https://privacypatterns.org/patterns/Anonymity-set) for anonymous visitors. Visitors with the same IP mask and user agent are grouped together.
+
+```yml
+cookies: false
+```
+
+## Dashboard Config
+
If the dashboard gets slow, you can make it faster with:
```yml
cache: true
```
This will use the Rails cache to speed up winning probability calculations.
-## Funnels
+If you need more precision, set:
+```yml
+precision: 1
+```
+
+## Multiple Goals
+
You can set multiple goals for an experiment to track conversions at different parts of the funnel. First, run:
```sh
-rails g field_test:events
+rails generate field_test:events
+rails db:migrate
```
And add to your config:
```yml
@@ -160,24 +222,34 @@
The results for all goals will appear on the dashboard.
## Analytics Platforms
-You can also send experiment data to analytics platforms like [Google Analytics](https://www.google.com/analytics/), [Mixpanel](https://mixpanel.com/), and [Ahoy](https://github.com/ankane/ahoy). Use:
+You may also want to send experiment data as properties to other analytics platforms like [Segment](https://segment.com), [Amplitude](https://amplitude.com), and [Ahoy](https://github.com/ankane/ahoy). Get the list of experiments and variants with:
```ruby
field_test_experiments
```
-to get all experiments and variants for a participant and pass them as properties.
+### Ahoy
-## Security
+You can configure Field Test to use Ahoy’s visitor token instead of creating its own:
+```ruby
+class ApplicationController < ActionController::Base
+ def field_test_participant
+ [ahoy.user, ahoy.visitor_token]
+ end
+end
+```
+
+## Dashboard Security
+
#### Devise
```ruby
-authenticate :user, -> (user) { user.admin? } do
+authenticate :user, ->(user) { user.admin? } do
mount FieldTest::Engine, at: "field_test"
end
```
#### Basic Authentication
@@ -187,16 +259,107 @@
```ruby
ENV["FIELD_TEST_USERNAME"] = "moonrise"
ENV["FIELD_TEST_PASSWORD"] = "kingdom"
```
-## Credits
+## Reference
-A huge thanks to [Evan Miller](https://www.evanmiller.org/) for deriving the Bayesian formulas.
+Assign a specific variant to a user with:
-## TODO
+```ruby
+experiment = FieldTest::Experiment.find(:button_color)
+experiment.variant(participant, variant: "green")
+```
-- Code samples for analytics platforms
+You can also change a user’s variant from the dashboard.
+
+To associate models with field test memberships, use:
+
+```ruby
+class User < ApplicationRecord
+ has_many :field_test_memberships, class_name: "FieldTest::Membership", as: :participant
+end
+```
+
+Now you can do:
+
+```ruby
+user.field_test_memberships
+```
+
+## Upgrading
+
+### 0.3.0
+
+Upgrade the gem and add to `config/field_test.yml`:
+
+```yml
+legacy_participants: true
+```
+
+Also, if you use Field Test in emails, know that the default way participants are determined has changed. Restore the previous way with:
+
+```ruby
+class ApplicationMailer < ActionMailer::Base
+ def field_test_participant
+ message.to.first
+ end
+end
+```
+
+We also recommend upgrading participants when you have time.
+
+#### Upgrading Participants
+
+Field Test 0.3.0 splits the `field_test_memberships.participant` column into `participant_type` and `participant_id`.
+
+To upgrade without downtime, create a migration:
+
+```sh
+rails generate migration upgrade_field_test_participants
+```
+
+with:
+
+```ruby
+class UpgradeFieldTestParticipants < ActiveRecord::Migration[5.2]
+ def change
+ add_column :field_test_memberships, :participant_type, :string
+ add_column :field_test_memberships, :participant_id, :string
+
+ add_index :field_test_memberships, [:participant_type, :participant_id, :experiment],
+ unique: true, name: "index_field_test_memberships_on_participant_and_experiment"
+ end
+end
+```
+
+After you run it, writes will go to both the old and new sets of columns.
+
+Next, backfill data:
+
+```ruby
+FieldTest::Membership.where(participant_id: nil).find_each do |membership|
+ participant = membership.participant
+
+ if participant.include?(":")
+ participant_type, _, participant_id = participant.rpartition(":")
+ participant_type = nil if participant_type == "cookie" # legacy
+ else
+ participant_id = participant
+ end
+
+ membership.update!(
+ participant_type: participant_type,
+ participant_id: participant_id
+ )
+end
+```
+
+Finally, remove `legacy_participants: true` from the config file. Once you confirm it’s working, you can drop the `participant` column (you can rename it first just to be extra safe).
+
+## Credits
+
+A huge thanks to [Evan Miller](https://www.evanmiller.org/) for deriving the Bayesian formulas.
## History
View the [changelog](https://github.com/ankane/field_test/blob/master/CHANGELOG.md)