- ブラウザURL入力
- DNS名前→IP
- ルータ経路選択
- ロードバランサ振り分け
- Nginx受け口
- アプリ処理今ここ
- DB保存
前回は、戻せるのはコードでデータではないことを見ました。最終回は、比べる相手である期待する出力そのものが書けない場合を扱います。
まず結論
正しい出力を人が前もって書けない処理があります。そのとき比べられるのは、1回の実行の入力と出力の関係と、複数回の実行同士の関係です。
どちらも正しい出力を保証しない部分的な判定手順で、関係を満たす誤りは通ります。それでも「観測できない」を「誤りの一部は観測できる」に変える手です。
商品の絞り込み検索をテストしたいが、どの条件で何件返るのが正しいかを人が前もって書けない。期待する出力を書かずに誤りを検出できる検査はどれか。
当てることが目的ではありません。外した予測ほど記憶に残るので、直感で選んでください。
比べる相手が、誰にも書けないとき
このコースの芯は「壊れていない」は何と比べたかでしか言えない、でした。これまでは比べる相手を人が用意できました。期待する出力、前のコミット、きれいな機械。この回は、その相手を誰も前もって書けない場合です。
Barr らのサーベイは、そうしたプログラムを non-testable programs と呼ぶ定義を Weyuker の1982年の論文から引いています(Weyuker の本文は未確認で、Barr らを通した孫引きです)。
“Programs which were written in order to determine the answer in the first place. There would be no need to write such programs, if the correct answer were known.” [196].
答えを知りたくて書いたのだから、答えは手元に無い。Chen らの1998年の報告も、arXiv 掲載の抄録で判定手順(引用内の test oracles)が手に入ることを実用上ほぼ望めないとする Weyuker の指摘を挙げます。
Thirdly, as indicated by Weyuker in [6], the availability of test oracles is pragmatically unattainable in most situations.
正しい出力が無いなら、比べる相手を変えます。候補は2つです。
- 1回の実行の入力と出力の関係。 fast-check は性質(property)を
a relationship between a code's input and output which should hold for all sets of inputsと定義します。 - 複数回の実行同士の関係。 Barr らはメタモルフィック関係を
a relation over applications of f that we expect to hold across multiple executions of pと定義します。
後者は正しい出力と比べる代わりに、実行と実行を比べます。
- ・性質もメタモルフィック関係も、書いた関係しか見ない
- ・並べ替えと絞り込みの例は教材用に作ったもので、Chen らのメタモルフィックテストの例ではない
並べ替えを、答えを書かずに検査する
Python 3.14.6(macOS 26.5.2)で、標準ライブラリだけの検査を書きました。乱数の種を固定しているので毎回同じ結果になり、2回の実行で出力は完全に一致しています。
並べ替えに期待する出力は書きません。代わりに2つの性質を、200回ぶんの乱数の入力で確かめます。隣り合う2つが a <= b(並んでいる)と、入力と出力で各要素の個数が同じ(元の要素の並べ替えである)です。誤った実装として、重複を落とす sorted(set(xs)) を用意しました。
sort_ok : OK 200 trialssort_dedup : NG trial=1 元の要素の並べ替えになっていない xs=[1, 7, 7, 7] ys=[1, 7](並び順だけ検査した場合) sort_dedup: True
誤った実装は2つ目の性質で落ちました。ところが3行目、別に作った50個の入力で並び順だけを確かめると True です。[1, 7] は並んでいます。消えた要素は、並び順の性質には映りません。
重複を落とす並べ替え実装を、「隣り合う2つが a <= b」という性質だけで検査するとどうなりますか。
実行と実行を比べる
並べ替えの性質は、1回の実行の中で閉じていました。出力が何であるべきかを入力だけから言えない処理もあります。検索がそうです。
それでも、2回の実行の結果の間なら言えることがあります。条件を1つ足した検索の結果は、足す前の結果に含まれるはずです。Barr らは、メタモルフィック関係が数式で書ける数値の性質に限られないと書き、検索エンジンを検査した Zhou らの関係を紹介しています。
Barr らが挙げる関係(ROR と名付けられたもの)は、検索が返すページの集合(where the Ai are sets of web pages returned by queries)について、A1 が A2 と A3 の和集合なら A2 の件数は A1 を超えない、というものです。この回の絞り込みの関係に近い例です。
絞り込みで、関係が捕まえるもの・捕まえないもの
同じスクリプトで、5件の商品に対する絞り込みを検査しました。乱数で条件 c1 を選び、そこに条件を1つ足して c2 を作り、「c2 の結果 ⊆ c1 の結果」を200回確かめます。正しい件数はどこにも書いていません。
search_ok : OK 200 trialssearch_or : NG trial=0 条件を足したのに結果が増えた {'color': 'red'}->[1, 3, 4] / {'color': 'red', 'size': 'S'}->[1, 3, 4, 5]search_empty: OK 200 trials (関係は満たすので検出できない)
2行目は、条件を OR で扱う誤った実装です。赤で3件、赤かつ S で4件に増えました(正しい AND なら [1])。
3行目は、常に空を返す実装が通ったことを示します。空は何の部分集合でもあるので、関係は満たされます。関係が比べているのは2回の実行の間の整合であって、どちらの結果の正しさでもありません。
常に空のリストを返す検索実装は、「条件を足した結果 ⊆ 足す前の結果」の検査でどうなりますか。
並べ替えの性質(1回の実行)
入力と出力の関係を2つ書きました。並び順だけなら重複を落とす実装が通り、要素の個数を足すと落ちました。関係の足りない分が、そのまま検査の穴になります。
性質 重複を落とす実装隣り合う2つが a <= b 通る各要素の個数が同じ 落ちる
絞り込みの関係(2回の実行)
条件を足した結果が足す前の結果に含まれるかを比べました。OR で扱う実装は落ち、常に空を返す実装は通りました。関係は2回の結果の整合しか見ません。
実装 c2 の結果 ⊆ c1 の結果OR で扱う 落ちる常に空を返す 通る
1回の実行の関係と、2回の実行の関係。比べ方は違いますが、どちらにも共通する限界は何でしょうか。
それぞれの表で「通る」と書かれた行が、なぜ通ったのかを見てください。
この章のまとめ
- 正しい出力を前もって書けない処理がある。Barr らは Weyuker 1982 を引いて non-testable programs と呼ぶ(孫引き)。
- そのときの比べる相手は、**1回の実行の入力と出力の関係(性質)**か、複数回の実行同士の関係(メタモルフィック関係)。混ぜない。
- 並べ替えは「並んでいる」だけでは足りない。重複を落とす実装が通った。
- 絞り込みは「条件を足した結果 ⊆ 足す前の結果」で OR の誤りを捕まえたが、常に空を返す実装は通った。
- どちらも部分的な判定手順。緑は「書いた関係を、試した入力で破らなかった」まで。
- 序章に戻ると、これは観測できない領域に当てる観測器を1つ増やす手。何と比べるかを決めるのは、最後まで人。
自分の現場で確かめる
読んだだけでは身につきません。手元の環境で実際に見てみてください。
理解度チェック
読んだ直後は「分かった」と感じやすいものです。実際に解いて確かめてください。
fast-check の文書が定義する「性質」と、Barr らが定義するメタモルフィック関係の違いとして正しいのはどれか。
用語集(4語)
- 性質(property)
- すべての入力で成り立つはずの、入力と出力の関係。fast-check は `an assertion of a relationship between a code's input and output which should hold for all sets of inputs` と定義する。1回の実行の中の関係。
- メタモルフィック関係
- 複数回の実行の間で成り立つはずの関係。Barr らの定義に従う。この回の例では「条件を足した検索の結果は、足す前の結果に含まれる」。
- 判定手順
- このコースの言い方。実行結果が正しいか誤っているかを決める手順。英語の文献では test oracle と呼ぶ。
- non-testable programs
- 答えを知るために書かれたので、正しい答えを前もって知りようがないプログラム。Barr らが Weyuker 1982 を出典として引く語。
出典(一次ソース)
- T. Y. Chen, S. C. Cheung, S. M. Yiu「Metamorphic Testing: A New Approach for Generating Next Test Cases」Technical Report HKUST-CS98-01, 1998(arXiv 掲載 2020-02-28) ↗
- E. T. Barr, M. Harman, P. McMinn, M. Shahbaz, S. Yoo「The Oracle Problem in Software Testing: A Survey」IEEE TSE 41(5), 2015 ↗
- fast-check — What is Property-Based Testing?(Last updated on Feb 7, 2026) ↗