[フレームワーク]テストフレームワーク

アプリケーション開発において、テストの生産性と品質は重要です。Nimbusでは、テストの自動化を支援するテストフレームワークを提供します。

対象テスト工程

通常、テスト工程と言えば、単体テスト、連結テスト、総合テスト、ユーザ受け入れテストなど、モジュールの連結度、環境、観点などから、複数の工程に分けて、積み上げテストを行います。
単体テストでは、いわゆる最小単位のモジュールレベルで、周りのモジュールをモック化して入力と出力のテストを行います。
単体テストの利点は、最小単位で行うため、1つ1つのテスト対象が小さく、周りのモジュールはモックであるため、全ての外部的な条件が整えやすく、ホワイトボックス(全網羅)テストが行えることです。また、周りのモジュールをモック化するため、周りのモジュールの開発状況の影響を受けずに、テストすることができます。
欠点は、見ている範囲が狭いため、システム全体としてありえる状態の考慮ができないため、そのモジュールとしてあり得る条件を全て網羅することになり、無駄に多くのテストを実施することになってしまいます。また、そのモジュール単体での要件仕様をテストするため、要件仕様自体の問題や間違いに気づく事が困難です。

連結テストでは、何らかの単位でモジュールを連結させて(連結させない部分は、結局モック化する)、入力と出力のテストを行います。
連結テストの利点は、モジュールが連結され、あり得る入出力の条件がより明確になるため、無駄なテストが減る事と、単体モジュール毎の要件仕様に間違いがなかったのかの確認が行えることです。
欠点は、連結対象のモジュールの開発状況を足並み揃える必要があることと、あり得る入出力の条件が絞られることで、各モジュールのホワイトボックステストを行うことが困難になり、ブラックボックステストになるため、テストの網羅性を外部観点のみで保証する必要があり、テストケース立ての難易度があがることです。また、テストをした結果、出力がNGな場合に、どこのモジュールに問題があるのかを切り分ける作業が必要になることです。

これ以降のテストは、基本的にモックが排除され、運用を意識したテストや、基盤を意識したテストが追加されたり、環境やテスト実施者が変わるなどしますが、基本的に実運用にそった形でシステムを稼働させ、手作業での確認作業を行うことになります。

従って、テストの自動化を行うのであれば、単体テスト及び連結テストまでが対象となります。
しかし、昨今のEOD(Ease of Developement)や、アジャイル開発などの流れから、システム開発は簡略化され、スケジュールも圧縮されてきています。それにより、モジュールの細分化が極力抑えられた設計が行われ、分割されたとしても、一連のモジュールは、同一の開発者が担当する事が多く、単体テストのメリットが減り、連結テストのデメリットも減ってきました。また、単体テストと連結テストのある意味、冗長なコストを掛けたテスト工程の積み上げを行う、スケジュールやコストが取れないという現実的な問題もあります。
そこで、Nimbusテストフレームワークでは、単体テストではなく、サーバ単位レベルでのサーバ内のモジュール連結以降の連結テストを対象とします。

テストケース構造

テストにおいて、あるテストケースを実施するために、他のテストケースの実施が前提になる場合があります。そのように連続した複数のテストケースをひとまとまりにしてテストする場合、そのかたまりをシナリオと呼びます。
それをふまえて、Nimbusテストフレームワークでは、テストケースの概念を3階層で定義します。最下層がテストケース、テストケースを1連の流れとしてまとめるシナリオ、シナリオを意味的にまとめるシナリオグループです。

シナリオグループ1
シナリオ1
テストケース1
テストケース2
シナリオ2
テストケース1
テストケース2
シナリオグループ2
シナリオ1
テストケース1
テストケース2
シナリオ2
テストケース1
テストケース2


テスト実装方法

