こんにちは。 @otukutunです。 今回とあるキャンペーンサイトでGoogle オプティマイズのリダイレクトテストとCakePHPを連携して、すばやくABテストできる仕組みを構築したのでその方法について説明します。
Google オプティマイズとは
Google オプティマイズはGoogleが提供しているABテストツールで、無料で提供されています(2022/03/11時点)。Google製ということもあり、Googleアナリティクス連携がスムーズにできる使い勝手のよいツールです。Google オプティマイズには様々なテスト方法が提供されていて、A/B テストやサーバーサイドテスト、リダイレクトテストなど様々な方法(エクスペリエンス)が提供されています。
各方法の具体的な説明はこちらの公式ページに見ていただくといいですが、ざっくりと説明すると
- A/B テストはHTMLや画像などのクライアントサイドの要素をテストできる、各種variantの振り分けはGoogleオプティマイズに任せることができる
- サーバーサイドテストはサーバーサイド側の要素もテストできる、ただし各種variantは自前でする必要がある(サーバーサイドテストの詳細はこちら)
- リダイレクトテストはランディングページ(以下LP)のテストができる、各種variantの振り分けはGoogleオプティマイズで行われ、ランディング後にリダイレクトされる
になっています。
サーバーサイドの変更をテストする場合は、サーバーサイドテストとリダイレクトテストが候補として上がりましたが、今回はリダイレクトテストを選択して行いました。理由としてはいくつかあるんですが
- 今回の対象がキャンペーンサイトでLPは1つになるので、リダイレクトテストでも要件を満たせた(サーバーサイドテストである必要がなかった)
- リダイレクトテストではVariantの比率などをwebページから操作できるので柔軟に設定できる(後から比率を変更することもできます)。サーバーサイドテストではサーバー側で実装する必要がある
- 結果が分かった段階で、一旦成果がでたvariantに寄せることができる
- Google Optimizeの設定が実装依存が少ないのでシンプルになる
などの利点があり、リダイレクトテストにしました。
リダイレクトテストを実施する
リダイレクトテストと連携するために
- LPでvariantを表すクエリストリングストリングからvariant設定する
- variantを取得する機能を提供(切り替えのため)
- (任意) 完了ページでURLでクエリストリングを付与する
を実装して連携できるようにしました。実装例はCakePHPですが、他の言語やフレームワークでも同じような実装でできるかと思います。
オプティマイズの設定
パターンでLPのvariantごとのURLを設定し、ページターゲティングを設定するだけです(目標数値などの設定は今回のテーマではないので省略します)。
CakePHPの実装
実装はシンプルでLPでクエリパラメータをみてvariantを設定して、それによって挙動を変えてあげるだけです。endページではクエリパラメータをつけることでどのvariantかをGAだけでなく広告のコンバージョンタグでも判別が容易になるようにしています。
CampaignsController.php
<?php class CampaignsController extends AppController { public function lp() { // ABテスト開始 $this->startABTest(); // variant毎に処理を変える if ($this->getABTestVariant() === 'a') { // オリジナルの場合 } else if ($this->getABTestVariant() === 'b') { // variant Bの場合 } // variantをクエリストリングに付与する $this->redirect('controller' => 'Campaings', 'action' => 'end', '_method' => 'GET', ['?' => ['variant' => $this->request->getSession()->read('ab_test_session')]]); } public function end() { // クエリストリングにvariantが付与される } /** * ABテストのタイプを設定 */ private function startABTest() { // 設定済みの値 $current = $this->getRequest()->getSession()->read('ab_test_session'); $variant = $this->request->getQuery('variant'); if (!in_array($variant, ['a', 'b'])) { // クエリパラメーターなしの場合は既に設定されている値、それもない場合はaとする $userType = $current ?? 'a'; } $this->getRequest()->getSession()->write( 'ab_test_session', $userType ); } }
Viewで挙動を変えたい場合はこんな感じで、切り分ければいけます。
lp.ctp
<?php // variantを取得 $abTestVariant = $this->request->getSession()->read('ab_test_session') ?> <?php if ($abTestVariant === 'a'): ?> <p>Aだよ~</p> <?php elseif ($abTestVariant === 'b'): ?> <p>Bだよ~</p> <?php endif; ?>
おわりに
Google オプティマイズのリダイレクトテストと簡単な仕組みでvariantの振り分けは任せつつvariant毎の実装に集中できるようになりました。今はComponentとHelper化してさらに使いやすくなり、素早くABテストを行えるようになっています。何かの参考になれば幸いです。ではまた!