vanity 1.8.4 → 1.9.0.beta

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/.travis.yml +3 -2
  2. data/CHANGELOG +12 -0
  3. data/Gemfile +6 -3
  4. data/Gemfile.lock +12 -10
  5. data/README.rdoc +45 -16
  6. data/Rakefile +14 -9
  7. data/doc/_layouts/page.html +4 -6
  8. data/doc/ab_testing.textile +1 -1
  9. data/doc/configuring.textile +2 -4
  10. data/doc/email.textile +1 -3
  11. data/doc/index.textile +3 -63
  12. data/doc/rails.textile +34 -8
  13. data/gemfiles/rails3.gemfile +12 -3
  14. data/gemfiles/rails3.gemfile.lock +37 -11
  15. data/gemfiles/rails31.gemfile +12 -3
  16. data/gemfiles/rails31.gemfile.lock +37 -11
  17. data/gemfiles/rails32.gemfile +12 -3
  18. data/gemfiles/rails32.gemfile.lock +37 -11
  19. data/gemfiles/rails4.gemfile +12 -3
  20. data/gemfiles/rails4.gemfile.lock +37 -11
  21. data/lib/vanity/adapters/abstract_adapter.rb +4 -0
  22. data/lib/vanity/adapters/active_record_adapter.rb +18 -10
  23. data/lib/vanity/adapters/mock_adapter.rb +8 -4
  24. data/lib/vanity/adapters/mongodb_adapter.rb +11 -7
  25. data/lib/vanity/adapters/redis_adapter.rb +88 -37
  26. data/lib/vanity/commands/report.rb +9 -9
  27. data/lib/vanity/experiment/ab_test.rb +120 -101
  28. data/lib/vanity/experiment/alternative.rb +21 -21
  29. data/lib/vanity/experiment/base.rb +5 -5
  30. data/lib/vanity/experiment/bayesian_bandit_score.rb +51 -51
  31. data/lib/vanity/experiment/definition.rb +10 -10
  32. data/lib/vanity/frameworks/rails.rb +39 -36
  33. data/lib/vanity/helpers.rb +6 -4
  34. data/lib/vanity/metric/active_record.rb +1 -1
  35. data/lib/vanity/metric/base.rb +23 -24
  36. data/lib/vanity/metric/google_analytics.rb +5 -5
  37. data/lib/vanity/playground.rb +118 -24
  38. data/lib/vanity/templates/_report.erb +20 -6
  39. data/lib/vanity/templates/vanity.css +2 -0
  40. data/lib/vanity/version.rb +1 -1
  41. data/test/adapters/redis_adapter_test.rb +106 -1
  42. data/test/dummy/config/database.yml +21 -4
  43. data/test/dummy/config/routes.rb +1 -1
  44. data/test/experiment/ab_test.rb +93 -13
  45. data/test/metric/active_record_test.rb +9 -4
  46. data/test/passenger_test.rb +43 -42
  47. data/test/playground_test.rb +50 -1
  48. data/test/rails_dashboard_test.rb +38 -1
  49. data/test/rails_helper_test.rb +5 -0
  50. data/test/rails_test.rb +66 -15
  51. data/test/test_helper.rb +24 -2
  52. data/vanity.gemspec +0 -2
  53. metadata +45 -57
data/.travis.yml CHANGED
@@ -20,8 +20,9 @@ gemfile:
20
20
  - gemfiles/rails32.gemfile
21
21
  - gemfiles/rails4.gemfile
22
22
  before_script:
23
- - if [[ "`basename $BUNDLE_GEMFILE`" == "Gemfile" ]]; then rvm rubygems --force 1.8.25; fi # Rubygems 2.0.x fails with Rails 2.3
24
- - "mysql -e 'create database vanity_test;' >/dev/null"
23
+ - 'echo ''gem: --no-ri --no-rdoc'' > ~/.gemrc' # skip installing docs for gems
24
+ - if [[ "`basename $BUNDLE_GEMFILE`" == "Gemfile" ]]; then rvm rubygems 1.8.25; fi # Rubygems 2.0.x fails with Rails 2.3
25
+ - if [[ "$DB" == "mysql" ]]; then mysql -e 'create database vanity_test;' >/dev/null; fi
25
26
  #- if [[ "$DB" == "pgsql" ]]; then psql -c 'create database vanity_test;' -U postgres >/dev/null; fi