ここで、一般的なテストフレームワークがどうなっているかを考えてみましょう。
一般的なテストフレームワークでは、テストの入力データをプログラム的に生成し、テスト対象のモジュールを呼び出し、その出力データをプログラムで検証します。また、テスト対象自体が呼び出すモジュールをプログラム的なモックで実装することで、モックへの入力データを検証し、出力データを返します。
これは、テスト対象が、基本的に単体テストであり、モジュールの開発者=テスト開発者(少なくともプログラマ)であることが前提になっています。また、さらに言えば、テストコード自体がプログラムであることから、テストレビューア=プログラマ(=もしかしたらモジュールの開発者)であることが、暗に要求されています。また、テストレビューアがプログラマであれ、プログラムで書かれた検証ロジックの妥当性を評価するのは、骨の折れる作業です。
しかし、エンタープライズな開発においては、モジュールの開発者=テスト開発者までは許容できても、テストレビューア=プログラマは、場合によっては困難かもしれませんし、テストレビューア=モジュールの開発者はあり得ません。つまり、求められているのは、モジュールの開発者=テスト開発者(でなくてもよい)かつ、テストレビューア=設計者(少なくともプログラマではない)です。

テストフレームワークで、このような関係性にするためには、テスト対象に対する入力(モックの出力も含む)をプログラムではなく、データとして表現できることが必要になります。また、テスト対象の出力(モックに対する入力も含む)をデータとして検証できることも必要となります。
それにより、テストレビューア=設計者(プログラマではない)を可能にします。
そこで、Nimbusテストフレームワークでは、テストの事前準備、テストの実行、テストの結果検証などを部品化し、部品に対する入力をデータファイルで渡し、出力もデータファイルで取得し、出力されたデータファイルを人間が目で検証する事で正当性を保証し、2度目以降のテストでは、検証したファイルをエビデンスとすることで、Diffを取り自動検証する方式を採用しました。
従って、Nimbusのテストフレームワークを使ったテストケース開発では、以下のような作業の流れになります。

  1. テスト対象サーバのテスト要件を整理する。
    テスト対象をどのように呼び出し、どのような応答が返ってくるか。
    テスト対象がどのようなスタブを必要とするか。
    テスト環境のネットワーク構成はどうなっているか。など
  2. 整理した要件に従って、テスト環境の環境構築、及びテストフレームワークのサービス構成を決めて構築する。
  3. 実施したいテスト内容から、シナリオグループ/シナリオ/テストケースをどのように使うかを決める。
  4. テストの実施内容をパターン化して、テストリソースのテンプレートを作成する。
    例えば、データベースを初期化し、テスト対象サーバにHTTPリクエストを要求し、HTTPレスポンスを出力し検証、データベースを検索して出力し検証する。など
  5. シナリオグループ/シナリオ/テストケースのテストリソース(テンプレート化されている場合は、テンプレートリンクファイルとテンプレート用データファイル)を作成する。
    また、入力データファイル、スタブ用出力ファイルなどの、データファイルを作成する。
  6. テストを実行して、テストの出力となる出力データファイル、スタブ入力ファイル等を、目視で検証して、正しければエビデンスファイルとして、テストリソースに加える。
  7. テストの再実行時は、今回のテスト出力とエビデンスファイルの差分検証が自動的に行われる。


テスト機能

Nimbusのテストフレームワークを機能分解すると、以下のようになります。


関連するパッケージは、以下です。

テスト実行 TestRunner

テストを実行するユーザインタフェースを提供する機能が、TestRunnerです。
TestRunnerは、ユーザのテスト実行要求に対して、TestControllerとやり取りを行い、テストを実行します。

TestRunnerクラスの一覧は以下のとおりです。

クラス概要
jp.ossc.nimbus.service.test.TestRunnerテスト実行定義ファイルを読み込み、コマンドラインでテストを自動実行するクラスです。
jp.ossc.nimbus.service.test.swing.TestSwingRunnerSwingのGUI画面をユーザが操作することでテストを実行するクラスです。


テストコントローラ TestController

