field_test 0.2.3 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: bf0f3fac61545757a6431b740be8d781bc40916b
4
- data.tar.gz: 7b83659f8ebc1d6b5bbe1d642a8b376191de0b74
2
+ SHA256:
3
+ metadata.gz: 96def1c6805d880a03c141a421570a3e4b9f912e9427c385b132ffae646bc74b
4
+ data.tar.gz: b6eb3262d522544a40db7169364ebef0f6d9f4d2f1f4c82712c91fec5a617a4f
5
5
  SHA512:
6
- metadata.gz: dddab4904f52e6c186a0a39a52a9cc3dbf88bff748ddf15cd56f3b356deea6660539eff75a6794a94ad537c66ba0e73590e50cf390994b3c64ed16f9b08a9870
7
- data.tar.gz: 43f4ada96d3338c83baf0e99067e96f873fd18c3888ebbd0f86154a18b352e8803a6886b327d3ca9f6cb93eb553b475d1ea3f1ae98bc86b48d3a83070927b476
6
+ metadata.gz: 35765af19297887bae1e807aeff9f4f741687b4c3fc961b6b91a6aa9c3060098f42bb677d1055309b2698377dd6694c24770e8ab0418fa4c675146c1661559c0
7
+ data.tar.gz: 786390b24efece6a99b5db602b6b0162a2b398b319f42e61c8b0db4aca021fb4b80fba65ecfa5c5d94ebb451b7b1c852c25983e72246a3aa4640dc41613963a1
@@ -1,29 +1,67 @@
1
- ## 0.2.3
1
+ ## 0.4.0 (2020-08-04)
2
+
3
+ - Fixed CSRF vulnerability with non-session based authentication
4
+ - Fixed cache key for requests
5
+
6
+ ## 0.3.2 (2020-04-16)
7
+
8
+ - Added support for excluding IP addresses
9
+
10
+ ## 0.3.1 (2019-07-01)
11
+
12
+ - Added `closed` and `keep_variant`
13
+ - Added `field_test_upgrade_memberships` method
14
+ - Fixed API controller error
15
+ - Fixed bug where conversions were recorded after winner
16
+
17
+ Security
18
+
19
+ - Fixed arbitrary variants via query parameters - see [#17](https://github.com/ankane/field_test/issues/17)
20
+
21
+ ## 0.3.0 (2019-06-02)
22
+
23
+ - Added support for native apps
24
+ - Added `cookies` option
25
+ - Added `precision` option
26
+ - Fixed bug in results with multiple goals
27
+ - Fixed issue where metrics disappeared from dashboard when moving to multiple goals
28
+ - Dropped support for Rails < 5
29
+
30
+ Breaking changes
31
+
32
+ - Split out participant id and type
33
+ - Changed participant logic for emails
34
+
35
+ ## 0.2.4 (2019-01-03)
36
+
37
+ - Fixed `PG::AmbiguousColumn` error
38
+
39
+ ## 0.2.3 (2018-01-28)
2
40
 
3
41
  - Fixed participant reporting for multiple goals
4
42
 
5
- ## 0.2.2
43
+ ## 0.2.2 (2017-05-01)
6
44
 
7
45
  - Added support for Rails 5.1
8
46
 
9
- ## 0.2.1
47
+ ## 0.2.1 (2016-12-18)
10
48
 
11
49
  - Added support for multiple goals
12
50
 
13
- ## 0.2.0
51
+ ## 0.2.0 (2016-12-17)
14
52
 
15
53
  - Better web UI
16
54
  - Removed `cookie:` prefix for unknown participants
17
55
 
18
- ## 0.1.2
56
+ ## 0.1.2 (2016-12-17)
19
57
 
20
58
  - Exclude bots
21
59
  - Mailer improvements
22
60
 
23
- ## 0.1.1
61
+ ## 0.1.1 (2016-12-15)
24
62
 
25
63
  - Added basic web UI
26
64
 
27
- ## 0.1.0
65
+ ## 0.1.0 (2016-12-14)
28
66
 
29
67
  - First release
@@ -1,4 +1,4 @@
1
- Copyright (c) 2016 Andrew Kane
1
+ Copyright (c) 2016-2019 Andrew Kane
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -3,10 +3,13 @@
3
3
  :maple_leaf: A/B testing for Rails
4
4
 
5
5
  - Designed for web and email
6
- - Comes with a [handy dashboard](https://fieldtest.dokkuapp.com/)
6
+ - Comes with a [dashboard](https://fieldtest.dokkuapp.com/) to view results and update variants
7
+ - Uses your database for storage
7
8
  - Seamlessly handles the transition from anonymous visitor to logged in user
8
9
 
9
- Uses [Bayesian statistics](http://www.evanmiller.org/bayesian-ab-testing.html) to evaluate results so you don’t need to choose a sample size ahead of time.
10
+ 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.
11
+
12
+ [![Build Status](https://travis-ci.org/ankane/field_test.svg?branch=master)](https://travis-ci.org/ankane/field_test)
10
13
 
11
14
  ## Installation
12
15
 
@@ -19,7 +22,8 @@ gem "field_test"
19
22
  Run:
20
23
 
21
24
  ```sh
22
- rails g field_test:install
25
+ rails generate field_test:install
26
+ rails db:migrate
23
27
  ```
24
28
 
25
29
  And mount the dashboard in your `config/routes.rb`:
@@ -28,7 +32,7 @@ And mount the dashboard in your `config/routes.rb`:
28
32
  mount FieldTest::Engine, at: "field_test"
29
33
  ```
30
34
 
31
- Be sure to [secure the dashboard](#security) in production.
35
+ Be sure to [secure the dashboard](#dashboard-security) in production.
32
36
 
33
37
  ![Screenshot](https://ankane.github.io/field_test/screenshot6.png)
34
38
 
@@ -45,12 +49,18 @@ experiments:
45
49
  - blue
46
50
  ```
47
51
 
48
- Refer to it in views, controllers, and mailers.
52
+ Refer to it in controllers, views, and mailers.
49
53
 
50
54
  ```ruby
51
55
  button_color = field_test(:button_color)
52
56
  ```
53
57
 
58
+ To make testing easier, you can specify a variant with query parameters
59
+
60
+ ```
61
+ http://localhost:3000/?field_test[button_color]=green
62
+ ```
63
+
54
64
  When someone converts, record it with:
55
65
 
56
66
  ```ruby
@@ -67,22 +77,88 @@ experiments:
67
77
 
68
78
  All calls to `field_test` will now return the winner, and metrics will stop being recorded.
69
79
 
70
- ## Features
80
+ You can keep returning the variant for existing participants after a winner is declared:
71
81
 
72
- You can specify a variant with query parameters to make testing easier
82
+ ```yml
83
+ experiments:
84
+ button_color:
85
+ winner: green
86
+ keep_variant: true
87
+ ```
73
88
 
89
+ You can also close an experiment to new participants without declaring a winner while still recording metrics for existing participants:
90
+
91
+ ```yml
92
+ experiments:
93
+ button_color:
94
+ closed: true
74
95
  ```
75
- ?field_test[button_color]=green
96
+
97
+ Calls to `field_test` for new participants will return the control, and they won’t be added to the experiment.
98
+
99
+ You can get the list of experiments and variants for a user with:
100
+
101
+ ```ruby
102
+ field_test_experiments
76
103
  ```
77
104
 
78
- Assign a specific variant to a user with:
105
+ ## JavaScript and Native Apps
106
+
107
+ For JavaScript and native apps, add calls to your normal endpoints.
79
108
 
80
109
  ```ruby
81
- experiment = FieldTest::Experiment.find(:button_color)
82
- experiment.variant(participant, variant: "green")
110
+ class CheckoutController < ActionController::API
111
+ def start
112
+ render json: {button_color: field_test(:button_color)}
113
+ end
114
+
115
+ def finish
116
+ field_test_converted(:button_color)
117
+ # ...
118
+ end
119
+ end
83
120
  ```
84
121
 
85
- You can also change a user’s variant from the dashboard.
122
+ For anonymous visitors in native apps, pass a `Field-Test-Visitor` header with a unique identifier.
123
+
124
+ ## Participants
125
+
126
+ Any model or string can be a participant in an experiment.
127
+
128
+ For web requests, it uses `current_user` (if it exists) and an anonymous visitor id to determine the participant. Set your own with:
129
+
130
+ ```ruby
131
+ class ApplicationController < ActionController::Base
132
+ def field_test_participant
133
+ current_company
134
+ end
135
+ end
136
+ ```
137
+
138
+ For mailers, it tries `@user` then `params[:user]` to determine the participant. Set your own with:
139
+
140
+ ```ruby
141
+ class ApplicationMailer < ActionMailer::Base
142
+ def field_test_participant
143
+ @company
144
+ end
145
+ end
146
+ ```
147
+
148
+ You can also manually pass a participant with:
149
+
150
+ ```ruby
151
+ field_test(:button_color, participant: company)
152
+ ```
153
+
154
+ ## Jobs
155
+
156
+ To get variants in jobs, models, and other contexts, use:
157
+
158
+ ```ruby
159
+ experiment = FieldTest::Experiment.find(:button_color)
160
+ button_color = experiment.variant(user)
161
+ ```
86
162
 
87
163
  ## Config
88
164
 
@@ -93,6 +169,15 @@ exclude:
93
169
  bots: false
94
170
  ```
95
171
 
172
+ Exclude certain IP addresses with:
173
+
174
+ ```yml
175
+ exclude:
176
+ ips:
177
+ - 127.0.0.1
178
+ - 10.0.0.0/8
179
+ ```
180
+
96
181
  Keep track of when experiments started and ended. Use any format `Time.parse` accepts. Variants assigned outside this window are not included in metrics.
97
182
 
98
183
  ```yml
@@ -126,6 +211,14 @@ experiments:
126
211
  - 15
127
212
  ```
128
213
 
214
+ 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.
215
+
216
+ ```yml
217
+ cookies: false
218
+ ```
219
+
220
+ ## Dashboard Config
221
+
129
222
  If the dashboard gets slow, you can make it faster with:
130
223
 
131
224
  ```yml
@@ -134,12 +227,19 @@ cache: true
134
227
 
135
228
  This will use the Rails cache to speed up winning probability calculations.
136
229
 
137
- ## Funnels
230
+ If you need more precision, set:
231
+
232
+ ```yml
233
+ precision: 1
234
+ ```
235
+
236
+ ## Multiple Goals
138
237
 
139
238
  You can set multiple goals for an experiment to track conversions at different parts of the funnel. First, run:
140
239
 
141
240
  ```sh
142
- rails g field_test:events
241
+ rails generate field_test:events
242
+ rails db:migrate
143
243
  ```
144
244
 
145
245
  And add to your config:
@@ -162,20 +262,30 @@ The results for all goals will appear on the dashboard.
162
262
 
163
263
  ## Analytics Platforms
164
264
 
165
- 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:
265
+ 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:
166
266
 
167
267
  ```ruby
168
268
  field_test_experiments
169
269
  ```
170
270
 
171
- to get all experiments and variants for a participant and pass them as properties.
271
+ ### Ahoy
272
+
273
+ You can configure Field Test to use Ahoy’s visitor token instead of creating its own:
274
+
275
+ ```ruby
276
+ class ApplicationController < ActionController::Base
277
+ def field_test_participant
278
+ [ahoy.user, ahoy.visitor_token]
279
+ end
280
+ end
281
+ ```
172
282
 
173
- ## Security
283
+ ## Dashboard Security
174
284
 
175
285
  #### Devise
176
286
 
177
287
  ```ruby
178
- authenticate :user, -> (user) { user.admin? } do
288
+ authenticate :user, ->(user) { user.admin? } do
179
289
  mount FieldTest::Engine, at: "field_test"
180
290
  end
181
291
  ```
@@ -189,13 +299,106 @@ ENV["FIELD_TEST_USERNAME"] = "moonrise"
189
299
  ENV["FIELD_TEST_PASSWORD"] = "kingdom"
190
300
  ```
191
301
 
192
- ## Credits
302
+ ## Updating Variants
303
+
304
+ Assign a specific variant to a user with:
305
+
306
+ ```ruby
307
+ experiment = FieldTest::Experiment.find(:button_color)
308
+ experiment.variant(participant, variant: "green")
309
+ ```
310
+
311
+ You can also change a user’s variant from the dashboard.
312
+
313
+ ## Associations
314
+
315
+ To associate models with field test memberships, use:
316
+
317
+ ```ruby
318
+ class User < ApplicationRecord
319
+ has_many :field_test_memberships, class_name: "FieldTest::Membership", as: :participant
320
+ end
321
+ ```
322
+
323
+ Now you can do:
324
+
325
+ ```ruby
326
+ user.field_test_memberships
327
+ ```
328
+
329
+ ## Upgrading
330
+
331
+ ### 0.3.0
332
+
333
+ Upgrade the gem and add to `config/field_test.yml`:
334
+
335
+ ```yml
336
+ legacy_participants: true
337
+ ```
338
+
339
+ Also, if you use Field Test in emails, know that the default way participants are determined has changed. Restore the previous way with:
340
+
341
+ ```ruby
342
+ class ApplicationMailer < ActionMailer::Base
343
+ def field_test_participant
344
+ message.to.first
345
+ end
346
+ end
347
+ ```
348
+
349
+ We also recommend upgrading participants when you have time.
350
+
351
+ #### Upgrading Participants
352
+
353
+ Field Test 0.3.0 splits the `field_test_memberships.participant` column into `participant_type` and `participant_id`.
354
+
355
+ To upgrade without downtime, create a migration:
356
+
357
+ ```sh
358
+ rails generate migration upgrade_field_test_participants
359
+ ```
360
+
361
+ with:
193
362
 
194
- A huge thanks to [Evan Miller](http://www.evanmiller.org/) for deriving the Bayesian formulas.
363
+ ```ruby
364
+ class UpgradeFieldTestParticipants < ActiveRecord::Migration[6.0]
365
+ def change
366
+ add_column :field_test_memberships, :participant_type, :string
367
+ add_column :field_test_memberships, :participant_id, :string
368
+
369
+ add_index :field_test_memberships, [:participant_type, :participant_id, :experiment],
370
+ unique: true, name: "index_field_test_memberships_on_participant_and_experiment"
371
+ end
372
+ end
373
+ ```
374
+
375
+ After you run it, writes will go to both the old and new sets of columns.
195
376
 
196
- ## TODO
377
+ Next, backfill data:
378
+
379
+ ```ruby
380
+ FieldTest::Membership.where(participant_id: nil).find_each do |membership|
381
+ participant = membership.participant
382
+
383
+ if participant.include?(":")
384
+ participant_type, _, participant_id = participant.rpartition(":")
385
+ participant_type = nil if participant_type == "cookie" # legacy
386
+ else
387
+ participant_id = participant
388
+ end
389
+
390
+ membership.update!(
391
+ participant_type: participant_type,
392
+ participant_id: participant_id
393
+ )
394
+ end
395
+ ```
197
396
 
198
- - Code samples for analytics platforms
397
+ 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).
398
+
399
+ ## Credits
400
+
401
+ A huge thanks to [Evan Miller](https://www.evanmiller.org/) for deriving the Bayesian formulas.
199
402
 
200
403
  ## History
201
404
 
@@ -209,3 +412,12 @@ Everyone is encouraged to help improve this project. Here are a few ways you can
209
412
  - Fix bugs and [submit pull requests](https://github.com/ankane/field_test/pulls)
210
413
  - Write, clarify, or fix documentation
211
414
  - Suggest or add new features
415
+
416
+ To get started with development:
417
+
418
+ ```sh
419
+ git clone https://github.com/ankane/field_test.git
420
+ cd field_test
421
+ bundle install
422
+ bundle exec rake test
423
+ ```