Skip to content

Commit b16b8b9

Browse files
committed
Rename treatment to variant
1 parent 856d51b commit b16b8b9

File tree

14 files changed

+154
-96
lines changed

14 files changed

+154
-96
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Generated by Django 3.1.3 on 2020-12-16 13:40
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('wagtail_ab_testing', '0009_rename_variant_to_version'),
10+
]
11+
12+
operations = [
13+
migrations.RenameField(
14+
model_name='abtest',
15+
old_name='treatment_revision',
16+
new_name='variant_revision',
17+
),
18+
migrations.AlterField(
19+
model_name='abtest',
20+
name='winning_version',
21+
field=models.CharField(choices=[('control', 'Control'), ('variant', 'Variant')], max_length=9, null=True),
22+
),
23+
migrations.AlterField(
24+
model_name='abtesthourlylog',
25+
name='version',
26+
field=models.CharField(choices=[('control', 'Control'), ('variant', 'Variant')], max_length=9),
27+
),
28+
]
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Generated by Django 3.1.3 on 2020-12-16 13:40
2+
3+
from django.db import migrations, models
4+
5+
6+
def rename_treatment_to_variant_forwards(apps, schema_editor):
7+
AbTest = apps.get_model('wagtail_ab_testing.AbTest')
8+
AbTest.objects.filter(winning_version='treatment').update(winning_version='variant')
9+
10+
AbTestHourlyLog = apps.get_model('wagtail_ab_testing.AbTestHourlyLog')
11+
AbTestHourlyLog.objects.filter(version='treatment').update(version='variant')
12+
13+
14+
def rename_treatment_to_variant_backwards(apps, schema_editor):
15+
AbTest = apps.get_model('wagtail_ab_testing.AbTest')
16+
AbTest.objects.filter(winning_version='variant').update(winning_version='treatment')
17+
18+
AbTestHourlyLog = apps.get_model('wagtail_ab_testing.AbTestHourlyLog')
19+
AbTestHourlyLog.objects.filter(version='variant').update(version='treatment')
20+
21+
22+
class Migration(migrations.Migration):
23+
24+
dependencies = [
25+
('wagtail_ab_testing', '0010_rename_treatment_to_variant'),
26+
]
27+
28+
operations = [
29+
migrations.RunPython(rename_treatment_to_variant_forwards, rename_treatment_to_variant_backwards)
30+
]