テスト全体を制御する機能を抽象化したのがTestControllerインタフェースです。
テストコントローラは、テストの開始を要求されると、テストリソース管理から、シナリオグループ/シナリオ/テストケースのテストリソースを取得します。
また、テストリソースに、スタブ向けのリソースが含まれている場合は、スタブリソース管理を経由して、テストスタブにリソースを配布し、テストスタブにテストの開始を通知します。
テストリソースに定義されているテストアクションテスト検証アクションを実行することで、テストの事前準備や、テストの実施、テスト結果の検証を行います。

TestControllerインタフェースの実装サービスの一覧は、以下のとおりです。

実装サービス実装概要
jp.ossc.nimbus.service.test.TestControllerServiceデフォルト実装サービスです。
jp.ossc.nimbus.service.test.HttpTestControllerClientServiceテスト用のサーバに配置したHttpTestControllerServerServiceとHTTP通信を行い、サーバ上のTestControllerServiceを制御する実装サービスです。


テストリソース管理 TestResourceManager

テストを実行するために必要なシナリオグループ/シナリオ/テストケースのリソース定義を提供する機能を抽象化したのが、TestResourceManagerインタフェースです。

TestResourceManagerインタフェースの実装サービスの一覧は、以下のとおりです。

実装サービス実装概要
jp.ossc.nimbus.service.test.resource.LocalTestResourceManagerServiceローカルのディスク上からリソース定義を提供する実装サービスです。
jp.ossc.nimbus.service.test.resource.CVSTestResourceManagerServiceCVSサーバ上からリソース定義を提供する実装サービスです。
jp.ossc.nimbus.service.test.resource.GitTestResourceManagerServiceGitサーバ上からリソース定義を提供する実装サービスです。
jp.ossc.nimbus.service.test.resource.SVNTestResourceManagerServiceSVNサーバ上からリソース定義を提供する実装サービスです。


テストアクション TestAction

テストに必要な処理を行う機能を抽象化したのがTestActionインタフェースです。

TestActionインタフェースの実装サービスの一覧は、以下のとおりです。

実装サービス実装概要
jp.ossc.nimbus.service.test.action.CommandExecuteActionServiceローカルでコマンドを実行するテストアクションです。
jp.ossc.nimbus.service.test.action.SSHCommandExecuteActionServiceSSHでリモートコマンドを実行するテストアクションです。
jp.ossc.nimbus.service.test.action.FileOperateActionServiceローカルのファイルを操作するテストアクションです。
jp.ossc.nimbus.service.test.action.FileToObjectConvertActionServiceファイルを読み込んでオブジェクトに変換するテストアクションです。
jp.ossc.nimbus.service.test.action.ObjectToFileConvertActionServiceオブジェクトをファイルに書き出すテストアクションです。
jp.ossc.nimbus.service.test.action.DatabaseSearchActionServiceデータベースを検索するテストアクションです。
jp.ossc.nimbus.service.test.action.DatabaseUpdateActionServiceデータベースを更新するテストアクションです。
jp.ossc.nimbus.service.test.action.FTPActionServiceFTP通信を行うテストアクションです。
jp.ossc.nimbus.service.test.action.SCPActionServiceSCP通信を行うテストアクションです。
jp.ossc.nimbus.service.test.action.HttpRequestActionServiceHTTP通信を行うテストアクションです。
jp.ossc.nimbus.service.test.action.ServiceCallActionServiceローカルのサービスを呼び出すテストアクションです。
jp.ossc.nimbus.service.test.action.MBeanCallActionServiceJMXでMBeanを呼び出すテストアクションです。
jp.ossc.nimbus.service.test.action.InterpreterActionServiceスクリプトを実行するテストアクションです。
jp.ossc.nimbus.service.test.action.PropertyGetActionServiceオブジェクトのプロパティを取得するテストアクションです。
jp.ossc.nimbus.service.test.action.PropertySetActionServiceオブジェクトのプロパティを設定するテストアクションです。
jp.ossc.nimbus.service.test.action.ScheduleMakeActionServiceScheduleManagerを使ってスケジュールを作成するテストアクションです。
jp.ossc.nimbus.service.test.action.ServerConnectionSendActionServiceNimbusメッセージ配信でメッセージを送信するテストアクションです。
jp.ossc.nimbus.service.test.action.MessageReceiverListenActionServiceNimbusメッセージ配信でメッセージを受信するように登録するテストアクションです。
jp.ossc.nimbus.service.test.action.MessageReceiverGetActionServiceMessageReceiverListenActionServiceで登録したメッセージ受信を待ち受けるテストアクションです。
jp.ossc.nimbus.service.test.action.JMSMessageSendActionServiceJMSでメッセージを送信するテストアクションです。
jp.ossc.nimbus.service.test.action.JMSMessageReceiverListenActionServiceJMSでメッセージを受信するように登録するテストアクションです。
jp.ossc.nimbus.service.test.action.JMSMessageReceiverGetActionServiceJMSMessageReceiverListenActionServiceで登録したメッセージ受信を待ち受けるテストアクションです。
jp.ossc.nimbus.service.test.action.CodeMasterNotifyActionServiceコードマスタの更新通知を投げるテストアクションです。
jp.ossc.nimbus.service.test.action.NetProxyControlActionServiceNetProxyを操作するテストアクションです。
jp.ossc.nimbus.service.test.action.TcpNetProxyControlActionServiceTcpNetProxyを操作するテストアクションです。


