Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions README.mdown
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,35 @@ Split.configure do |config|
end
```

### Trial Event Hooks

You can define methods that will be called at the same time as experiment
alternative participation and goal completion.

For example:

``` ruby
Split.configure do |config|
config.on_trial_choose = :log_trial_choice
config.on_trial_complete = :log_trial_complete
end
```

Set these attributes to a method name available in the same context as the
`ab_test` method. These methods should accept one argument, a `Trial` instance.

``` ruby
def log_trial_choose(trial)
logger.info "experiment=%s alternative=%s user=%s" %
[ trial.experiment.name, trial.alternative, current_user.id ]
end

def log_trial_complete(trial)
logger.info "experiment=%s alternative=%s user=%s complete=true" %
[ trial.experiment.name, trial.alternative, current_user.id ]
end
```

## Web Interface

Split comes with a Sinatra-based front end to get an overview of how your experiments are doing.
Expand Down
2 changes: 2 additions & 0 deletions lib/split/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ class Configuration
attr_accessor :persistence
attr_accessor :algorithm
attr_accessor :store_override
attr_accessor :on_trial_choose
attr_accessor :on_trial_complete

attr_reader :experiments

Expand Down
11 changes: 11 additions & 0 deletions lib/split/helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ def finish_experiment(experiment, options = {:reset => true})
alternative_name = ab_user[experiment.key]
trial = Trial.new(:experiment => experiment, :alternative => alternative_name, :goals => options[:goals])
trial.complete!
call_trial_complete_hook(trial)

if should_reset
reset!(experiment)
else
Expand Down Expand Up @@ -178,6 +180,7 @@ def start_trial(trial)
ret = ab_user[experiment.key]
else
trial.choose!
call_trial_choose_hook(trial)
ret = begin_experiment(experiment, trial.alternative.name)
end
end
Expand All @@ -186,6 +189,14 @@ def start_trial(trial)
ret
end

def call_trial_choose_hook(trial)
send(Split.configuration.on_trial_choose, trial) if Split.configuration.on_trial_choose
end

def call_trial_complete_hook(trial)
send(Split.configuration.on_trial_complete, trial) if Split.configuration.on_trial_complete
end

def keys_without_experiment(keys, experiment_key)
keys.reject { |k| k.match(Regexp.new("^#{experiment_key}(:finished)?$")) }
end
Expand Down
16 changes: 16 additions & 0 deletions spec/helper_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,14 @@
end
end

context "when on_trial_choose is set" do
before { Split.configuration.on_trial_choose = :some_method }
it "should call the method" do
self.should_receive(:some_method)
ab_test('link_color', 'blue', 'red')
end
end

it "should allow passing a block" do
alt = ab_test('link_color', 'blue', 'red')
ret = ab_test('link_color', 'blue', 'red') { |alternative| "shared/#{alternative}" }
Expand Down Expand Up @@ -247,6 +255,14 @@
doing_other_tests?(@experiment.key).should be false
end

context "when on_trial_complete is set" do
before { Split.configuration.on_trial_complete = :some_method }
it "should call the method" do
self.should_receive(:some_method)
finished(@experiment_name)
end
end

end

context "finished with config" do
Expand Down