wagtail_ab_testing/models.py

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class AbTest(models.Model):
2727
Represents an A/B test that has been set up by the user.
2828
2929
The live page content is used as the control, the revision pointed to in
30-
the `.treatment_revision` field contains the changes that are being tested.
30+
the `.variant_revision` field contains the changes that are being tested.
3131
"""
3232

3333
class Status(models.TextChoices):
@@ -38,7 +38,7 @@ class Status(models.TextChoices):
3838

3939
# These two sound similar, but there's a difference:
4040
# 'Finished' means that we've reached the sample size and testing has stopped
41-
# but the user still needs to decide whether to publish the treatment version
41+
# but the user still needs to decide whether to publish the variant version
4242
# or revert back to the control.
4343
# Once they've decided and that action has taken place, the test status is
4444
# updated to 'Completed'.
@@ -47,18 +47,18 @@ class Status(models.TextChoices):
4747

4848
class Version(models.TextChoices):
4949
CONTROL = 'control', __('Control')
50-
TREATMENT = 'treatment', __('Treatment')
50+
VARIANT = 'variant', __('Variant')
5151

5252
class CompletionAction(models.TextChoices):
5353
# See docstring of the .complete() method for descriptions
5454
DO_NOTHING = 'do-nothing', "Do nothing"
5555
REVERT = 'revert', "Revert to control"
56-
PUBLISH = 'publisn', "Publish treatment"
56+
PUBLISH = 'publisn', "Publish variant"
5757

5858
page = models.ForeignKey('wagtailcore.Page', on_delete=models.CASCADE, related_name='ab_tests')
5959
name = models.CharField(max_length=255)
6060
hypothesis = models.TextField(blank=True)
61-
treatment_revision = models.ForeignKey('wagtailcore.PageRevision', on_delete=models.CASCADE, related_name='+')
61+
variant_revision = models.ForeignKey('wagtailcore.PageRevision', on_delete=models.CASCADE, related_name='+')
6262
goal_event = models.CharField(max_length=255)
6363
goal_page = models.ForeignKey('wagtailcore.Page', null=True, blank=True, on_delete=models.SET_NULL, related_name='+')
6464
sample_size = models.PositiveIntegerField(validators=[MinValueValidator(1)])
@@ -150,7 +150,7 @@ def finish(self):
150150
Note that this doesn't 'complete' the test: a finished test means
151151
that testing is no longer happening. The test is not complete until
152152
the user decides on the outcome of the test (keep the control or
153-
publish the treatment). This decision is set using the .complete()
153+
publish the variant). This decision is set using the .complete()
154154
method.
155155
"""
156156
self.status = self.Status.FINISHED
@@ -166,14 +166,14 @@ def complete(self, action, user=None):
166166
Actions can be:
167167
- AbTest.CompletionAction.DO_NOTHING - This just completes
168168
the test but does nothing to the page. The control will
169-
remain the published version and the treatment will be
169+
remain the published version and the variant will be
170170
in draft.
171171
- AbTest.CompletionAction.REVERT - This completes the test
172172
and also creates a new revision to revert the content back
173173
to what it was in the control while the test was taking
174174
place.
175175
- AbTest.CompletionAction.PUBLISH - This completes the test
176-
and also publishes the treatment revision.
176+
and also publishes the variant revision.
177177
"""
178178
self.status = self.Status.COMPLETED
179179
self.save(update_fields=['status'])
@@ -186,7 +186,7 @@ def complete(self, action, user=None):
186186
self.page.save_revision(user=user, log_action='wagtail.revert').publish(user=user)
187187

188188
elif action == AbTest.CompletionAction.PUBLISH:
189-
self.treatment_revision.publish(user=user)
189+
self.variant_revision.publish(user=user)
190190

191191
def add_participant(self, version=None):
192192
"""
@@ -195,23 +195,23 @@ def add_participant(self, version=None):
195195
# Get current numbers of participants for each version
196196
stats = self.hourly_logs.aggregate(
197197
control_participants=Sum('participants', filter=Q(version=self.Version.CONTROL)),
198-
treatment_participants=Sum('participants', filter=Q(version=self.Version.TREATMENT)),
198+
variant_participants=Sum('participants', filter=Q(version=self.Version.VARIANT)),
199199
)
200200
control_participants = stats['control_participants'] or 0
201-
treatment_participants = stats['treatment_participants'] or 0
201+
variant_participants = stats['variant_participants'] or 0
202202

203203
# Create an equal number of participants for each version
204204
if version is None:
205-
if treatment_participants > control_participants:
205+
if variant_participants > control_participants:
206206
version = self.Version.CONTROL
207207

208-
elif treatment_participants < control_participants:
209-
version = self.Version.TREATMENT
208+
elif variant_participants < control_participants:
209+
version = self.Version.VARIANT
210210

211211
else:
212212
version = random.choice([
213213
self.Version.CONTROL,
214-
self.Version.TREATMENT,
214+
self.Version.VARIANT,
215215
])
216216

217217
# Add new participant to statistics model
@@ -222,7 +222,7 @@ def add_participant(self, version=None):
222222
# get a chance to turn into conversions. It's unlikely to make a
223223
# significant difference to the results.
224224
# Note: Adding 1 to account for the new participant
225-
if control_participants + treatment_participants + 1 >= self.sample_size:
225+
if control_participants + variant_participants + 1 >= self.sample_size:
226226
self.finish()
227227

