Jianyuan フォーラム · モデルの表示丨ソフトウェア プロパティに基づく自動テスト テクノロジ

著者 | Xiong Yiheng 博士、華東師範大学ソフトウェア工学部

         Su Ting 教授、華東師範大学ソフトウェア工学部

セクション | 建源フォーラム · モデル観察

コミュニティ| WeChat ID「TICPShanghai」を追加して「Shanghai Kongan 51fusa Security Community」に参加します。

ソフトウェア開発ライフサイクルにおいて、テストは重要な部分です。ソフトウェア製品の品質を保証するために、開発チームは包括的なテストを実施して、ソフトウェア内の潜在的な欠陥や問題を発見して修正する必要があります。従来の手動テストは効果的ですが、時間と労力がかかり、コストがかかります。テストの効率と精度を向上させるために、自動テストは重要な研究分野となっています。

写真

図1 自動テスト技術

図 1 は、いくつかの既存の自動テスト手法を紹介しています [1]。 X 軸は機能コンプライアンス、つまりテスターがテストしたい機能をテストがカバーしているかどうかを表し、Y 軸はカバーされる入力スコープを表し、テスト入力のカバレッジの程度を表します。図の右上隅、つまり、高い機能準拠と完全な入力範囲の両方を満たすテスト テクノロジが欠けていることがわかります。この技術が次に紹介する特性ベースのテスト技術です。

01

ソフトウェアの性質を踏まえた自動テスト技術とは

プロパティベースのテストは、一般的な自動テスト テクノロジです。その原理は、テスターがテスト対象のソフトウェアに適用できる実際の論理ステートメント (つまり、プロパティ) を作成し、自動テスト ツールを使用して大量のテスト入力を生成し、ソフトウェアを完全にテストすることです。テスト対象をテストし、テスターが書き込んだプロパティが満たされているかどうかを検証します [2]。プロパティに違反している場合は、ソフトウェアにバグがある可能性があることを示します。たとえば、下図はテスト対象のプログラム `my_sort()` で、その機能は入力シーケンスをソートし、ソートされたシーケンスを返すことです。

写真

図2 テスト対象のプログラム

`my_sort()` をテストするには、通常、テスターは単体テスト ケースを作成します。従来の単体テストを作成するには、テスト入力と予想される出力を手動で指定する必要があります。次の図に示すように、テスト対象プログラムをテストするためのテスト ケースは 6 つあります。ただし、この方法の欠点は、テスト入力ごとに対応するテスト出力を手動で指定する必要があるため、非常に労力がかかることです。さらに、テストでは入力が限られており、テスターの知識に依存しているため、テスト対象のプログラムを適切にテストすることが困難になります。

写真

図 3 単体テスト ケース

ただし、プロパティベースのテストを使用する場合は、すべてのテスト入力をカバーするテスト メソッドを作成するだけで済みます。最初に、テスト対象プログラムの理解に基づいて、テスト対象プログラムが持つべき性質(プロパティ)を与えました。たとえば、my_sort() が満たすべきプロパティの 1 つは、返されるリストの各要素がその後ろの要素より大きくてはいけないということです。このプロパティに基づいて、テスト ケースを作成できます。注: 作成例として、Python 言語のプロパティベースのテスト フレームワークである仮説を使用します。

写真

図 4 プロパティベースのテストのテスト ケース

上の図に示すように、コード `@given(st.lists(st.integers())` の最初の行はデコレータであり、テストが開始されると、Hypothesis が ` として大量のランダムなリストを生成することを示しています。 test_prop_ordered()` 関数の入力。生成された各リストはパラメーター xs として `test_prop_ordered()` 関数に渡され、関数本体が実行され、その後、assert ステートメントが true であることが検証されます。特定のテスト入力および出力データを手動で指定することなく、テスト対象のプログラムが設定したプロパティを満たしているかどうかを検証するのに十分なリストを自動的に生成できるため、テストの効率が大幅に向上します。

02

ソフトウェアの性質に基づいて自動テストを実施する方法

前のセクションではプロパティベースのテストの概念を紹介し、このセクションではソフトウェアの性質に基づいて自動テストを実行する方法を紹介します。共通のテンプレートを使用して、プロパティベースのテストを実行する方法を説明します。

写真

図 5 プロパティベースのテスト テンプレート 

ステップ 1: テストするプログラムの性質を決定します。図 5 の 3 行目に示されているように、テスターはテスト対象のプログラムを理解することで、テストするプログラムの性質を決定します。たとえば、図 4 のテスト ケースは、次のプログラム プロパティを検証するように設計されています。並べ替えられたリスト内の各要素は、その後の要素より大きくてはなりません。テスト中にこのプロパティに違反した場合、テスト対象のプログラムにバグが発生した可能性があることを示します。

ステップ 2: テスト入力のタイプと範囲を決定します。最初のステップが完了したら、図 5 の 1 行目と 2 行目に示すように、テスターはテスト対象プログラムに渡されるテスト入力の種類と範囲を決定する必要があります。たとえば、図 4 では、テスト対象プログラムの機能はリスト内の要素をサイズで並べ替えることであるため、テスト入力はリストである必要があります。同時に、並べ替えには要素の大小比較が含まれるため、リスト内の要素は数値である必要があります。ここでは、要素タイプとして整数を選択しました。

