ナレッジ
【連載】なにそれ?あなたの知らないテストの言葉(第4回):プロパティベーステスト(Property Based Testing)

マンガ連載:プロパティベーステスト(Property Based Testing)

解説:プロパティベーステスト(Property Based Testing)
このマンガ連載では普段目にすることが少ない「なにそれ」という用語をピックアップして解説します。
第4回は「プロパティベーステスト(Property Based Testing)」です。
プロパティベーステストとは、システムや関数が満たすべき性質(プロパティ)を定義し、さまざまなデータを自動的に生成して入力し、その性質が常に成り立つかを検証するテスト手法です。
通常のテスト(例示でのテスト)では、「特定の具体的な入力に対して、期待する具体的な結果が得られるか」をテストします。マンガで例えた名前のテストであれば、「たけし」や「ジョン」といった特定の文字列を使ってテストします。
プロパティベーステストは、個別の入力・出力の例ではなく「『どんな入力に対しても常に成り立つはずの性質(プロパティ)』を定義する」という違いがあります。よく使われるプロパティの例としては、「配列を2回反転したら元の配列に戻る」「ソートした配列は常に昇順になっている」などがあります。他にも文字列のスペースを削る仕様のプログラムであれば「どのような入力を渡しても、出力には常にスペースが含まれていない」というプロパティが挙げられます。そして数多くのデータを自動生成・入力し、そのプロパティが常に成立するかを検証します。シンプルに言い換えると、出力に現れる特徴が定義に沿っているかどうかで判定するテスト手法と言えるでしょう。
プロパティベーステストは主にライブラリを用いて実行されます。その機能としてシュリンク(shrinking)と呼ばれる自動デバッグ支援機能があります。プロパティに沿っていない入力が見つかった際に、その失敗を引き起こす最小の失敗ケースを探してくれる機能です。また失敗したケースを再テストに利用する機能を持っているものもあります。
プロパティベーステストのメリット
大量のデータで検証し、予期しないバグを検出できる場合がある
以前、キャラクター名に「ソ」が入ると問題が発生する不具合がありました。これは5C問題といわれ古参のエンジニアには知られています。しかし、キャラクターコードがShift_JISでの問題なので最近では知らない方も多いのではないでしょうか。
知らない方がキャラクター名のテストを例示のテストで作った場合「ア」や「ン」といった入力は挙げても「ソ」を使ったテストは思い付くものではありません。プロパティベーステストでは、プロパティの定義次第ですが、大量の文字列を自動生成して検証するため、問題を発見できる可能性もあります。
プロパティベーステストのデメリット
プロパティの定義を間違えると、意味のないテストになってしまう可能性がある
例えば、配列のソート機能があるとします。このときプロパティを「入力時と出力時で要素の数が変わらない」と定義してテストしたとします。本来確認したいことはソートのため、要素数をプロパティに設定すると、ソート機能の正しさを検証できないテストとなります。
また、マンガでは「ひらがな・カタカナ以外の文字は削除される」仕様についてプロパティを「出力は常にひらがな・カタカナまたは空白となる」と定義しました。これはプロパティを伝えるために分かりやすさ優先で書いたものです。絵文字などが混じった文字列を入力し、出力がひらがな・カタカナのみになれば削除がうまくいったと思えなくもありません。
しかし例えば「はら♡ペコ」という文字列が入力され、誤って絵文字以降も削除されてしまい「はら」のみになったとします。この場合も先の定義では合格となります。よってこのプロパティの定義では文字の削除のテストとしては弱いと言えます。この場合は素直に入力と期待結果をセットにしたこれまで通りの例示のテストの方が良いでしょう。
代表的なプロパティの例
書き込み→読み込み
データを書き込み、そのデータの読み込みをすると、読み込んだデータと書き込んだデータは等しいはずです。違いが出た場合は、書き込みか読み込みの過程でバグがある可能性があります。
1回目の結果と2回目の結果が等しい
マンガで示したような不要な文字の削除が例として挙げられます。1回目の処理で不要な文字列は削除しているため、再度同じ処理をしても結果は変わらないはずです。
入力順を変えても結果が等しい
例えば、足し算「1 + 2 = 3」は入力順を変更し「2 + 1 = 3」でも結果は変わりません。データをどういった順で入力しても、またはデータの並び順が異なっても結果は同じといった場合です。
逆操作
データや操作を反転させ、再度反転させると元の状態に戻ります。例えば、「やり直し機能」があったとします。あるデータ変更を「やり直し」し、そのやり直しを「やり直し」すると、データはやり直し以前の状態に戻るはずです。
Pythonでのプロパティベーステストの例
Pythonでのプロパティベーステストではhypothesisが使われることが多いです。今回はhypothesisを使ったプロパティベーステストの例をgithubに用意しました。ご興味がありましたらご覧ください。
https://github.com/jam0824/PropertyBasedTesting
マンガでわかるソフトウェアテスト入門
よろしければこちらもご覧ください。
この記事は面白かったですか?
今後の改善の参考にさせていただきます!

































.png)






