26
27
  matrix:
27
28
  exclude:
data/CHANGELOG CHANGED
@@ -1,3 +1,15 @@
1
+ == 1.9.0 (2014-01-18)
2
+
3
+ Change order of preference for vanity identity, from highest to lowest: URL param, cookie, method call, assignment. (@phillbaker)
4
+ Add Playground#request_filter for AbTest#choose(s) (@phillbaker)
5
+ Call on_assignment and perform rebalance when using js (@tmandry)
6
+ Add Adapter#experiment_persisted? and check before showing Dashboard. (@phillbaker)
7
+ Show info message at top of report if not collection (@hellochar)
8
+ Add gracefull failover when redis is down/unreachable. (@phillbaker)
9
+ Update README and documentation for clarity. (@nextmat)
10
+ Remove hard Redis gem dependency from gemspec. (@phillbaker)
11
+ Update appraisal to v1.0.0. (@phillbaker)
12
+
1
13
  == 1.8.3 (2013-11-20)
2
14
 
3
15
  Add support for Rails 4. (@phillbaker)
data/Gemfile CHANGED
@@ -9,10 +9,13 @@ gem "rails", "~>2.3.8"
9
9
  gem "passenger", "~>2.0"
10
10
 
11
11
  # Persistence
12
+ gem "redis", ">= 2.1"
13
+ gem "redis-namespace", ">= 1.1.0"
12
14
  gem "bson_ext"
13
15
  gem "mongo"
14
16
  gem "mysql"
15
- gem "pg"
17
+ gem "sqlite3"
18
+ # gem "pg"
16
19
 
17
20
  # Math libraries
18
21
  gem "backports", :platforms => :mri_18
@@ -26,14 +29,14 @@ gem "garb"
26
29
  gem "SystemTimer", "1.2.3", :platforms => :mri_18
27
30
 
28
31
  # Testing
29
- gem "appraisal"
30
-
31
32
  gem "mocha", :require=>false
32
33
  gem "shoulda", :require=>false # Requires test/unit
33
34
  gem "timecop", :require=>false
34
35
  gem "webmock", :require=>false
35
36
 
36
37
  group :development do
38
+ gem "appraisal", ">= 1.0.0.beta2" # For setting up test Gemfiles
39
+
37
40
  gem "jekyll"
38
41
  gem "rake"
39
42
  gem "RedCloth"
data/Gemfile.lock CHANGED
@@ -1,9 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- vanity (1.8.4)
5
- redis (>= 2.1)
6
- redis-namespace (>= 1.1.0)
4
+ vanity (1.8.3)
7
5
 
8
6
  GEM
9
7
  remote: https://rubygems.org/
@@ -23,9 +21,10 @@ GEM
23
21
  addressable (2.2.7)
24
22
  albino (1.3.3)
25
23
  posix-spawn (>= 0.3.6)
26
- appraisal (0.5.2)
24
+ appraisal (1.0.0.beta2)
27
25
  bundler
28
26
  rake
27
+ thor (>= 0.14.0)
29
28
  backports (3.3.5)
30
29
  bson (1.6.0)
31
30
  bson_ext (1.6.0)
@@ -61,7 +60,6 @@ GEM
61
60
  fastthread (>= 1.0.1)
62
61
  rack
63
62
  rake (>= 0.8.1)
64
- pg (0.13.2)
65
63
  posix-spawn (0.3.6)
66
64
  rack (1.1.3)
67
65
  rails (2.3.14)
@@ -72,16 +70,18 @@ GEM
72
70
  activesupport (= 2.3.14)
73
71
  rake (>= 0.8.3)
74
72
  rake (10.1.0)
75
- redis (3.2.0)
76
- redis-namespace (1.5.1)
77
- redis (~> 3.0, >= 3.0.4)
73
+ redis (3.0.6)
74
+ redis-namespace (1.3.2)
75
+ redis (~> 3.0.4)
78
76
  rubystats (0.2.3)
79
77
  shoulda (3.0.1)
80
78
  shoulda-context (~> 1.0.0)
81
79
  shoulda-matchers (~> 1.0.0)