ステップ 3: テスト ケースを作成して実行します。 現在、開発者は、さまざまなソフトウェアまたはプログラミング言語(Java: QuickTheories、Python: Hypothesis、C++: RapidCheck、Scala: ScalaCheck、JavaScipt: fast)向けにさまざまなプロパティベースのテスト フレームワークを開発しています。 -check、Ruby: Rantly、Swift: Swiftcheck など) [3-9]。適切なテスト フレームワークが選択されたら、そのテスト フレームワークを使用して、対応するテスト ケースを作成し、実行できます。

03

方法適切なソフトウェア プロパティを選択する方法

最初の 2 つのセクションでは、プロパティ ベースのテストの概念とプロパティ ベースのテストの実行方法を紹介しましたが、プロパティ ベースのテストが非常に効率的なテスト テクノロジであることがわかります。ただし、テスターが実際にテスト ケースを作成し始めると、多くの場合、「テストにはどのプロパティを選択する必要があるか?」という質問に遭遇します。したがって、このセクションでは、適切なソフトウェア プロパティを選択する方法についてテスターに​​インスピレーションを与えることを期待して、より一般的なプロパティ [10] を紹介します。

プロパティ 1: 対称 (対称)。以下に示すように。ある値を別の値に変換し、再度元の値に変換できる場合は、元の値との一貫性が保たれるはずです。たとえば、シリアライゼーションがその典型的な例です。テキストをオブジェクトに変換してから、そのオブジェクトを元に戻すと、テキストは変更されないままになります。

写真

図 6 対称性

プロパティ 2: 可換性 (可換性)。このプロパティは、操作が実行される順序を変更することを指しますが、最終結果は変わりません。たとえば、下図のようにリストの先頭に要素を追加し、最後に要素を追加する場合、この 2 つの操作の順序を入れ替えると、最終的なリストは同じになります。

写真

図 7 可換性 

プロパティ 3: 不変条件 (不変条件)。このプロパティは、特定の操作が実行された後、テスト オブジェクトの特定のプロパティが変更されないことを意味します。たとえば、次の図に示すように、配列を並べ替えた後も、配列の長さは同じままでなければなりません。

写真

図 8 不変性 

プロパティ 4: べき等)。この特性は一般に、操作を複数回実行した場合の効果は、操作を 1 回実行した場合と同じである必要があることを意味します。たとえば、次の図に示すように、リストの場合、1 回ソートしても複数回ソートしても、最終結果は同じになるはずです。

写真

図 9 冪等性

プロパティ 5: 誘導 (誘導)。この性質は通常、大きなオブジェクトを小さなオブジェクトに分割でき、特定のプロパティがこれらの小さなオブジェクトに当てはまる場合、これらのプロパティが大きなオブジェクトにも当てはまることが証明できることを意味します。たとえば、以下のようになります。黒のセットに要素が含まれている場合は、赤、青、緑、黒のセットにも要素が含まれている必要があります。

写真

図 10 導出

04

要約する

プロパティベースのテストは、近年非常に人気のあるテスト技術となっており、開発者はさまざまなプロパティベースのテスト フレームワークを開発しています。この技術には、理論上、考えられるすべてのテスト入力をカバーできること、ユーザーが関心のある機能をより完全にテストできること、テストコストを削減できることなど、多くの利点があります。ただし、その特性上、いくつかの課題もあります。たとえば、テストしたいプロパティのみを考慮するため、特定のプロパティが完全にテストされ、他のプロパティはまったくテストされません。さらに、テスターは、維持する必要があるプロパティを抽象化するためにテスト対象のソフトウェアを十分に理解する必要があるため、テスターに​​は高い要求が課せられます。さらに、効率的なプロパティベースのテスト フレームワークを開発することも、開発者にとって大きな課題です。開発者は、テスターがプロパティを簡単に作成できるようにする方法、より優れたデータ ジェネレーターを開発する方法などを考える必要があります。最も重要なことは、プロパティベースの自動テスト手法は、他のテスト手法 (単体テストなど) を置き換えることを目的としたものではなく、他のテスト手法と共存できることです。テスターは、ソフトウェア テストをより適切に提供できるように、テストのニーズに基づいて適切なテスト テクノロジを選択する必要があります。

参考文献:

[1]https://medium.com/criteo-engineering/introduction-to-property-based-testing-f5236229d237

[2] Claessen, K.、Hughes, J.: QuickCheck: Haskell プログラムのランダム テスト用の軽量ツール。参照: 第 5 回 ACM SIGPLAN 関数型プログラミング国際会議 (ICFP'00) の議事録、ACM、268 ~ 279 ページ (2000 年)。 https://doi.org/10.1145/ 351240.351266

[3] クイック理論。 https://github.com/quicktheories/QuickTheories

[4] 仮説。 https://仮説.works/

[5] ラピッドチェック。 https://github.com/emil-e/rapidcheck

[6] スカラチェック。 https://github.com/typelevel/scalacheck

[7] 素早いチェック。 https://github.com/dubzzz/fast-check

[8] 暴言を吐く。 https://github.com/rantly-rb/rantly

[9] スイフトチェック。 https://github.com/typelift/SwiftCheck

[10] https://fsharpforfunandprofit.com/posts/property-based-testing-2/

おすすめ

転載: blog.csdn.net/TICPSH/article/details/133705513