テスト検証アクション EvaluateTestAction

テストに必要な検証処理を行う機能を抽象化したのがEvaluateTestActionインタフェースです。

EvaluateTestActionインタフェースの実装サービスの一覧は、以下のとおりです。

実装サービス実装概要
jp.ossc.nimbus.service.test.evaluate.TextEvaluateActionServiceテキストファイルを検証するテスト検証アクションです。
jp.ossc.nimbus.service.test.evaluate.TextCompareEvaluateActionService2つのテキストファイルを比較検証するテスト検証アクションです。
jp.ossc.nimbus.service.test.evaluate.CSVCompareEvaluateActionService2つのCSVファイルを比較検証するテスト検証アクションです。
jp.ossc.nimbus.service.test.evaluate.BinaryCompareEvaluateActionService2つのバイナリファイルを比較検証するテスト検証アクションです。
jp.ossc.nimbus.service.test.evaluate.ServiceLoadActionServiceNimbusのサービス定義をロードして、正しくロードできたかを検証するテスト検証アクションです。
jp.ossc.nimbus.service.test.evaluate.ScheduleWaitActionServiceScheduleManagerを使って、スケジュールが想定通り終了したかを検証するテスト検証アクションです。


連鎖テストアクション ChainTestAction

テストアクションを連鎖させることで、複数のテストアクションを論理的にひとかたまりに扱う機能を抽象化したのがChainTestActionインタフェースです。

ChainTestActionインタフェースの実装サービスの一覧は、以下のとおりです。

実装サービス実装概要
jp.ossc.nimbus.service.test.ChainTestActionServiceデフォルト実装のテスト検証アクションです。


連鎖テスト検証アクション ChainEvaluateTestAction

テストアクションを連鎖させ、最後にテスト検証アクションで検証することで、連鎖テストアクションの機能性とテスト検証アクションの機能性を兼ね備えるような機能を抽象化したのがChainEvaluateTestActionインタフェースです。

ChainEvaluateTestActionインタフェースの実装サービスの一覧は、以下のとおりです。

実装サービス実装概要
jp.ossc.nimbus.service.test.ChainEvaluateTestActionServiceデフォルト実装の連鎖テスト検証アクションです。


リトライ連鎖テスト検証アクション RetryEvaluateTestAction

テストアクションテスト検証アクションを連鎖させ、最後にテスト検証アクションで検証し、途中の検証または最後の検証がNGの場合はリトライできる機能を抽象化したのがRetryEvaluateTestActionインタフェースです。