228228
return version
@@ -240,7 +240,7 @@ def check_for_winner(self):
240240
"""
241241
Performs a Chi-Squared test to check if there is a clear winner.
242242
243-
Returns Version.CONTROL or Version.TREATMENT if there is one. Otherwise, it returns None.
243+
Returns Version.CONTROL or Version.VARIANT if there is one. Otherwise, it returns None.
244244
245245
For more information on what the Chi-Squared test does, see:
246246
https://www.evanmiller.org/ab-testing/chi-squared.html
@@ -250,30 +250,30 @@ def check_for_winner(self):
250250
stats = self.hourly_logs.aggregate(
251251
control_participants=Sum('participants', filter=Q(version=self.Version.CONTROL)),
252252
control_conversions=Sum('conversions', filter=Q(version=self.Version.CONTROL)),
253-
treatment_participants=Sum('participants', filter=Q(version=self.Version.TREATMENT)),
254-
treatment_conversions=Sum('conversions', filter=Q(version=self.Version.TREATMENT)),
253+
variant_participants=Sum('participants', filter=Q(version=self.Version.VARIANT)),
254+
variant_conversions=Sum('conversions', filter=Q(version=self.Version.VARIANT)),
255255
)
256256
control_participants = stats['control_participants'] or 0
257257
control_conversions = stats['control_conversions'] or 0
258-
treatment_participants = stats['treatment_participants'] or 0
259-
treatment_conversions = stats['treatment_conversions'] or 0
258+
variant_participants = stats['variant_participants'] or 0
259+
variant_conversions = stats['variant_conversions'] or 0
260260

261-
if not control_conversions and not treatment_conversions:
261+
if not control_conversions and not variant_conversions:
262262
return
263263

264-
if control_conversions > control_participants or treatment_conversions > treatment_participants:
264+
if control_conversions > control_participants or variant_conversions > variant_participants:
265265
# Something's up. I'm sure it's already clear in the UI what's going on, so let's not crash
266266
return
267267

268268
# Create a numpy array with values to pass in to Chi-Squared test
269269
control_failures = control_participants - control_conversions
270-
treatment_failures = treatment_participants - treatment_conversions
270+
variant_failures = variant_participants - variant_conversions
271271

272-
if control_failures == 0 and treatment_failures == 0:
272+
if control_failures == 0 and variant_failures == 0:
273273
# Prevent this error: "The internally computed table of expected frequencies has a zero element at (0, 1)."
274274
return
275275

276-
T = np.array([[control_conversions, control_failures], [treatment_conversions, treatment_failures]])
276+
T = np.array([[control_conversions, control_failures], [variant_conversions, variant_failures]])
277277

278278
# Perform Chi-Squared test
279279
p = scipy.stats.chi2_contingency(T, correction=False)[1]
@@ -283,10 +283,10 @@ def check_for_winner(self):
283283
if 1 - p > required_confidence_level:
284284
# There is a clear winner!
285285
# Return the one with the highest success rate
286-
if (control_conversions / control_participants) > (treatment_conversions / treatment_participants):
286+
if (control_conversions / control_participants) > (variant_conversions / variant_participants):
287287
return self.Version.CONTROL
288288
else:
289-
return self.Version.TREATMENT
289+
return self.Version.VARIANT
290290

291291
def get_status_description(self):
292292
"""
@@ -303,8 +303,8 @@ def get_status_description(self):
303303
if self.winning_version == AbTest.Version.CONTROL:
304304
return status + " (" + _("Control won") + ")"
305305

306-
elif self.winning_version == AbTest.Version.TREATMENT:
307-
return status + " (" + _("Treatment won") + ")"
306+
elif self.winning_version == AbTest.Version.VARIANT:
307+
return status + " (" + _("Variant won") + ")"
308308

309309
else:
310310
return status + " (" + _("No clear winner") + ")"

wagtail_ab_testing/static_src/style/progress.scss

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
@import 'vendor/c3.min.css';
22

33
$color-control: #0c0073;
4-
$color-treatment: #ef746f;
4+
$color-variant: #ef746f;
55

66
$light-teal: #e1f0f0;
77
$dark-teal: #007273;
@@ -63,16 +63,16 @@ $charcoal-grey: #333;
6363
}
6464
}
6565

