ABテストをしよう、となるとGoogle Optimizerが候補として上がってくると思います。

通常はOptimizerが発行するjsのコードをページに埋め込んだら、あとはOptimizerの管理画面から設定をしてABテストをすることになりますが、なんらかの事情でABテストのパターン割り当てをサーバーサイド(バックエンド)で実施したいケースがあります。

たとえば、サーバーサイドの言語でviewを書き換えしてABテストをしたい、とか、Optimizerのjsによるview表示後の書き換え(リダイレクトも含む)が気に入らない場合などです。

この記事ではそんな感じでOptimizerを使いつつも、サーバーサイド側でABテストの振り分けをする方法についてメモしていきます。

なお、Optimizerの基本的な使い方は解説していません。

まずは以下のようにいつもと同じようにOptimizerの管理画面にABテストの設定をしていきます。

いつも通りにOptimizerを設定

次がポイントです。

ページターゲティングのところで「URLが次と等しい」を条件として選択し、SERVER_SIDEという文字列を設定しておきます。

この設定をしておくことでABテストのパターン分けは自分達でやりますよ、ということになります。

SERVER_SIDEと設定

あとは、Optimizerが発行するテストIDをメモしておきましょう。このテスト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に伝わります。

  • eventexperiment_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テスト苦手、というか嫌いでした。

今はもう心を無にして取り組むことができるようになりました。

根本的にはあまり嗜好は変わっていないけれど、大人になったということでしょう。