Google OptimizerでサーバーサイドでABテストのパターンを決定する方法
ABテストをしよう、となるとGoogle Optimizerが候補として上がってくると思います。
通常はOptimizerが発行するjsのコードをページに埋め込んだら、あとはOptimizerの管理画面から設定をしてABテストをすることになりますが、なんらかの事情でABテストのパターン割り当てをサーバーサイド(バックエンド)で実施したいケースがあります。
たとえば、サーバーサイドの言語でviewを書き換えしてABテストをしたい、とか、Optimizerのjsによるview表示後の書き換え(リダイレクトも含む)が気に入らない場合などです。
この記事ではそんな感じでOptimizerを使いつつも、サーバーサイド側でABテストの振り分けをする方法についてメモしていきます。
なお、Optimizerの基本的な使い方は解説していません。
まずは以下のようにいつもと同じようにOptimizerの管理画面にABテストの設定をしていきます。
次がポイントです。
ページターゲティングのところで「URLが次と等しい」を条件として選択し、SERVER_SIDEという文字列を設定しておきます。
この設定をしておくことでABテストのパターン分けは自分達でやりますよ、ということになります。
あとは、Optimizerが発行するテストIDをメモしておきましょう。このテストIDをソースコードで使います。
ここまでがOptimizer上での設定です。
次はコードを調整していきましょう。
ソースコードでは以下2点を書いていくことになります。
- ABテストのパターン振り分け
- ABテストの振り分け結果をOptimizerに飛ばす
それぞれ見ていきましょう。
まず、ABテストのパターン振り分けからいきます。
以下はRuby on Railsの例ですが他の言語もで大体似たような感じかなと思います。ABテスト用のmoduleを作成しました。
Optimizerでは、Aパターン、Bパターンというのをゼロから始まる数字で管理しています。
ここ最初気がつかなくて、aとかbとかの文字列をOptimizerへ送っていたんですがそれでは全然ダメでした。
module AbPatternAssignable
def set_ab_experiments
return if session[:ab_test_pattern].present?
# ここでABのパターンを振り分け。3パターンだったら%w[0 1 2].sampleと増やす
# セッションに残しておくことで、同じユーザーには常に同じABテストのパターンが割り当てられた状態になる
session[:ab_test_pattern] = %w[0 1].sample
end
def assigned_ab_pattern
session[:ab_test_pattern] || ''
end
end
このmoduleをあとはcontrollerでincludeして使っていきます。
class SampleController < ApplicationController
include AbPatternAssignable
before_action :set_ab_experiments
def index
# abテストのパターンを取得してviewで使う
# この変数の中身を基準にして、view上の表記を適宜変更する
@ab_test_pattern = assigned_ab_pattern
end
end
あとは、ABテストの振り分け結果をOptimizerに飛ばすところです。
ABテストの対象となるview画面で以下のようにgtagコマンドを発行するようにします。 これで、このユーザーはAパターンなんだとか、BパターンなんだってことがOptimizerに伝わります。
event
はexperiment_impression
の固定値experiment_id
はOptimizerの管理画面でメモしたテストIDを指定variant_id
はテストID
+.(ドット)
+ABテストパターンの文字列
を連結した文字列を指定send_to
はGA4のトラックングID(測定ID)を指定
gtag('event', 'experiment_impression', {
'experiment_id': '{ここにテストIDを指定する}',
'variant_id': "{ここにテストIDを指定する}.#{@ab_test_pattern}",
'send_to': '{GA4のトラックングID(測定ID)}',
});
以下はおまけ。ABテストをする以上、CVを測定しないとですが、この前はこんな感じでやりました。
.js-click
のクラスが設定してあるボタンやリンクがクリックされたら、gtagイベントが発火するように仕込みました。
この辺りはテスト要件や環境構成で大きく変化するでしょう。
window.addEventListener('DOMContentLoaded', () => {
const buttons = document.querySelectorAll('.js-click');
buttons.forEach((btn) => {
btn.addEventListener('click', () => {
gtag('event', '{CVとして採用しているevent_nameを指定}');
})
});
});
この記事の環境情報
- Google Optimizer 2022年12月時点
- 大掃除をしていく
あとがき
昔はABテスト苦手、というか嫌いでした。
今はもう心を無にして取り組むことができるようになりました。
根本的にはあまり嗜好は変わっていないけれど、大人になったということでしょう。
最近の記事を読む
- Flutterでcontextを使わずにlocale情報を取得する
- Cloud RunでIAPを有効にしようとしてハマったこと
- slimでtype='application/ld+json'のscriptタグを書く
- タグマネージャーでjsのloadイベントを発火させたいとき
- mysqlコマンドを実行してERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)と言われたら