66-
&--treatment {
66+
&--variant {
6767
right: 0;
6868
padding-left: 10px;
69-
color: $color-treatment;
69+
color: $color-variant;
7070

7171
a {
72-
color: $color-treatment !important;
72+
color: $color-variant !important;
7373

7474
&:hover {
75-
color: darken($color-treatment, 10%) !important;
75+
color: darken($color-variant, 10%) !important;
7676
}
7777
}
7878
}
@@ -105,15 +105,15 @@ $charcoal-grey: #333;
105105
&__version--control &__version-heading {
106106
border-bottom-color: $color-control;
107107
}
108-
&__version--treatment &__version-heading {
109-
border-bottom-color: $color-treatment;
108+
&__version--variant &__version-heading {
109+
border-bottom-color: $color-variant;
110110
}
111111

112112
&__version--control &__version-heading--winner {
113113
background-color: $color-control;
114114
}
115-
&__version--treatment &__version-heading--winner {
116-
background-color: $color-treatment;
115+
&__version--variant &__version-heading--winner {
116+
background-color: $color-variant;
117117
}
118118

119119
&__version-inner {

wagtail_ab_testing/templates/wagtail_ab_testing/results.html

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ <h2>{{ ab_test.name }}</h2>
1515

1616
<a href="{% url 'wagtail_ab_testing:add_test_participants' ab_test.id %}">Add test participants</a>
1717
<a href="{% url 'wagtail_ab_testing:add_test_conversions' ab_test.id 'control' %}">Add conversions for control</a>
18-
<a href="{% url 'wagtail_ab_testing:add_test_conversions' ab_test.id 'treatment' %}">Add conversions for treatment</a>
18+
<a href="{% url 'wagtail_ab_testing:add_test_conversions' ab_test.id 'variant' %}">Add conversions for variant</a>
1919

2020
<div class="abtest-progressbar">
2121
<svg class="abtest-progressbar__sample-size">
@@ -78,36 +78,36 @@ <h3>{% trans "Control" %} <a href="{% pageurl page %}" target="_blank">{% icon n
7878
{% endif %}
7979
</div>
8080
</div>
81-
<div class="abtest-results__version abtest-results__version--treatment">
82-
<div class="abtest-results__version-heading{% if treatment_is_winner or unclear_winner %} abtest-results__version-heading--winner{% endif %}">
83-
{% if treatment_is_winner %}{% icon "crown" %} {% trans "Winner!" %}{% elif unclear_winner %}{% trans "No clear winner" %}{% endif %}
81+
<div class="abtest-results__version abtest-results__version--variant">
82+
<div class="abtest-results__version-heading{% if variant_is_winner or unclear_winner %} abtest-results__version-heading--winner{% endif %}">
83+
{% if variant_is_winner %}{% icon "crown" %} {% trans "Winner!" %}{% elif unclear_winner %}{% trans "No clear winner" %}{% endif %}
8484
</div>
8585
<div class="abtest-results__version-inner">
86-
<h3>{% trans "Treatment" %} <a href="{% url 'wagtailadmin_pages:view_draft' page.id %}" target="_blank">{% icon name="link-external" %}</a></h3>
86+
<h3>{% trans "Variant" %} <a href="{% url 'wagtailadmin_pages:view_draft' page.id %}" target="_blank">{% icon name="link-external" %}</a></h3>
8787

8888
<ul class="abtest-results__version-stats">
8989
<li>
9090
<div class="abtest-results__version-stat">
91-
{{ treatment_conversions_percent }}%
91+
{{ variant_conversions_percent }}%
9292
</div>
9393
<div class="abtest-results__version-stat-name">
9494
{% trans "Conversion rate" %}
9595
</div>
9696
</li>
9797
<li>
9898
<div class="abtest-results__version-stat">
99-
{{ treatment_conversions }}
99+
{{ variant_conversions }}
100100
</div>
101101
<div class="abtest-results__version-stat-name">
102-
{% trans "Conversions" %} <span>({% blocktrans count treatment_participants as count %}1 user{% plural %}{{ count }} users{% endblocktrans %})</span>
102+
{% trans "Conversions" %} <span>({% blocktrans count variant_participants as count %}1 user{% plural %}{{ count }} users{% endblocktrans %})</span>
103103
</div>
104104
</li>
105105
</ul>
106106

107107
{% if ab_test.status == 'finished' %}
108108
<form method="post">
109109
{% csrf_token %}
110-
<button type="submit" name="action-select-treatment" value="{% trans 'Publish and end test' %}" class="button">{% trans "<span>Publish</span> and end test" %}</button>
110+
<button type="submit" name="action-select-variant" value="{% trans 'Publish and end test' %}" class="button">{% trans "<span>Publish</span> and end test" %}</button>
111111
</form>
112112
{% endif %}
113113
</div>
@@ -116,7 +116,7 @@ <h3>{% trans "Treatment" %} <a href="{% url 'wagtailadmin_pages:view_draft' page
116116
</div>
117117
{% url 'wagtail_ab_testing:compare_draft' page.id as compare_url%}
118118
{% blocktrans with compare_url=compare_url trimmed %}
119-
<a href="{{ compare_url }}" target="_blank">Compare pages</a> and see how the control and treatment pages differ.
119+
<a href="{{ compare_url }}" target="_blank">Compare pages</a> and see how the control and variant pages differ.
120120
{% endblocktrans %}
121121
<hr>
122122
<h3>{% trans "Conversions over time" %}</h3>

0 commit comments

Comments
 (0)