プロパティベーステストとは?
プロパティベーステストは、手作業で選んだ少数のケースを確認するのではなく、自動生成された多数の入力にわたって一般的なプロパティが成り立つことを表明します。
ほとんどのテストは、あなたが手作業で選んだ例を使います。プロパティベーステストはその代わりに、常に真であるべきルールを表明し、それを破ろうとして何百ものランダムな入力をフレームワークに生成させます。失敗する入力を見つけると、それを最小の例までシュリンク(縮小)し、手作業では決して書かなかったであろうエッジケースをしばしば明らかにします。
例ではなくプロパティ
reverse([1,2,3]) が [3,2,1] に等しいと表明する代わりに、プロパティを表明します。リストを2回反転させると元のリストになる、というものです。フレームワークはそのプロパティに対して多数のランダムなリストを投げ込み、例ベースのテストよりもはるかに広い入力空間を探索します。
生成とシュリンキング
フレームワークはデータの記述から入力を生成し、プロパティを実行し、失敗するとその入力を依然として失敗する最小のケースまでシュリンクします。シュリンキングこそがこの手法を実用的にするものです。巨大なランダムな失敗の代わりに、小さくデバッグ可能な反例が得られます。
簡単な例
ラウンドトリッププロパティは、任意の文字列をエンコードしてからデコードすると元に戻ることを、多数の生成された文字列にわたって確認します。
A round-trip property
forAll(strings, (s) => {
expect(decode(encode(s))).toBe(s);
});得意とすること
- 人間が見逃す境界ケースやエッジケースを見つけること。
- シリアライゼーション、パース、ラウンドトリップのテスト。
- 数学的またはインバリアント型のプロパティの検証。
- 例ベースのテストを置き換えるのではなく補完すること。
CIにおけるプロパティベーステスト
各プロパティを多数の入力にわたって実行するため、プロパティベーステストは単一の例テストよりも重く、生成された入力が真の非決定性を露呈することがときどきあります。ランダムシードを固定することで実行を再現可能に保ち、これらのスイートを高速なrunnerで実行することで余分な入力量を吸収します。
重要なポイント
- プロパティベーステストは、多数の生成された入力にわたって不変条件を検証します。
- シュリンキングは、失敗を最小限でデバッグ可能な例まで縮小します。
- エッジケースやラウンドトリッププロパティに優れています。CIではシードを固定しましょう。
関連ガイド
What Is Fuzz Testing?Fuzz testing explained: feeding random or malformed input to find crashes and security bugs, coverage-guided…
What Is Mutation Testing?Mutation testing explained: how it grades your tests by introducing bugs and checking if tests catch them, th…
What Is a Unit Test?Unit testing explained: what a unit is, why these tests are small and fast, a simple example, common pitfalls…
What Is a Flaky Test?Flaky tests explained: tests that pass and fail on the same code, the common causes, an example, the damage t…