BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース 多くの入力パターンをテストできるProperty-based Testing

多くの入力パターンをテストできるProperty-based Testing

Property-based Testingは、特定の例に頼るのではなく、常に真となるはずのステートメントを指定するアプローチである。これにより、より少ないテスト回数で、多くの入力に対して機能をテストできる。

Lucy Mair 氏はNDC Oslo 2023でProperty-based Testingについて語った。

Property-based Testingとは、プロパティ(前提条件を満たす全ての入力に対して、ある述語が成り立つ)を特定し、それを使ってテストを記述するテクニックである、とMair氏は説明する。

はじめに、プロパティを特定するような関数を書きます。すなわち、前提条件を満たす入力を受け取り、述語が成り立つことを確認する関数です。次にProperty-based Testingのフレームワークを使って、様々な入力を生成し、関数を実行して述語が成り立つかをチェックするのです。

Mair氏はFsCheckとF#を使った例を紹介したが、このテクニックはどの言語にも使える。

Property-based Testingを書くもっとも大きな利点は、多数のテストを書くことなく多数の入力で関数をテストできることだ。とMair氏は言う。Property-based Testingを実行するたびに異なる入力を使用するため、一般的な場合でコードが機能することを確認できる。Mair氏は、テストすることを思いつかない入力のエッジケースを見つけるのに特に価値があると述べた。

Property-based Testingは、多くのケースを生成してテストすることで機能するため、従来の単体テストよりも時間がかかる。パフォーマンスへの影響は、特定の用途によって異なるとMair氏は言う。

InfoQはLucy Mair氏にproperty-based testingについてインタビューした。

InfoQ: プロパティの具体的な例を挙げてください。

Lucy Mair氏:それでは、2つのリストを連結する関数**concat(a, b)**の場合を考えてみましょう。例として、concat([0, 1, 2], [3, 4]) = [0, 1, 2, 3, 4] です。 **c = concat(a, b)**について、常に成り立つステートメントにはどんなものがあるでしょうか。

  • cの長さはa.length + b.lengthとなる。
  • aに含まれるすべての項目はcに含まれる。
  • bに含まれる項目はすべてcに含まれる。
  • 空のリストと連結すると、同じリストが返される a = concat(a, []) = concat([], a)

InfoQ: フロントエンド開発では、どのようにProperty-based Testingを行えばよいでしょうか?

Mair氏:JavaScriptでのフロントエンド開発ではProperty-based Testingにおいて、いくつかの固有の課題があります。

1つの問題はJavaScriptの実行時の型付けが比較的緩いため、テストを実行するための正しい形状のオブジェクトを生成することが容易でないことです。TypeScriptでもこれは解決できません。TypeScriptの型はコンパイル時のみであるため、正しい形状のオブジェクトを生成するために使用できないのです。

2つ目の問題はフロントエンドのテストのために、コンポーネントをレンダリングする事に時間がかかることです。Property-based Testingにレンダリングが含まれる場合、異常に遅くなることがあります。

InfoQ: Property-based Testingには、どのような欠点がありますか?

Mair氏:単純な関数に対するテストの場合、従来の単体テストの場合に例えば10ms、Property-based Testingの場合に200msかかるとすると、パフォーマンスへの影響は無視できるでしょう。しかし、もしテストがコンポーネントのレンダリングや API 呼び出し、あるいは計算集約的なタスクの実行などの「処理速度が遅い」ことを実行すれば、 Property-based Testingは、パフォーマンスのオーバーヘッドが大きすぎて使えないかもしれません。

既存のコードベースにProperty-based Testingを導入するのは、難しいかもしれません。プログラムの実行中に発生することのないエッジケースが存在する可能性が高く、そのようなケースはテストされません。例えば、除算をする場合、ゼロで割ることは無効ですが、ゼロ除算は発生しないかもしれないのです。このような仕様は、本来テストに明記されるべきものですが、実際にはほとんど書かれることはありません。

作者について

この記事に星をつける

おすすめ度
スタイル

BT