ja en en ja ja ja ja ja ja ja ja ja ja ja ja ja en ja ja ja ja ja en ja ja ja en ja ja ja ja ja ja ja ja en ja ja ja ja ja ja ja ja ja ja ja ja ja ja ja ja en ja ja ja ru ja ja ja ja ja en ja ja ja ja ja en ja en ja ja ja ja ja ja ja ja ja ja ja ja ja ja ja ja ja ja ja ja ja ja ja ja ja ja fr ja ja ja ja ja ja en en ja ja en ja ja ja ja ja ja ja ja ja zh ja en en ja ja zh ja zh zh zh ja zh zh zh ja zh ja zh ja zh zh zh zh zh ja ja ja ja ja ja ja ja ja ja ja ja ja ja ja ja ja zh ja zh ja ja ja ja ja zh ja ja zh zh ja ja ja ja ja zh ja ja ja ja en en ja ja ja en ja
「 We Help People Get Jobs (人々の仕事探しのお手伝いをする)」 ― これが Indeed のミッションだ。
以来、 Proctor Web アプリのオープンソース化も実現している。こちらは Proctor のテスト定義を管理する Web アプリケーションだ。
図 1 は、コントロールグループ A とテストグループ B を表している。 A は、 Find Jobs (求人検索)ボタンに変更を加えていないもの。一方 B は、ボタンの背景色が青に変更されている。
図 1 : 現行のボタン(A) VS. 背景色を青に変更したボタン(B)
上に挙げたシンプルなテストを行うために、まず Indeed サイトにアクセスした各ユーザーのグループ( A または B )とその後派生するクリック数のログを取った。そして、自社の分析ツールを使用したところ、明らかになったのは、この場合はテストグループの方が、より多くの検索、そしてさらなるユーザー・エンゲージメントをもたらす、という事だった。
上記の例は、1つのテストの挙動だが、通常僕らは 1 件のテストにつき代替案となる複数の挙動をテストする。このテストでは、おそらく背景色を 2 つ以上は試すかと思われる。
このように、機能の中である特定の部分に対して、複数の変数 (テキストや色) をテストすることは、 「多変量テスト」 として知られている。
図2:  1 つのボタンに対して同時に 2 つのテストを実行する
今回の記事では、 Proctor の主要な機能とコンセプトを中心に、 Indeed の基本的なProctor の利用法を述べていく。
図 3 はとてもシンプルなバージョンのボタン・テストを表している。この図では、 50% のユーザーがコントロールグループ A ( バケット 0 ) に割り当てられ、残りの 50% はテストグループ B(バケット1)に割り当てられている。
"buttontst": { "description": "backgroundcolortest", "salt": "buttontst", "buckets": [ { "name": "control", "value": 0, "description": "current button treatment (A)" }, { "name": "altcolor", "value": 1, "description": "test background color (B)" } ], "allocations": [ { "ranges": [ { "length": 0.5, "bucketValue": 0 }, { "length": 0.5, "bucketValue": 1 } ] } ], "testType": "USER" }
図 3 : シンプルな Proctor のテスト定義
全てのテストにはテストタイプ (testType) が存在する。もっとも一般的なタイプはユーザー (USER) である。これは、僕らがユーザー識別子を使ってテストのバリエーションをマップする事を意味している。テストタイプについて、後でさらに詳しく述べたいと思う。
各テストはバケット (buckets) の配列とアロケーション (allocations) の配列からなる。
バケットは Proctor のテスト定義内のバリエーションまたはグループを指す。各バケットは短い名前 (name) 、整数値 (value) 、そして解りやすい説明 ( description ) を含んでいる。
アロケーションはバケットのサイズを範囲 (range) の配列として指定する。各範囲は 0 から 1 の間の長さで、バケット用にバケットの値 (bucketValue) への参照を持つ。1つのアロケーションの範囲の合計は1になる必要がある。ルールを使用すれば、複数のアロケーションを持つ事ができる(これも詳しくは後述)。
Proctor Web アプリ
Proctor Web アプリを使用する事で、テスト定義をWeb ブラウザから管理・デプロイする事ができる。
このアプリは、色々な方法でカスタマイズでき、以下のようなシステムやツールとの統合を可能にしてくれるのだ。
テスト変更履歴を維持するバージョン管理システム
テスト変更のワークフローを管理するための課題トラッキングシステム
ビルドやデプロイシステムなどのその他の外部ツール
図 4: Proctor Web アプリ内のテスト定義のスクリーンショット
JSON のテスト仕様から Java コードを生成する
Proctor 内のテスト仕様は テスト定義から独立した JSON ファイルである。これは、テスト定義のフルセットの中から、アプリケーションがどのテストとバケットを認識しているかを宣言できるようにしている。
これらは、ビルドプロセスではJava コード生成の際に使用可能だ。実行時には、テストマトリックスの関連部分を読み込む際に使用できる。
コード生成は任意だが、コンパイル時のタイプセーフを提供してくれるので、テストとバケット名を含む文字列リテラルを持つコードを捨ててしまう必要がなくなる。
また、生成されたクラスは Java コードやテンプレート言語のテストを書くのを簡単にしてくれる( 図5はJSPでの例 )。
さらに、生成された Java のオブジェクトは、ユーザーがそのテストグループに割り当てられているかどうかを JSON や XML などの形式へとシリアライズする事ができる。
.searchBtn { background-color: #2164f3; color: #ffffff; }
図5 : テストグループ・メンバーシップに基づいたJSPテンプレート内の条件付き CSS
ルールに基づくコンテクスチュアル・アロケーション
Proctor のルール定義の言語を使用すると、ランタイム・コンテキストに対してルールを評価することができる。そうする事で、システムはテストならびにテスト・アロケーションを適用する事ができる。
例えば、テスト全部が、特定のセグメントのユーザーにのみ利用可能になるように定義することが可能になる。または、セグメントに応じて、テストグループのアロケーションを調整する事もできる。ある国では、テストを A/B で 50% ずつで行い、その他全ての国で A/B/C/D で 25% ずつにすることもできる。
ルールに基づいたグループの割り当てを行うと、柔軟にテストをロールアウトし、評価することができるようになるのだ。
"allocations" : [ { "rule" : "'US' == country && 'en' == userLanguage", "ranges": [ { "length": 0.5, "bucketValue": 0 }, { "length": 0.5, "bucketValue": 1 } ] }, { "rule" : null, "ranges" : [ { "length" : 1.0, "bucketValue" : -1 } ] } ]
図6: 米国英語使用者向け 50/50 テストその他ユーザーには無効なテスト ( bucket -1 ) である。
テスト定義において、テストグループにデータのペイロードを添付可能である事は、コードをシンプルにしてくれる。
図の 7 と 8 では、テストしているボタンの色をテスト定義の中でどのようにペイロードとして指定できるか、指定された色にテンプレートからどうやってアクセスできるかを具体的に示している。
この例では、テンプレートコードの総量は減ってはいないが、もし複数のテストバリエーションがあって、それぞれ別の色を指定していたら、ペイロードを使用することでコードの行数は減るだろう。
"buckets": [ { "name": "control", "value": 0, "description": "current button treatment (A)", "payload": { "stringValue": "#dddddd" } }, { "name": "altcolor", "value": 1, "description": "test background color (B)", "payload": { "stringValue": "#2164f3″ } } ]
図7 : 色の値を含むデータ・ペイロードをテストグループ B に添付
.searchBtn { background-color: ${groups.buttontstPayload}; }
図8 :  JSP テンプレートを使用した CSS でのデータ・ペイロードのアップデート
Proctor はテストタイプに関して柔軟なコンセプトを持っている。
バケットの決定は以下に基づいて可能だ。
ユーザー(通常トラッキング・クッキーの値によって定義される)
アカウント ID (デバイス間で固定可能)
またはリクエスト間で完全にランダムにすることもできる。
さらに、Proctor はテストタイプをカスタマイズして拡張することも可能だ。
例えば、ページ URL やコンテンツ・カテゴリのような、コンテキストあるいはコンテンツに基づく attributeでテストグループを決めたいときには、カスタマイズしたテストタイプは便利である。
バイアスのない独立したテスト
一様分布のハッシュ関数を使用して、 Proctor は インプットとなる識別子 ( 例.ユーザーID )を整数にマップする。テストにバケットを割り当てるためである。
バケットに対する範囲の割り当てが、各バケットを定義する整数の範囲を決定するのだ。図 9 は 50/50 の割合のコントロール/テストの例だ。ハッシュ関数が一様なので、バケットの指定はバイアスのないものになるはずである。
図 9 : ハッシュ関数使用のため、整数の範囲にマップされた 50/50 のコントロール/テスト・バケット
さらに、 Proctor のテストは独立している。つまり、あるテストで特定のテストグループに属していることは、他のテストでどのテストグループに属するかということに全く相関がないのだ。
この独立性は、各テストに異なる salt を割り当てることで成立している。この salt はハッシュ関数への input として識別子と一緒に使用される。
各テスト定義に異なる salt を含める事で、次の2つの高度な機能が使用可能だ。
同じ salt を複数のテスト間で共有し、異なるテスト間で意図的にバケットをそろえる(相互に依存させる)ことができる。ただし、共有の salt は “&” で始まらなければならない。実際には、この方法で 2 つのテストをそろえる必要があるケースは殆ど目にしない。
salt を変更する事で、テストの配分の「シャッフル」が可能になる。というのは、ハッシュ関数からまったく異なる output がかえってくるからだ。このシャッフルを行う事で、テスト内に偶発的なバイアスがないか再確認する事ができる。
Indeed における Proctor
Indeed のプロダクト開発に対するデータドリブンなアプローチにおいて、Proctor は重要な役割を担うようになった。
現在本番環境には、 100 件以上のテストと 300 件以上のテストのバリエーションが存在する。
次回のポストでは Indeed での Proctor 使用法をより詳細に説明していく。
« バグ・バウンティ・プログラム
脆弱性発見者には報奨金: 挑戦者求む:Indeed (2013~2014年) コーディング・デュエル »
@ Indeed テックトーク
Indeedのオープンソースプロジェクト»
Indeed ユニバーシティ»
エンジニア採用 @ Indeed Tokyo
Indeedの採用情報を全て見る
CPU スロットリング 2
Uncategorized 1
エンジニアリング 27
エンジニアリング文化 25
データサイエンス 13
Toggle More
2022年4月 (2)
2022年2月 (1)
2021年6月 (1)
2021年3月 (1)
2021年2月 (1)
2020年12月 (1)
2020年11月 (1)
2020年10月 (1)
2020年9月 (1)
2020年8月 (1)
2020年7月 (1)
2020年3月 (1)
2020年1月 (2)
2019年12月 (2)
2019年11月 (1)
2019年10月 (1)
2019年9月 (3)
2019年8月 (3)
2019年7月 (2)
2019年3月 (1)
2019年2月 (1)
2018年12月 (6)
2018年11月 (1)
2018年10月 (5)
2018年9月 (1)
2018年6月 (2)
2018年4月 (1)
2018年2月 (1)
2018年1月 (1)
2017年12月 (2)
2017年11月 (5)
2017年6月 (2)
2017年3月 (1)
2017年1月 (1)
2016年12月 (1)
2016年10月 (1)
2016年9月 (1)
2016年3月 (2)
2016年2月 (1)
2015年12月 (2)
2015年9月 (1)
2015年7月 (1)
2015年3月 (2)
2015年2月 (1)
2015年1月 (2)
2014年12月 (1)
2014年11月 (1)
2014年10月 (1)
2014年9月 (1)
2014年8月 (1)
2014年6月 (1)
2014年4月 (1)
2014年2月 (2)
2013年12月 (1)
2013年10月 (2)
2013年9月 (1)
2013年8月 (1)
2013年3月 (2)
2013年2月 (2)
2012年12月 (1)
2012年11月 (2)
Toggle More
Back to top
©2022 Indeed - Cookies, Privacy and Terms of Service