rails_ab_test 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +153 -8
- data/lib/rails_ab_test.rb +2 -1
- data/lib/rails_ab_test/controller.rb +36 -0
- data/lib/rails_ab_test/helper.rb +29 -0
- data/lib/rails_ab_test/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1eab8c6bad3e294a01e3450bfd378a172caa48ae
|
4
|
+
data.tar.gz: 8c76e60529064f64209412bc1695b2329c539bdc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 91988263e562a86f21e290cb4e3424ae7508ffd5ffceabeb1c14f7d7b0fd82d9226b40f44f504a478f16fb84e63e60a923f0a1badd59eeb0434fe0d43a57d191
|
7
|
+
data.tar.gz: 0d46ed3f864cbdacf2b187c9f59910a44b7c1f8e3d83008d086b7416390b3355bd1d242a07143e78b7de7b875daa4977019073978e4aea0983f629bda4961334
|
data/README.md
CHANGED
@@ -1,8 +1,11 @@
|
|
1
1
|
# RailsAbTest
|
2
2
|
|
3
|
-
|
3
|
+
Perform A/B Testing in your Rails app with ease.
|
4
4
|
|
5
|
-
|
5
|
+
The idea is a combination of
|
6
|
+
|
7
|
+
- minimal Code to support A/B Test versioning, is provided by this gem.
|
8
|
+
- A simple Pattern to organize the code in views into separated versions for each A/B Test version.
|
6
9
|
|
7
10
|
## Installation
|
8
11
|
|
@@ -22,20 +25,162 @@ Or install it yourself as:
|
|
22
25
|
|
23
26
|
## Usage
|
24
27
|
|
25
|
-
|
28
|
+
Let's start with the simplest usage case:
|
29
|
+
|
30
|
+
### The Code
|
31
|
+
|
32
|
+
Configure your controllers by including the module, normally `ApplicationController` is a good candidate for this:
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
include RailsAbTest::Controller
|
36
|
+
```
|
37
|
+
|
38
|
+
Then for the action (`index` in the example) that will be A/B Tested set a `before_filter`:
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
# a controller
|
42
|
+
before_filter :choose_ab_test, only: :index
|
43
|
+
```
|
44
|
+
|
45
|
+
The method `choose_ab_test` will randomly (with 50% probability) choose A or B as the A/B Test version.
|
46
|
+
From here the version chosen will be accessible in your views and helpers in the variable `@ab_test`.
|
47
|
+
|
48
|
+
Then inside the action you need to replace `render` with `render_ab`
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
# a controller
|
52
|
+
def index
|
53
|
+
render_ab
|
54
|
+
end
|
55
|
+
```
|
56
|
+
|
57
|
+
`render_ab` will infer the template to render from the action name, and prepend it with `@ab_test` to fully
|
58
|
+
determine the template name. i.e. if the A/B Version is A it will render the template `index_A`.
|
59
|
+
|
60
|
+
### The Pattern
|
26
61
|
|
27
|
-
|
62
|
+
Now you need to make 2 copies of your `index` view template, and name it `index_A` for the A/B Test version A, and
|
63
|
+
`index_B` for B.
|
28
64
|
|
29
|
-
|
65
|
+
Make sure you set up different tracking for each version and you are good to go. Your controller's `index` action is ready to be A/B Tested.
|
66
|
+
|
67
|
+
## QA and Test support
|
68
|
+
|
69
|
+
For testing and QA purposes the A/B Test version can be selected by appending `?ab_test=A` to the url of the page,
|
70
|
+
that will make sure the version A is selected.
|
71
|
+
|
72
|
+
## More complex usage
|
73
|
+
|
74
|
+
### More versions that just A and B
|
75
|
+
|
76
|
+
Then instead of a `before_filter` you can call the method `choose_ab_test` directly:
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
# a controller
|
80
|
+
def show
|
81
|
+
choose_ab_test ['A', 'B', 'C'] # this action calls the method directly instead
|
82
|
+
render_ab
|
83
|
+
end
|
84
|
+
```
|
85
|
+
|
86
|
+
Again the 3 versions will have the same probability of being chosen.
|
87
|
+
|
88
|
+
*NOTE:* in the current version the gem only supports versions with equal probabilities each.
|
89
|
+
|
90
|
+
### 2 actions 1 template
|
91
|
+
|
92
|
+
Imagine that the actions `index` and `archive` are both A/B versioned and they share the same template. The action `index` will not change, but `archive` needs to explicitly render the `index` template like this:
|
93
|
+
|
94
|
+
```ruby
|
95
|
+
# a controller
|
96
|
+
before_filter :choose_ab_test, only: :index, :archive
|
97
|
+
|
98
|
+
def archive
|
99
|
+
render_ab template: 'index'
|
100
|
+
end
|
101
|
+
```
|
30
102
|
|
31
|
-
|
103
|
+
### Versioned partials
|
104
|
+
|
105
|
+
If instead of a full page template only a partial is going to be A/B Tested, you can achieve like this:
|
106
|
+
|
107
|
+
```ruby
|
108
|
+
# index.haml.html template
|
109
|
+
= render_ab partial: 'menu', variable_for_the_partial: @variable
|
110
|
+
```
|
111
|
+
|
112
|
+
The pattern again here is to make 2 copies of the `_menu` partial and name them, i.e. `_menu_A` and `_menu_B`.
|
113
|
+
|
114
|
+
### Versioned html snippets and partials
|
115
|
+
|
116
|
+
Based on the variable `@ab_test` you can also make conditions in views and helpers:
|
117
|
+
|
118
|
+
```ruby
|
119
|
+
# index.haml.html template
|
120
|
+
- if @ab_test == 'A'
|
121
|
+
version A is rendered
|
122
|
+
- else
|
123
|
+
hello B
|
124
|
+
```
|
125
|
+
|
126
|
+
```ruby
|
127
|
+
# a view helper
|
128
|
+
def helper_method_AB_versioned
|
129
|
+
if @ab_test == 'A'
|
130
|
+
'version A is rendered'
|
131
|
+
else
|
132
|
+
'Hello B'
|
133
|
+
end
|
134
|
+
end
|
135
|
+
```
|
136
|
+
|
137
|
+
### Several pages sharing the same A/B version
|
138
|
+
|
139
|
+
Now imagine that the `index` actions of 2 controllers (e.g. `posts` and `authors`) are A/B versioned,
|
140
|
+
and that you want that when an user sees version A of `posts#index` she should also see version A of `authors#index`.
|
141
|
+
|
142
|
+
This can be achieved by overriding the method `choose_ab_test` in both controllers, and using a cookie:
|
143
|
+
|
144
|
+
```ruby
|
145
|
+
# posts controller
|
146
|
+
before_filter :choose_ab_test, only: :index
|
147
|
+
|
148
|
+
...
|
149
|
+
|
150
|
+
def choose_ab_test
|
151
|
+
@ab_test = cookies['shared-version-posts-authors'] || super
|
152
|
+
cookies['shared-version-posts-authors'] = @ab_test
|
153
|
+
end
|
154
|
+
|
155
|
+
# authors controller should have the same code as above
|
156
|
+
```
|
157
|
+
|
158
|
+
Of course you can extract the common code to a central place. Also name the cookie with a name that makes sense for you, and expire it, sign it or encrypt it as needed.
|
159
|
+
|
160
|
+
### Cookies to persist versions
|
161
|
+
|
162
|
+
If an user should always see the same A/B version of a page, the same method above and a cookie work perfectly:
|
163
|
+
|
164
|
+
```ruby
|
165
|
+
# a controller
|
166
|
+
before_filter :choose_ab_test, only: :index
|
167
|
+
|
168
|
+
...
|
169
|
+
|
170
|
+
def choose_ab_test
|
171
|
+
@ab_test = cookies['shared-version-posts-authors'] || super
|
172
|
+
cookies['shared-version-posts-authors'] = @ab_test
|
173
|
+
end
|
174
|
+
```
|
32
175
|
|
33
176
|
## Contributing
|
34
177
|
|
35
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
178
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/joahking/rails_ab_test.
|
36
179
|
|
180
|
+
## TODOs
|
181
|
+
|
182
|
+
- write tests
|
37
183
|
|
38
184
|
## License
|
39
185
|
|
40
186
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
41
|
-
|
data/lib/rails_ab_test.rb
CHANGED
@@ -0,0 +1,36 @@
|
|
1
|
+
# Public: helper methods for ApplicationController to generate A/B testing version.
|
2
|
+
#
|
3
|
+
module RailsAbTest
|
4
|
+
module Controller
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
include RailsAbTest::Helper
|
9
|
+
helper RailsAbTest::Helper
|
10
|
+
end
|
11
|
+
|
12
|
+
protected
|
13
|
+
|
14
|
+
# Internal: generates the AB version, i.e. randomly (50%) "A" or "B".
|
15
|
+
# Examples
|
16
|
+
# before_filter :choose_ab_test or read README for other examples.
|
17
|
+
#
|
18
|
+
# The version s accessible in controllers, views and helpers as @ab_test.
|
19
|
+
#
|
20
|
+
# For testing/QA purposes: If the parameter ab_test=A is appended to the url,
|
21
|
+
# the version passed is used.
|
22
|
+
#
|
23
|
+
# TODO: should/can be extended to:
|
24
|
+
# - accept different probabilities of each version to e.g. 75%, 25%
|
25
|
+
#
|
26
|
+
def choose_ab_test(ab_tests: ['A', 'B'])
|
27
|
+
@ab_test = if ab_tests.include? params[:ab_test]
|
28
|
+
# support to test/QA page versions
|
29
|
+
params[:ab_test]
|
30
|
+
else
|
31
|
+
ab_tests.sample # randomize A/B Test version
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# Public: helpers for your controllers and views.
|
2
|
+
#
|
3
|
+
module RailsAbTest
|
4
|
+
module Helper
|
5
|
+
|
6
|
+
# Public: renders A/B Test versions of same template/partial.
|
7
|
+
#
|
8
|
+
# options - hash to determine whether to render a template or a partial. Optional.
|
9
|
+
# If not passed it renders a template by controller.action_name. Default.
|
10
|
+
#
|
11
|
+
# Examples:
|
12
|
+
# to render a template use:
|
13
|
+
# render_ab template: 'template_name'
|
14
|
+
#
|
15
|
+
# to render a partial, the options hash can contain more keys:
|
16
|
+
# render_ab partial: 'partial_name', variable: 'you name it'
|
17
|
+
#
|
18
|
+
def render_ab(options = {})
|
19
|
+
if options[:partial].present?
|
20
|
+
partial = options.delete(:partial)
|
21
|
+
render "#{partial}_#{@ab_test}", options
|
22
|
+
else
|
23
|
+
template = options[:template] || action_name
|
24
|
+
render "#{template}_#{@ab_test}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rails_ab_test
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joaquin Rivera Padron
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-10-
|
11
|
+
date: 2016-10-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -68,6 +68,8 @@ files:
|
|
68
68
|
- bin/console
|
69
69
|
- bin/setup
|
70
70
|
- lib/rails_ab_test.rb
|
71
|
+
- lib/rails_ab_test/controller.rb
|
72
|
+
- lib/rails_ab_test/helper.rb
|
71
73
|
- lib/rails_ab_test/version.rb
|
72
74
|
- rails_ab_test.gemspec
|
73
75
|
homepage: https://github.com/joahking/rails_ab_test
|