82
80
  shoulda-context (1.0.0)
83
81
  shoulda-matchers (1.0.0)
82
+ sqlite3 (1.3.8)
84
83
  syntax (1.0.0)
84
+ thor (0.18.1)
85
85
  timecop (0.3.5)
86
86
  webmock (1.8.0)
87
87
  addressable (>= 2.2.7)
@@ -94,7 +94,7 @@ PLATFORMS
94
94
  DEPENDENCIES
95
95
  RedCloth
96
96
  SystemTimer (= 1.2.3)
97
- appraisal
97
+ appraisal (>= 1.0.0.beta2)
98
98
  backports
99
99
  bson_ext
100
100
  garb
@@ -104,12 +104,14 @@ DEPENDENCIES
104
104
  mongo
105
105
  mysql
106
106
  passenger (~> 2.0)
107
- pg
108
107
  rack
109
108
  rails (~> 2.3.8)
110
109
  rake
110
+ redis (>= 2.1)
111
+ redis-namespace (>= 1.1.0)
111
112
  rubystats
112
113
  shoulda
114
+ sqlite3
113
115
  timecop
114
116
  vanity!
115
117
  webmock
data/README.rdoc CHANGED
@@ -1,7 +1,7 @@
1
1
  = Vanity
2
2
  {<img src="https://travis-ci.org/assaf/vanity.png?branch=master" alt="Build Status" />}[https://travis-ci.org/assaf/vanity]
3
3
 
4
- Vanity is an Experiment Driven Development framework for Rails.
4
+ Vanity is an A/B testing framework for Rails that is datastore agnostic.
5
5
 
6
6
  * All about Vanity: http://vanity.labnotes.org
7
7
  * On Github: http://github.com/assaf/vanity
@@ -9,12 +9,18 @@ Vanity is an Experiment Driven Development framework for Rails.
9
9
  http://farm3.static.flickr.com/2540/4099665871_497f274f68_o.jpg
10
10
 
11
11
 
12
- == A/B Testing With Rails (In 5 Easy Steps)
12
+ == A/B Testing With Rails
13
13
 
14
14
  === <b>Step 1:</b> Start using Vanity in your Rails application
15
15
 
16
16
  ==== Step 1.1
17
17
 
18
+ ===== Rails 3 & Rails 4 installation
19
+
20
+ Add to your Gemfile:
21
+
22
+ gem "vanity"
23
+
18
24
  ===== Rails 2.x installation
19
25
 
20
26
  Rails::Initializer.run do |config|
@@ -25,27 +31,46 @@ http://farm3.static.flickr.com/2540/4099665871_497f274f68_o.jpg
25
31
  end
26
32
  end
27
33
 
28
- ===== Rails 3 & Rails 4 installation
34
+ ==== Step 1.2
35
+
36
+ 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.
37
+
38
+ ===== Redis Setup
29
39
 
30
40
  Add to your Gemfile:
31
41
 
32
- gem "vanity"
42
+ gem "redis", ">= 2.1"
43
+ gem "redis-namespace", ">= 1.1.0"
33
44
 
34
- ==== Step 1.2
45
+ ===== MongoDB Setup
35
46
 
36
- Choose a method to store experiment results: for Redis or an external tracking mechanism, migrations aren't needed. Mongo is also available. To use a relational database, via ActiveRecord, run the generator and migrations to create the database schema:
47
+ Add to your Gemfile:
48
+
49
+ gem "bson_ext"
50
+ gem "mongo"
51
+
52
+ ===== SQL Database Setup
53
+
54
+ 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:
55
+
56
+ gem "active_record"
57
+
58
+ If you're going to store data in the database, run the generator and migrations to create the database schema:
37
59
 
38
60
  $ rails generate vanity
39
61
  $ rake db:migrate
40
62
 
41
63
  ==== Step 1.3
42
64
 
43
- add to your application controller:
65
+ Turn Vanity on, and pass a reference to a method that identifies a user. For example:
44
66
 
45
67
  class ApplicationController < ActionController::Base
46
68
  use_vanity :current_user
69
+ layout false # exclude this if you want to use your application layout
47
70
  end
48
71
 
72
+ For more information, please see the {identity documentation}[http://vanity.labnotes.org/identity.html].
73
+
49
74
  === <b>Step 2:</b> Define your first A/B test
50
75
 
51
76
  This experiment goes in the file <code>experiments/price_options.rb</code>:
@@ -56,7 +81,11 @@ This experiment goes in the file <code>experiments/price_options.rb</code>:
56
81
  metrics :signups
57
82
  end
58
83
 
59
- NOTE: If using a metric as above ("signups"), there needs to be a corresponding ruby file for that metric. Inside the "experiments" directory create a "metrics" directory with a file called "signups.rb". The contents of the file can describe the signup metric, refer to the "Metrics" Vanity documentation page for an example.
84
+ If the experiment uses a metric as above ("signups"), there needs to be a corresponding ruby file for that metric, <code>experiments/metrics/signups.rb</code>.
85
+
86
+ metric "Signup (Activation)" do
87
+ description "Measures how many people signed up for our awesome service."
88
+ end
60
89
 
61
90
  === <b>Step 3:</b> Present the different options to your users
62
91
 
@@ -88,26 +117,26 @@ To view metrics and experiment results with the dashboard in Rails 3 & Rails 4:
88
117
 
89
118
  In <code>config/routes.rb</code>, add:
90
119
 
91
- match '/vanity(/:action(/:id(.:format)))', :controller => :vanity, :via => :get
120
+ match '/vanity(/:action(/:id(.:format)))', :controller => :vanity, :via => [:get, :post]
92
121
 
93
- Where the controller should looks like:
122
+ The controller should look like:
94
123
 
95
124
  class VanityController < ApplicationController
96
125
  include Vanity::Rails::Dashboard
97
126
  end
98
127
 
99
- NOTE: By default, Vanity turns collection off in development mode. To turn it on, in <code>config/environments/development.rb</code> add:
100
-
101
- Vanity.playground.collecting = true
102
-
103
128
  == Registering participants with Javascript
104
129
 
105
- 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 almost all robots out. To set this up simply do the following:
130
+ 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 almost all robots out. To set this up simply do the following:
106
131
 
107
132
  * Add <code>Vanity.playground.use_js!</code>
108
- * Set <code>Vanity.playground.add_participant_path = '/path/to/vanity/action'</code>, this should point to the add_participant path that is added with Vanity::Rails::Dashboard, make sure that this action is available to all users
133
+ * Set <code>Vanity.playground.add_participant_path = '/path/to/vanity/action'</code>, 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).
109
134
  * Add <code><%= vanity_js %></code> to any page that needs uses an ab_test. <code>vanity_js</code> 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 <code>vanity_js</code> to the bottom of your layouts is a good option. Keep in mind that if you call <code>use_js!</code> and don't include <code>vanity_js</code> in your view no participants will be recorded.
110
135
 
136
+ === <b>Update regarding using AJAX registration to avoid robots</b>
137
+
138
+ As of January 2014, as reported in {issue 175}[https://github.com/assaf/vanity/issues/175], Googlebot is now executing AJAX requests to the original domain of the page, which includes the current implementation of the JS callback. This means that Googlebot-originating requests may be included in experiments, greatly skewing results. A fix is being worked on, please follow the issue for further updates.
139
+
111
140
  == Compatibility
112
141
 
113
142
  Here's what's tested and known to work:
data/Rakefile CHANGED
@@ -1,5 +1,4 @@
1
1
  require "rake/testtask"
2
- require 'appraisal'
3
2
 
4
3
  # -- Building stuff --
5
4
 
@@ -75,10 +74,16 @@ ADAPTERS = %w{redis mongodb mysql}
75
74
 
76
75
  desc "Test using different back-ends"
77
76
  task "test:adapters", :adapter do |t, args|
78
- adapters = args.adapter ? [args.adapter] : ADAPTERS
79
- adapters.each do |adapter|
80
- puts "** Testing #{adapter} adapter"
81
- sh "rake appraisal test DB=#{adapter} #{'--trace' if Rake.application.options.trace}"
77
+ begin # Make sure we have appraisal installed and available
78
+ require "appraisal"
79
+
80
+ adapters = args.adapter ? [args.adapter] : ADAPTERS
81
+ adapters.each do |adapter|
82
+ puts "** Testing #{adapter} adapter"
83
+ sh "rake appraisal test DB=#{adapter} #{'--trace' if Rake.application.options.trace}"
84
+ end
85
+ rescue LoadError
86
+ warn "The appraisal gem must be available"
82
87
  end
83
88
  end
84
89
 
@@ -150,10 +155,10 @@ task :report do
150
155
  Vanity.playground.metrics.values.each(&:destroy!)
151
156
  Vanity.playground.reload!
152
157
 
153
- # Control 182 35 19.23% N/A
154
- # Treatment A 180 45 25.00% 1.33
155
- # Treatment B 189 28 14.81% -1.13
156
- # Treatment C 188 61 32.45% 2.94
158
+ # Control 182 35 19.23% N/A
159
+ # Treatment A 180 45 25.00% 1.33
160
+ # Treatment B 189 28 14.81% -1.13
161
+ # Treatment C 188 61 32.45% 2.94
157
162
  Vanity.playground.experiment(:null_abc).instance_eval do
158
163
  fake nil=>[182,35], :red=>[180,45], :green=>[189,28], :blue=>[188,61]
159
164
  @created_at = (Date.today - 40).to_time
@@ -16,11 +16,11 @@
16
16
  <div id="links">
17
17
  <a href="http://github.com/assaf/vanity">Source code</a> |
18
18
  <a href="http://groups.google.com/group/vanity-talk" title="vanity-talk google group">Google Group</a> |
19
- <a href="http://vanity.labnotes.org/api/index.html">API reference</a>
19
+ <a href="http://rdoc.info/gems/vanity">API reference</a>
20
20
  </div>
21
21
  <div id="sidebar">
22
22
  <ul>
23
- <li><a href="index.html#intro" title="A/B Testing with Rails in 5 easy steps">2 Minute Demo</a></li>
23
+ <li><a href="index.html#intro" title="A/B Testing with Rails">Intro</a></li>
24
24
  <li><a href="metrics.html">Metrics</a></li>
25
25
  <li><a href="ab_testing.html" title="Everything you need to know">A/B Testing</a></li>
26
26
  <li><a href="rails.html">Using with Rails</a></li>
@@ -29,11 +29,9 @@
29
29
  <li><a href="configuring.html">Configuring</a></li>
30
30
  <li><a href="contributing.html">Contributing</a></li>
31
31
  <li><a href="experimental.html">Experimental</a></li>
32
- <li>Download: <a href="vanity-api.zip">API</a>/<a href="vanity.pdf">PDF</a></li>
33
- </ul>
32
+ </ul>
34
33
  <ul id="stats">
35
- <li><a href="http://travis-ci.org/assaf/vanity"><img src="http://travis-ci.org/assaf/vanity.png"></a></li>
36
- <li><a href="http://github.com/assaf/vanity/graphs/traffic">Traffic</a></li>
34
+ <li><a href="http://travis-ci.org/assaf/vanity"><img src="https://api.travis-ci.org/assaf/vanity.png?branch=master"></a></li>
37
35
  <li><a href="http://wiki.github.com/assaf/vanity/whos-using-vanity">Who's using it?</a></li>
38
36
  </ul>
39
37
  </div>
@@ -75,7 +75,7 @@ Vanity splits the audience randomly -- using "cookies and other mechanisms":iden
75
75
 
76
76
  Vanity will show the conversion rate for each alternative, and how that conversion compares to the worst performing alternative. In the example above, option A has 80.6% conversion rate, 11% more than option B's 72.6% conversion rate (72.6 * 111% ~ 80.6%).
77
77
 
78
- (These large numbers are easily explained by the fact that this report was generated form made up data)
78
+ (These large numbers are easily explained by the fact that this report was generated from made up data)
79
79
 
80
80
  It takes only a handful of visits before you'll see one alternative clearly performing better than all others. That's a sign that you should continue running the experiment. You see, small sample size tend to give out random results.
81
81
 
@@ -11,6 +11,8 @@ Database connection information is loaded from @config/vanity.yml@, based on the
11
11
  development:
12
12
  adapter: redis
13
13
  connection: redis://localhost:6379/0
14
+ test:
15
+ collecting: false
14
16
  production:
15
17
  adapter: mongodb
16
18
  database: analytics
@@ -24,10 +26,6 @@ The available database adapters are:
24
26
  * +mongodb+ -- Available options are host, port, database (defaults to "vanity"), username and password.
25
27
  * +active_record+ -- Uses existing ActiveRecord configuration, by you can over-ride by supplying different options. To pick different underlying adapter, set +active_record_adapter+.
26
28
 
27
- You want Vanity to collect information (metrics, experiments, etc) in production, but there's no point collecting data in other environments. You can turn data collection on and off by setting @Vanity.playground.collecting@. Under Rails, collection is turned off in all environments expect production.
28
-
29
- You may want to turn data collection on for integration tests, depending on what you're testing. Also, you may need to turn it on if your development server runs more than one process, e.g. if you're using Passenger for development and want to use the Vanity console to pick a particular alternative in an A/B test.
30
-
31
29
  Available configuration options are:
32
30
 
33
31
  |_. name |_. Is all about ... |_. Default |
data/doc/email.textile CHANGED
@@ -48,7 +48,7 @@ end
48
48
  Create an ActionMailer class, for example:
49
49
 
50
50
  <pre>
51
- class UserMailer < ActionMailer::Base
51
+ class UserMailer < ActionMailer::Base
52
52
  def invite_email(user)
53
53
  use_vanity_mailer user
54
54
  mail :to => user.email, :subject =>ab_test(:invite_subject)
@@ -125,5 +125,3 @@ A/B test your email content:
125
125
  </pre>
126
126
 
127
127
  Here we use the text from the "invite_text" experiment and then use the @vanity_track_url_for@ helper to add the identity and the metric to track into the url so that Vanity can track the click-throughs.
128
-
129
- Remember: By default, Vanity only collects data in production mode.
data/doc/index.textile CHANGED
@@ -10,7 +10,7 @@ title: Welcome to Vanity
10
10
 
11
11
  h3. Reading Order
12
12
 
13
- * "2 Minute Demo(A/B Testing with Rails in 5 easy steps)":#intro
13
+ * "Introduction & Setup":#intro
14
14
  * "Metrics":metrics.html
15
15
  * "A/B Testing(Everything you need to know)":ab_testing.html
16
16
  * "Using with Rails":rails.html
@@ -24,68 +24,8 @@ Also:
24
24
  * "Join vanity-talk list":http://groups.google.com/group/vanity-talk
25
25
  * "Contributing to Vanity":contributing.html
26
26
 
27
+ h3(#intro). Introduction & setup
27
28
 
28
- h3(#intro). A/B Testing with Rails (in 5 easy steps)
29
-
30
- *Step 1:* Start using Vanity in your Rails application:
31
-
32
- <pre>
33
- Rails::Initializer.run do |config|
34
- gem.config "vanity"
35
-
36
- config.after_initialize do
37
- require "vanity"
38
- end
39
- end
40
- </pre>
41
-
42
- And:
43
-
44
- <pre>
45
- class ApplicationController < ActionController::Base
46
- use_vanity :current_user
47
- end
48
- </pre>
49
-
50
- *Step 2:* Define your first A/B test. This experiment goes in the file <code>experiments/price_options.rb</code>:
51
-
52
- <pre>
53
- ab_test "Price options" do
54
- description "Mirror, mirror on the wall, who's the better price of all?"
55
- alternatives 19, 25, 29
56
- metrics :signup
57
- end
58
- </pre>
59
-
60
- *Step 3:* Present the different options to your users:
61
-
62
- <pre>
63
- <h2>Get started for only $<%= ab_test :price_options %> a month!</h2>
64
- </pre>
65
-
66
- *Step 4:* Measure conversion:
67
-
68
- <pre>
69
- class SignupController < ApplicationController
70
- def signup
71
- @account = Account.new(params[:account])
72
- if @account.save
73
- track! :signup
74
- redirect_to @acccount
75
- else
76
- render action: :offer
77
- end
78
- end
79
- end
80
- </pre>
81
-
82
- *Step 5:* Check the report:
83
-
84
- <pre>
85
- vanity report --output vanity.html
86
- </pre>
87
-
88
- !images/price_options.png!
29
+ Please see the "setup instructions in the README":https://github.com/assaf/vanity#vanity
89
30
 
90
31
  Read more about "A/B Testing ...":ab_testing.html
91
-