顧客は「速く」とだけ書いた
一言でいうと
受け入れ基準は、顧客の形容詞を指標・計算方法・基準値・測定条件の4つの部品に置き換えたものです。受け入れテストの実行ツールは、その基準表をコードの外から読み、リクエストを送って、証拠と判定をあわせて残します。
なぜ必要なのか
購買チームのメールには、「見積もりの照会が速く動作する必要があります」という一文だけがありました。開発チームは、平均が80msなので速いと言い、運用チームは、昨日の午後に照会画面が3秒ずつ止まったと言いました。どちらも事実です。20回に1回止まるサービスは、平均で見れば速いのです。受け入れの会議でこの違いが表に出ないと、納品のあとで、「速いと言ったじゃないですか」と「速くないじゃないですか」がぶつかります。
FDEにとって受け入れ基準は、文書作業ではなく、交渉の成果物です。顧客が望む体験を数字に移しつつ、その数字が何をどう測った値なのかまで合意してはじめて、あとで同じ数字を前にして違うことを言わずに済みます。さらに、合意した数字をコードに埋め込むと、基準が変わるたびに実行ツールを直す必要があり、どのバージョンの実行ツールが、どの基準で判定したのかがあいまいになります。基準表をファイルにする理由です。
どう動くのか
Google SREの書籍のサービスレベル目標の章は、SLIを平均だけで集めると、大半は速く、長いテールははるかに遅いという状況が隠れると警告し、パーセンタイルで分布の形を見るよう勧めています。同じ章は、SLOの自然な形を「SLI ≤ 目標」と書いています。このラボの基準表の1行が、まさにその形です。
{"id": "quote-latency", "metric": "p95_ms", "op": "<=", "threshold": 250,
"source": "견적 조회가 빠르게 되어야 합니다"}
計算方法まで書く必要があります。「p95」は、1つの値ではありません。Pythonのstatistics.quantilesは、デフォルトがexclusive方式で、2つのサンプルの間を線形補間し、inclusive方式も別にあります。実測で、40件のリクエストのうち38件が5ms、2件が400msのとき、3つの方式を比べました。nearest-rank(並べ替えたあとのceil(0.95×n)番目の値)は5.0、quantiles(n=100)の95番目の分割点は、exclusiveで380.25、inclusiveで24.75でした。基準値が250msなら、同じ証拠が、方式によって、合格にも不合格にもなります。そのため、契約書にnearest-rankを明記し、証拠から誰でも計算し直せるようにします。
測定条件も基準です。遅延は、リクエストを送ってから本文をすべて受け取るまでを、time.perf_counterで測ります。ドキュメントは、この時計を、短い区間を測るための最も精密な時計と説明し、基準点が決まっていないので、2回の呼び出しの差だけに意味があると書いています。CPythonでは、後ろに戻らないmonotonicの時計と同じ時計です。一方、time.time()は、2回の呼び出しの間にシステムの時計が後ろに調整されると、より小さな値を返すことがあると、同じドキュメントに書かれているので、区間の測定には使いません。エラー率は、「何をエラーと数えるか」が先です。この顧客とは、200ではない応答と、1000ms以内に届かなかった応答を数えることにしました。urllib.requestのドキュメントは、urlopenのtimeoutを、接続の試行のようなブロッキング動作1つ1つの制限だと説明しています。リクエスト全体の締め切りではないという意味なので、少しずつ流して送ってくるサーバーでは、基準より長くかかることがあります。実行ツールは、測った時間を証拠にそのまま残して、こうした場合を表に出します。
正確性と再現性は、別々に測ります。正確性は、顧客がくれたケース表の期待値と比べ、再現性は、同じケース表を2回照会して、結果どうしを比べます。2回目の比較では、request_idや生成時刻のように、毎回変わるのが正常なフィールドを除く必要があり、どのフィールドを除くかも基準表に書きます。コードに書いておくと、サーバーがフィールド名を変えた瞬間に、正常なビルドが不合格になります。
| 顧客の文 | 指標 | 基準 | 測定条件 |
|---|---|---|---|
| 速く | p95_ms (nearest-rank) | 250以下 | リクエスト全体、本文の受信まで |
| エラーなく | error_rate | 0.01以下 | 200ではない+1000ms超過 |
| 金額が正しく | mismatches | 0 | 1回目、ケース表の期待値と比較 |
| もう一度動かしても同じに | rerun_diffs | 0 | 1・2回目の比較、変わるフィールドを除く |
現場での姿
最もよくある失敗は、判定だけの報告書です。「受け入れテストに合格」という一行を受け取った顧客の運用チームは、その言葉を検証する方法がなく、2か月後に障害が起きれば、テストが何を測ったのかから、問い直すことになります。リクエストごとに、遅延・状態・応答を残した証拠があれば、顧客が自分の方法で計算し直せます。証拠から計算し直した値と、報告書の値が違えば、報告書を信じません。このラボの採点ツールがしていることが、まさにそれです。
2つ目は、基準を事後に直すことです。候補ビルドが金額の基準で不合格になったので、「1ウォンの違いは四捨五入だから許容しよう」と基準表を変えて、もう一度実行する場面です。許容誤差が必要なことはありえます。しかし、それは顧客と新しく合意する事柄であり、実行ツールを動かした人が、結果を見て決めることではありません。判定の報告書に、基準値をそのまま書き写す理由も、ここにあります。
実務で本当に大切なこと
- 形容詞1つごとに、指標・計算方法・基準値・測定条件を書き、根拠となった顧客の文もあわせて残します。
- 基準値は、基準表から読みます。実行ツールに数字が埋め込まれていると、基準が変わった日に、静かに間違います。
- リクエスト数を正確に守ります。ウォームアップや再試行を混ぜると、エラー率とパーセンタイルの分母が変わります。
- 証拠を先に残し、判定は証拠から計算します。再計算が同じであってはじめて、報告書です。
次のラボですること
顧客のメールと議事録を基準表に移したあと、遅延・エラー率・正確性・再現性を、順に実行ツールに入れます。採点ツールは、ダミーの見積もりサーバーで、テールが遅いビルド、ときどき止まったり500を返したりするビルド、一部の金額が1ウォン間違っているビルド、再照会が揺らぐビルドを立ち上げ、基準値とケース表を毎回変えて、実行ツールを動かします。最後に、顧客の候補rc2を自分で立ち上げ、受け入れの可否を判定します。