|
翼―ユニットテストをインテリジェントかつ完全自動化に前書き ユニットテストは、早期介入の概念やUIの影響を受けずに高速で検証可能なユニットテストの特徴から、ソフトウェア品質を確保する非常に効果的な手段です。したがって、業界が推奨するテスト駆動型開発、ここで言及されるテストドライバーは、むしろユニットテストドライバーを指します。 しかし、一般的な開発チームは依然としてユニットテストを体系的に実行することは稀であり、アプリケーションソフトウェアのテストは主にプロのテストチームがブラックボックステストを行うために行っています。 ユニットテストの最大の難しさは、入力と出力が決定できないことではなく、モジュール開発段階で既に決定されていることです。しかし、ユニットテストケースの作成には多くの開発者の労働時間がかかり、関連統計によれば、ユニットテストケースの時間は関数自体の開発時間をはるかに上回ることもあります。 以下は、開発がユニットテストを書かない最も一般的な理由のいくつかです: ●要件は常に無限で、次の段階で実現すべき機能要件も残っており、ユニットを埋める時間もありません ●単元テストが多すぎて補足できず、始める方法もないので主観的に抵抗しています。 ● ユニットテストは書くのが難しい。 一方では、関数関数の実装が十分に合理的でないこと、他方では有用なユニットテストフレームワークやモックフレームワークが存在しない(あるいは不明)であることが理由かもしれません。 ● ユニットテストはワークロードに含まれていません。 第二に、機能要件が依然として不安定であり、ユニットテストを書くコストパフォーマンスも高くありません。 つまり、もし明日要件が変われば、機能コードだけでなくユニットテストも廃止されるということです。 ユニットテストを書かなければ、この部分の努力は無駄にはなりません。 実際、上記の点の根本原因は、ユニットテストの書き込みがあまりにも時間がかかりすぎて、最終的にテスト駆動エンジンのパワーが失われ、実際のシナリオではテスト駆動開発の美しいビジョンが停滞してしまうことです。なぜなら、このドライブ用のエンジンを作るのがあまりにも困難かつ高価だからです。 市場にある様々な「x」ユニットやユニットテストフレームワークは、テスト駆動のアウトウターフレームを生成する問題を解決するだけで、深いプログラム理解に基づくユースケースロジックやデータ生成機能は一切ありません。 したがって、開発者はさまざまな開発関連のシナリオで抵抗力を持つようになります。 Wings(現在はC向け)のリリースは、プログラマーにとって最大の問題の一つを解決し、ユニットテストの現状を根本的に変える可能性を秘めています。これにより、膨大な人材に基づくシステムレベルのブラックボックステストや自動化テストのプレッシャーを効果的に軽減するでしょう。 制約テストケースはプログラムによって自動的に生成され、最も重要な基盤技術は複雑なパラメータ解析技術です。 つまり、任意の複雑な型に対してコンパイラレベルでネストレベル再帰解析を任意に定義できます。 この重要な技術のブレークスルーがなければ、自動テストケース生成システムは商業的に機能しないか、非常に低効率ながら準拠したテストデータを生成するように進化していくでしょう。 例えば、有名なファジングツールであるAmerican Fuzzy Lopは、ユーザーのプログラムに必要な構造の種類を特定できず、最外層に基づいて探索アルゴリズムを進化させる必要があります。 このプログラムの特徴は、インターフェースレベルの入力や内部モジュールのデータ要件が遠く離れていること、そして外部データは通常、複雑な変換層ごとに変換され、内部モジュールが要求するデータ構造タイプに変換されるため、外部層からの探索に必要な計算量と時間は想像を絶することです。 アメリカのファジーロップに基づき、正当なSQL文を生成するためには、プログラムの内部モジュールを数分や数時間ではなく数日で探索する必要があります。 もう一つの制約は、各プログラムが引き継ぐ入力が多数のルールを持つ慎重に構造化・コンパイルされたデータであり、ランダム+探索的手法でこれらのデータを生成するのは非常に非現実的で非常に時間がかかることです。 したがって、ブラックボックスから最外層の入力だけでなく自動生成ユースケースを生成するのは現実的ではありません。 ユースケース駆動がソフトウェアの内部構造の分析から生成される場合、ソフトウェアのコンパイル構造を深く理解する必要があります。 実行可能なテストケース生成システムは、プログラムの中間(キーエントリーポイント)を最も適切なテストエントリーポイントとして基づくべきです。 これらのモジュールの入力は、ファジィ入力を高度に構造化されたパラメータに変換しました。 これらの複雑な構造を特定できれば、複雑なデータ型を段階的に単純なデータ型に分解でき、パラメータ構築も同時に完了できるため、駆動ユースケースの生成も自動的に完了できます。 モジュールベーステストは、従来のユニットテストに分類され、R&Dフェーズで欠陥を発見し、封じ込める最良の方法です。 しかし、ユニットテストの制約により、多数のドライバーの開発が必要であり、業界での普及や応用は大きく制限されています。 もちろん、システム統合後に仮想スタブプログラムを作成する必要を回避するためにユニットテストを実行することも可能です。 Nebulas TestingのWings製品は、数日前に世界初公開されたインテリジェントで完全自動化のユニットテストケース生成システムであり、以下の課題を研究・解決し、現在皆様と共有しています。 (1) プログラムパラメータの詳細な分析 Wingsはコンパイラの基盤技術を用いて、関数に応じて入力ソースファイルに基づいてモジュールオブジェクトを形成します。 このオブジェクトには関数の入力パラメータ、返り値型、その他の情報が含まれており、これらはドライバー関数モジュールやテストケースモジュールで利用可能です。 各ファイルは各関数のパラメータを詳細に分析するユニットであり、入れ子型や複素型などの正確な解析や分解を実現し、複雑なタイプの基本データ型として層ごとに説明し、パラメータ構造の記述ファイル(PSD)を生成することができます。 (2) モジュールの自動生成機能駆動 PSDファイルのフォーマット情報によると、テスト対象のソースプログラムのすべてのドライバ関数は自動的に生成され、ユニットテストプロセスは開発者が手動でテスト関数を書く必要がなくなり、生成されたドライバー関数とテスト対象のソースファイルを一緒にコンパイルするだけで済み、テスト結果を実行し、テスト結果を閲覧できます。 テストドライバーはPSDの記述に基づいてプログラムを自動的に生成し、テスト対象となるすべてのパラメータと必要なグローバル変数を完全に自動で構築し、複素変数の階層に沿った構造化されたテストドライバーを生成できるため、ユニットテストケースの作成に多くの時間を節約できます。 (3) テストデータの自動生成および管理 これはテスト関数によって抽出された情報に対応したテストデータを自動生成し、そのデータは特定の階層的論理関係を持つJSONファイルに保存されます。 分解と展開後のデータ型は互いに対応します。 ユーザーはビジネス要件に応じてこれらのデータを任意に周縁化し、JSONファイルを使って構造化かつ階層的に表示することも非常に明確です。 テストデータには、グローバル変数の値と、テスト対象関数が呼び出されたときのパラメータ値が含まれます。 Wingsはドライバー関数を自動的に生成するためのユニットテスト手法を提供しており、主に以下のステップが含まれます。 図1:ユニットテスト駆動ビルドフロー 1 テスト対象プログラムの情報抽出テスト対象プログラムの構造情報は主にグローバル変数と関数情報を含み、関数情報にはパラメータ数、パラメータ型、関数の返り値型が含まれます。 最も重要なのは、複雑なタイプのシンボル情報や型情報を抽出し、それらを層ごとに基本データ型に解析してグローバル変数や関数パラメータの構築を完了することです。 変数の型は一般的に基本型、構成型、ポインタ型、ヌル型に分けられます。 Wingsは基礎となるコンパイル技術を用いて、異なる変数タイプを異なる方法で処理します。 (1) 基本型、例えば符号なしint u_int=20 では、Wingsは変数名をu_intに、データ型を符号なしintに解析します。 (2) 構成タイプ 構成タイプは大まかに配列、構造体、共通体、列挙型に分けられます。 ● 配列タイプ(例:intarray[2][3])、配列名は2D配列の型intと長さ、挙動2、列3です。 ●構造体タイプ:配列や構造体連結リストなどは、異なるマーカーが分割されています。 (3) ポインタ型、例:int **ptr = 0; は、ポインタをint型のレベル2ポインタとして解析します。 (4) NULL型(NULLと解決されます)。 (5) ファイル、size_tなどのシステムタイプはシステムタイプとしてマークされ、テンプレートに追加されユーザーによって割り当てられます。 (6) 関数ポインタ型、返還値型、パラメータ型、関数のパラメータ数を解析します テスト対象のソースプログラムの各コンパイルユニットに対して、解析された関数情報は対応するPSD構造に保存され、以下のソースコード例を説明します。
上記のプログラムでは、StructTypeTest3を無効化します(myy_struct mm_struct[2])保存されたPSD構造は以下の通りです:
PSDファイル内の各ノードの意味は以下の通りです: ●StructTypeTest3は関数名、parmType0はパラメータ型、parmNumはパラメータ数を表します ●mm_structは関数パラメータのシンボルを表し、baseType1は型の分類(基本データ型、構成型、ポインタ型、null型)を表し、型はint、char、short、long、double、float、boolなどの特定の型を表し、これらの符号なし型やその他の基本型を表します。また、ZOA_FUN型は関数型を表します。 StructureOrClassTypeは構造体型などを表し、nameは構造体、ユニオン型、enum型の名前を表します ●i_int は基底型を表し、これは最小の割り当て単位です ●array_oneは配列タイプを表し、RowSizeは配列の長さを表し、配列は一次元配列、二次元配列などに分割できます ●ポイントはポインタ型を表し、ポインタは1レベルポインタ、2レベルポインタなどに分けられ、一般的なポインタは配列として関数パラメータとして使われます。つまり、基本的なポインタタイプでは動的割り当て配列メソッドで値を割り当て、ユーザーは必要に応じて対応する値を変更できます。 ● w はビットフィールドの種類を表し、bitfileld は桁数を表します ●functionPtr は関数ポインタタイプを表し、パラメータの種類、パラメータ数、返り値情報をそれぞれ解析します ●Demはコンソーシアムタイプ(consortium type)の略です ● dyはenum型を表し、valueはenum型の値を表します ●ファイルは構造体タイプを表し、SystemVarはこの変数がシステムヘッダーファイルの変数に属します。このタイプの変数に対して、Wingsはテンプレートライブラリにテンプレート変数を追加し、ユーザーは特定のニーズに応じて特別な値を割り当てることができます。 例えば、ファイル形式は次のように扱われます:
ユーザーは自分の割り当て方法も追加できます。 システムタイプに関しては、Wingsは通常のユーザー定義型と区別でき、システムの組み込み型に解析すると、再帰解析を下位に停止できます。 ●g_int はグローバル変数を表し、globalTypeはグローバル変数を表します ●nextは連結リスト構造を表し、NodeTypeはこの構造を連結リストとして表します ●returnTypeは関数の返還値型を表します。 2 ドライバーの自動生成上記の論文では、グローバル変数や関数の構造情報を解析・抽出し、以下の情報をPSDで保存してテスト対象のソースプログラムの駆動フレームワーク全体の生成を完了させます。 発電は主に以下の側面に分けられます。 Ø Declaration of global variables Ø 関数パラメータの割り当て操作は、関数パラメータの数に応じて値を割り当てます Ø グローバル変数の割り当ては、解析で使用されるグローバル変数の数に応じて順次行われます 元の関数のØ Call 注意すべき点は以下の通りです。 ●ドライバー生成プロセス中、主機能や静的機能などの特殊機能は外部からアクセスできないため一時的に処理されません。 ● テスト対象の各ソースファイルごとに対応するドライバーファイルが生成されます。 ● ドライブ制御はマクロを通じて機能のテスト回数を自動的に設定するDriver_main.cppに含まれています 上記のソースプログラムによって生成されるドライバー関数は以下の通りです: ● すべての変数は元の変数名の前に名前が付けられ、_ を追加します ●対応するテストデータを取得することで、変数が順に割り当てられます ●システムの組み込みパラメータとユーザーの特殊パラメータについては、割り当てメソッドはテンプレートメソッドを通じて一様に構成されます。 ●テスト対象の関数にパラメータを割り当てて呼び出します。 3 テストデータは自動的に生成されます以下は図3のPSD形式で生成されたデータのセットで、各データセットはJSON形式に保存されているため、データの階層的関係がより分かりやすくなっています。
各コンパイルユニットごとに、すべての関数に対応するテストデータファイルのセットがデフォルトで生成され、その値生成は構成の数によって変更可能です。 4 Mysqlプログラムのテスト結果が表示されますドライバーフレームワークの生成を完了する方法については、オープンソースプログラムMySQLの完全な生成プロセスについて詳しく説明します。 以下はWingsがMySQLをテストする主なインターフェース図です: テスト対象のソースプログラムのプロジェクトディレクトリを設定するには「ファイル」ボタンをクリックしてください。 設定が完了したら、主にパラメータ解析、ドライバー生成、値ファイル生成、テンプレート追加を含む関数操作をクリックします。 分析のために生成されるフォルダーは以下の通りです: その中で、パラメータ解析モジュールはFunXmlとGlobalXmlを生成し、それぞれ抽出したコンパイルユニットの関数情報とグローバル変数情報を格納します。 ドライバー生成モジュールは対応するフォルダWings_Projects生成され、各コンパイルユニットのドライバーファイルが格納されます 価値生成モジュールは各コンパイルユニットの生成テストデータを格納します。 以下の図はMySQLによって読み込まれたドライバーファイル構造の情報を示し、左側のナビゲーションツリーは生成されたドライバーファイルで、各コンパイルユニットの関数、関数のパラメータおよびグローバル変数を含んでいます。 コンパイルユニットのいずれかをクリックすると、対応するドライバーファイルと対応する値ファイルを読み込みます。 上記はMySQLの全体の生成に対応するドライバファイルおよび数値ファイルであり、ドライバファイルは以下のコードで詳細に説明されています。 ● 各コンパイル単位に対して、グローバル変数の参照はexternによって行われます。 ●ドライバー関数は一様に「Driver_XXXメソッド」と呼ばれ、JSONはテストデータを取得する方法として使われ、timesは単一関数のテスト回数を表します。 ●各パラメータ割り当て操作に対して、解析されたPSDストレージ形式を用いて、各レイヤー構造に値を割り当てます。 Wingsの応用は非常にシンプルで、以下はMysqlコードを用いた生成されたテストデータの統計的インデックスで、Visual Studio 2015で通常コンパイル可能です。例えば、生成プロセス全体は手動作業を必要とせず、生成・駆動すべきソースコードの経路を定式化するだけで済みます。 MySQLテストデータ コンピュータ設定手順: | オペレーティング システム | | | Inter(R) Core(TM) i7-7700cpu 3.60GHz | | | | |
以下はソースコード統計ツールを用いて得られた結果で、Wingsによって完全に自動的に生成された400万行以上の有効なユニットテストコードです。 さらに興味深いのは、これらのコードの手作業開発コストが最大で1,079人月、最大で1,079万人にのぼることです。 Wingsはプログラムによる自動生成の探索の第一歩を実現しました。最初のバージョンは現在リリース中で、興味のある開発者はコードクラウドプラットフォーム(https://gitee.com/teststars/wings_release)で直接ダウンロードできます。商用ライセンスは1か月間の無制限機能体験を提供し、Wingsの魔法のような力を素早く体験できます。Wingsの言語版はVisual Studioなど複数のプラットフォームに対応しています。 VXワークス、GCC、QTなどです。 WingsはNebulasのテスト(www.teststar.cc)チームによって設計・開発されており、興味のある開発者はCodecloudのインタラクティブプラットフォームを通じてNebulasのテストチームに連絡し、デザインアイデアや製品の利用フィードバックを共有できます(優れた提案が採用された場合、Nebulasは無料使用期間を少なくとも3か月延長できます)。 Wingsはソフトウェア品質を大幅に向上させる強い基盤を持ち、将来的には自動で書かれたプログラムの可読性(優れたプログラマーの執筆レベルに近いもの)やC++言語のサポートを深く最適化していく予定です。
|