mcpField
P
property-based-testing

property-based-testing

github.com/trailofbitsテスト・品質7.9k7.1k 回インストール今日更新
リポジトリ

property-based-testing について

不変条件、往復性、参照結果など検証可能な規則を持つコードに、プロパティベーステストを適用するためのガイダンスです。有意義なプロパティの設計、空疎なテストの回避、適用の適否判断を支援します。

主な機能

  1. 01プロパティパターン集
  2. 02テスト入力生成のガイダンス
  3. 03恒真・空疎なテストの検出
  4. 04リファクタリングによる検証箇所の抽出
  5. 05失敗分析とライブラリ選択の参考資料

活用シーン

  1. 01シリアライズや変換のプロパティ設計
  2. 02既存のプロパティテストのレビュー
  3. 03生成テストの失敗調査
  4. 04プロパティベーステストの適否判断

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/trailofbits/skills --skill property-based-testing

インストール後、Claude Code で/property-based-testingを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

README.md
agents/
openai.yaml
assets/
trail-of-bits-mark.svg
references/
generating.md
interpreting-failures.md
libraries.md
refactoring.md
reviewing.md

詳細

プロパティベーステスト

サンプルテストは1つの点を検証します。プロパティは入力ドメイン全体にわたる規則を検証し、生成器に反例を探させます。この方法を選ぶ価値があるのは、コードに代数的な構造(逆演算、不変条件、オラクル)がある場合で、それ以外ではありません。そのような構造がないコードにはサンプルテストを使います。そのように判断することも、妥当な結論です。

まず、その構造が欠けているのか、単に埋もれているだけなのかを確認してください。I/Oでラップされた計算、連結で組み立てられた文字列、その場でのミューテーションには、それぞれプロパティがあり、それを検証するための継ぎ目がないだけです。検証できるものが何もないと結論づける前に、references/refactoring.mdを参照してください。

プロパティの一覧

プロパティ数式適用先
ラウンドトリップdecode(encode(x)) == xシリアライズ、変換のペア
逆演算f(g(x)) == x暗号化/復号、圧縮/展開
オラクルnew(x) == reference(x)最適化、リファクタリング、再実装
冪等性f(f(x)) == f(x)正規化、フォーマット、ソート
不変条件前後で成立するあらゆる変換、コントラクトの状態
検証が容易is_sorted(sort(x))検証器のコストが低い複雑なアルゴリズム
可換性f(a, b) == f(b, a)二項演算、集合演算
結合性f(f(a,b), c) == f(a, f(b,c))結合する演算
単位元f(x, e) == x中立元を持つ演算

強さの順序(弱いものから強いものへ): クラッシュしない → 型の保持 → 不変条件 → 冪等性 → ラウンドトリップ/オラクル。

コードで検証できる、最も強いプロパティをアサートしてください。「クラッシュしない」だけでは、依存関係を追加する根拠として不十分なことがほとんどです。それしか見つからない場合は、小規模なコードの並べ替えでより強いプロパティを明らかにできるか、あるいはこのコードはPBTに適さない候補だと率直に報告してください。後者を選ぶ前に、前者を検討してください。

プロパティテストが何もアサートしない2つのケース

  • トートロジー。 assert add(a, b) == a + bは実装を言い換えているだけなので、両者に共通するバグは検出できません。関数を再計算せずに制約できるプロパティを選んでください。ただし例外があります。f(x) == f(x)は、fが明らかに純粋でない場合、真の決定性プロパティです。たとえば、dictやsetを対象にするシリアライザー、ハッシュ化、時刻を読み取る処理などです。
  • 空疎性。 ほぼすべての入力を除外するassume()は、何も実行せずにテストを通過させます。また、矛盾するassume()は、ケースを1つも実行せずに通過します。制約をストラテジーに組み込み、生成器が有効な入力を直接生成するようにしてください。

次に参照するもの

目の前のタスクに合うものを読み込んでください。

タスクファイル
新しいテストの作成、ストラテジーの設計references/generating.md
アサートできるプロパティがまだコードにないreferences/refactoring.md
既存のプロパティテストのレビューreferences/reviewing.md
プロパティテストが失敗したreferences/interpreting-failures.md
ライブラリの選択、EchidnaとMedusareferences/libraries.md

PBTを導入していないプロジェクトへの導入

プロジェクトですでにPBTライブラリを使用している場合は、それを使ってテストを書いてください。使用していない場合は、ライブラリの追加はユーザーが判断する依存関係の選択です。書く予定の具体的なプロパティを添えて一度提案し、どちらの回答でも受け入れてください。

コメント