RetryEvaluateTestActionインタフェースの実装サービスの一覧は、以下のとおりです。

実装サービス実装概要
jp.ossc.nimbus.service.test.RetryEvaluateTestActionServiceデフォルト実装のリトライ連鎖テスト検証アクションです。


テストスタブ TestStub

テストコントローラからスタブとして制御可能になるような機能を抽象化したのがTestStubインタフェースです。
テストスタブは、テストコントローラから、テストの開始イベントを受け取ると、スタブリソース管理を経由して、スタブとして応答すべき出力データを受け取ります。その後、テスト対象からの要求を受け取ると、要求内容を入力データとして記録し、出力データを応答します。次に、テストの終了イベントを受け取ると、テスト対象からの要求内容たる入力データを、スタブリソース管理を経由して、テストコントローラに渡します。

TestStubインタフェースの実装サービスの一覧は、以下のとおりです。

実装サービス実装概要
jp.ossc.nimbus.service.test.stub.http.HttpTestStubServiceHTTPサーバのスタブ実装です。
jp.ossc.nimbus.service.test.stub.tcp.TCPTextTestStubServiceTCPプロトコルでテキストベースのデータプロトコルを持つサーバ(SMTPなど)のスタブ実装です。


スタブリソース管理 StubResourceManager

テストコントローラテストスタブ間のデータのやり取りを中継する機能を抽象化したのがStubResourceManagerインタフェースです。

StubResourceManagerインタフェースの実装サービスの一覧は、以下のとおりです。

実装サービス実装概要
jp.ossc.nimbus.service.test.resource.LocalStubResourceManagerServiceローカルのディスクを経由してリソースを中継する実装です。


テンプレートエンジン TemplateEngine

テンプレート言語で書かれたテンプレートファイルと、データファイルをテンプレートエンジンでマージしてファイルを出力する機能を抽象化したのがTemplateEngineインタフェースです。
テンプレート言語と、データファイルのフォーマットは、実装クラスに依存します。

TemplateEngineインタフェースの実装サービスの一覧は、以下のとおりです。

実装サービス実装概要
jp.ossc.nimbus.service.test.resource.VelocityTemplateEngineServiceApache Velocityを使った実装です。


テストレポーター TestReporter

テストに関するレポートを出力する機能を抽象化したのがTestReporterインタフェースです。

TestReporterインタフェースの実装サービスの一覧は、以下のとおりです。

実装サービス実装概要
jp.ossc.nimbus.service.test.report.ConsoleTestEstimateReporterServiceテストの見積もりを標準出力に出力するテストレポーター実装です。
jp.ossc.nimbus.service.test.report.CSVTestEstimateReporterServiceテストの見積もりをCSVファイルに出力するテストレポーター実装です。
jp.ossc.nimbus.service.test.report.HtmlTestCaseProgressReporterServiceテストの進捗をHTMLファイルに出力するテストレポーター実装です。
jp.ossc.nimbus.service.test.report.MSProjectTestReporterServiceテストの進捗をMicrosoft Projectで読み込めるXMLファイルに出力するテストレポーター実装です。
jp.ossc.nimbus.service.test.report.ConsoleTestReporterServiceテスト実行結果を標準出力に出力するテストレポーター実装です。
jp.ossc.nimbus.service.test.report.CSVTestReporterServiceテスト実行結果をCSVファイルに出力するテストレポーター実装です。
jp.ossc.nimbus.service.test.report.HtmlTestReporterServiceテスト実行結果をHTMLファイルに出力するテストレポーター実装です。


ネットワークプロキシ NetProxy

ネットワーク通信をプロキシして、通信エラーを疑似する機能を抽象化したのがNetProxyインタフェースです。

NetProxyインタフェースの実装サービスの一覧は、以下のとおりです。

実装サービス実装概要
jp.ossc.nimbus.service.test.proxy.netcrusher.TcpNetProxyServiceTCP通信をプロキシする実装です。

サンプルは、以下。