STAF/STAX によるテストの自動化と継続的インテグレーション

STAF/STAX フレームワークを使用して開発時間の短縮とソフトウェアの品質向上を実現する

リグレッション・テストとインクリメンタル・テストは、数百、あるいは数千もの要件で構成されるアプリケーションをテストする際に重要な役割を果たします。インクリメンタル・テストは手動で実行できる場合もありますが、リグレッション・テストには自動化ツールまたは自動化フレームワークが欠かせません。さまざまなオペレーティング・システム、アーキテクチャー、ミドルウェア・ソフトウェア (アプリケーション・サーバーやデータベースなど) に対応するのであれば、なおのこと自動化フレームワークが差し迫って必要になってきます。この記事では、STAF/STAX テスト自動化フレームワークについて概説し、STAF/STAX を使用して複雑なテスト・ベッドでのテストの自動化と継続的インテグレーションに対応するためのフレームワークを構築する方法を説明します。

2013年 2月 26日 ― JUnitRunner.xml および JUnitUtil.xml サンプル・ファイルを含めたダウンロード・ファイルを追加し、「STAX スクリプトから JUnit を呼び出す」セクションにダウンロード・ファイルへのリンクを追加しました。

Fabio Negrello, Software Engineer, IBM

Photo of Fabio NegrelloFábio Negrello は、セキュリティー、Web アプリケーション、開発フレームワークなどの分野で 10 年以上のソフトウェア開発経験を積んでいます。現在は、IBM Brazil Software Lab の Registry Services for Jazz for Service Management でソフトウェア・エンジニアとして働いています。



2013年 6月 06日

リグレッション・テストとインクリメンタル・テストについて

リグレッション・テストは、ソフトウェアに加えた変更によって新しい問題 (つまり、障害) がソフトウェアに取り込まれていないことを確認するために行います。また、以前に修正したバグが再び発生していないことを確認するという目的もあります。サード・パーティーのコンポーネントやライブラリー (XML を処理するための API や、JPA などのデータベース抽象化 API など) への依存関係が多数あるソフトウェアでは、変更によって新しい問題が生じることは特によくあることです。例えば、データベース・スキーマをわずかに変更しただけでも、アプリケーションの動作が変わることがあります。このような変化を予測するのは困難です。本質的に複雑なソフトウェアでは、一般的なコードでのたった 1 つのささいな変更が、予期せぬ副次的影響をもたらす可能性があります。

特定のミドルウェア・ソフトの以前のバージョンの継続サポートや、異なる複数のプラットフォームの継続サポートが必要なシナリオでは、保守や開発の作業時に問題が取り込まれる可能性が極めて高くなります。データベース・ミドルウェアの 1 つのバージョンで正常に動作する修正や関数でも、別のバージョンでは散々な結果になる可能性があります。また、関数を追加するときに、新しいバージョンのミドルウェアでのみ使用可能な API が、それよりも前のバージョンを使用しているクライアントを壊してしまう可能性も考えられます。異なる複数のプラットフォームをサポートする際には、コマンドライン・インターフェースやスクリプトに依存する関数を徹底的にテストしてください。これを怠ると、例えば Windows とLinux などといったオペレーティング・システムの違いによって、動作が異なってくる可能性があります。

リグレッション・テストでは、ソフトウェア全体を 1 つのターゲットとして捉え、他のコンポーネントやアプリケーションと、このソフトウェアとの相互依存関係のテストを行いますが、開発時には開発対象の特定のモジュールや関数にフォーカスしてください。それぞれのモジュールや関数は、それぞれの実装時にインクリメンタル方式でテストすることができます。他の関数がまだ実装されていなければ、その関数を参照するスタブを使用できる場合もあります。インクリメンタル・テストが十分に構造化されていて他への依存性がなく、特定の環境 (必須のミドルウェア・ソフト、マシン、構成など) でインクリメンタル・テストを繰り返し行えるようであれば、それらのインクリメンタル・テストをその後のリグレッション・テストで再利用することができます。このような構造化と非依存性により、すべてのコードが開発時と同じ精査プロセスでテストされるため、テストを作成し直す必要が軽減され、テストの品質が向上します。

開発中の関数を、あるアーキテクチャー、オペレーティング・システム、ミドルウェアのバージョンの組み合わせでテストする際に、自動化されたインクリメンタル・テストを実施するというケースを考えてみましょう。例えば、Linux、AIX、Windows 7、Windows XP でサポートされているコマンドライン・インターフェースについて考えてみると、開発時に、これらのオペレーティング・システムのそれぞれでテストを実行するとなると、かなりのリソースと時間が必要になります。場合によっては、新しい機能をテストするのに必要な時間が、その機能を開発するのに必要な時間を上回ってしまうことも考えられます。さらに、プロジェクトで多数の機能が別々の開発者によって同時に開発されているとしたら、より一層困難を極めることになります。一般にテストに使用できるマシンは、それが仮想マシンだとしても数が限られているためです。テストのために、データベース・サーバーやアプリケーション・サーバーなどが事前に構成された環境が必要になるケースもよくあります。テスト専用のマシンの数が多ければ、それに比例して、各マシンを更新して構成するために必要な時間が増えてきます。一連の環境 (つまり、テスト・ベッド) でツールによって自動インクリメンタル・テストを実行すれば、環境ごとに手動でテストを実行するのに必要な時間を節約できると同時に、リソースをより有効に共有できるようになります。

自動リグレッション・テストでは、インクリメンタル・テストと同じテスト・ベッドを使用することができます。その場合、例えば自動リグレッション・テストを 1 日に 1 回実行されるように設定することで、リグレッション・テストがなければ開発やインクリメンタル・テストで使用していたかもしれないリソースを、リグレッション・テストの時間には使わないようにします。長い時間がかかるリグレッション・テストは、さらに長い間隔をおいて (例えば、毎週末など) 実行されるように設定することができます。


STAF/STAX フレームワーク

STAF (Software Testing Automation Framework) は、自動化ソリューションを構築するのに最適なサービスのセットが組み込まれた、オープンソースのフレームワークです。サービスは、再利用可能なコンポーネントになっており、これらのコンポーネントが STAFのすべての機能を提供します。STAF の各サービスには、以下に示すような特定の関数セットが用意されています。

  • ロギング
  • ファイルシステム操作
  • セキュリティーおよびプロセスの呼び出し
  • 一連のリクエストの定義

このフレームワークに組み込まれていないサービスは、e-メール・サービス、FTP サービス、タイマー・サービスなど数多くありますが、これらのサービスは簡単にフレームワークに追加することができます。

STAX サービスは、Java 環境 (つまり、実行エンジン) に実装される特殊なサービスで、XML を使用して他の STAF サービスを呼び出すことができます。STAX サービスでは、以下の内容に対応しています。

  • 並列実行
  • ユーザーによる、実行制御の粒度の定義
  • ネストされたテスト・ケースのサポート
  • 実行時間の長さを制御する機能
  • 実行時にモジュールをインポートする機能
  • Python および Java の既存のモジュールとパッケージのサポート

STAX で定義されている XML 要素はプログラミング言語のように機能し、言語に不可欠な以下の要素がすべて含まれています。

  • ループ
  • 条件
  • エラー処理
  • 関数呼び出し

STAX で XML 要素のスクリプトを使用すると Python スクリプトを埋め込むことができるため、さらに複雑なロジックを実装することや、事前に定義済みの Python モジュールを利用することが可能になります。

Python コードは、Jython によって実行されます。Jython では Python プログラミング言語の構文を採用しており、Java プラットフォーム上で Python コードを実行することができます。これにより、Java ライブラリーや他のJava アプリケーションを使用した統合が可能となるため、Java 開発者で構成されるチームの生産性が向上します。

STAX の興味深い機能の 1 つは、補助関数が含まれる既存の STAX ファイルをインポートできることです。この機能により、自動化コードの編成が改善され、コードの再利用が促進されます。

STAF は、構成済みポートからのリクエストをリッスンするデーモンとして実行されます。STAF サービスには、これらのリクエスト (必要なコマンドに対する命令) を介してアクセスします。STAX では、リクエストを表現するために使用できる要素として stafcmd を定義しています。リスト 1 に記載されているように、リクエストには以下の情報を含めます。

  • コマンドを実行する場所
  • コマンドを実行するサービス
  • 実際のコマンド
リスト 1. リクエストの例
<stafcmd>
    <location>'lab01.mydomain.com'</location>
    <service>'FS'</service>
    <request>'CREATE DIRECTORY /tmp/CVT_TEMP' </request>
</stafcmd>

リスト 1 のコードは、lab01.mydomain.com マシン上にディレクトリー /tmp/CVT_TEMP を作成するように要求しています。このコマンドを定義しているサービスは FS (File System サービス) です。コマンドを実行する場所が ‘local’ でない場合、コマンドの実行を要求する STAF インスタンスは、指定された場所にリクエストを送信します。この通信は、呼び出し側には明らかになりません。ローカル・マシンにディレクトリーを作成する場合のリクエストにも、同じ構文を使用します。唯一の違いは、場所を 'local' に指定することだけです。このように指定することにより、STAF はコマンドを他のマシンではなく、ローカルで実行する必要があることを理解します。


STAF/STAX を使用してテストを自動化する

テストの実行を自動化するために必要なステップは、テスト対象のソフトウェアによって異なりますが、ほとんどの自動化ソリューションでは主に以下のステップが必要になります。

  1. テスト・ケース用の環境を準備する
    1. リモート・ディレクトリーを作成する
    2. 必要なイメージと前提条件をリモート環境にコピーする
    3. イメージと前提条件をそれぞれ適切な場所に配置または解凍する
    4. データベース・サーバーまたはアプリケーション・サーバーを起動する
    5. データベースを作成する
    6. アプリケーションをインストールする
  2. テスト・ケースを実行する
  3. 情報 (結果、カバレッジ情報、ログ) を収集する
  4. リソースを解放する
    1. 一時フォルダーを削除する
    2. データベースを破棄する
  5. 結果からレポートを作成する (Junit レポート、Coverage レポート、または HTML レポート)
  6. 結果をローカルまたはリモート・サーバーに格納する (FTP、共有フォルダー、またはその他のツールを使用)
  7. 通知 (e-メール) を送信する

以下の例で説明するように、上記のすべてのステップは、STAF/STAX を使用して実行することができます。

テスト・ケース用の環境を準備する

テスト・ベッドを編成する 1 つの方法は、環境ごとにプロパティー・ファイルを作成し、そのファイルに、テスト・ケースに必要なすべてのプロパティーを配置することです。これらのプロパティーには、例えば以下のものがあります。

  • データベースのポート
  • サーバーのポート
  • ソフトウェアのインストール・ディレクトリー
  • テスト・ケースに必要なその他すべてのプロパティー

それぞれのプロパティー・ファイルは、ある特定のマシンでの 1 つのテスト環境を表します。1 つのマシンに複数の環境を設定することもできます。例えば、ある環境には DB2 データベースと WebSphere Application Server V8.5 のインストール済み環境を定義する一方、同じマシン上の別の環境には Oracle と WebSphere Application Server V7.0 のインストール済み環境のプロパティーを含めるといった具合です。この場合も、それぞれのプロパティー・ファイルが、ある特定のマシンでの 1 つのテスト環境を表しています。

準備フェーズでは、開発者は一連の環境に対して順番に、それぞれの環境が定義されているリモート・マシンでテストを行うための準備用コマンド・セットを実行する、という作業を繰り返す必要があります。リスト 2 に、環境に対する基本ループを示します。

リスト 2. 基本ループ
<script>
    env_list = ['LinuxDB2Websphere8','WindowsDB2Webshere85']
</script>
<paralleliterate var="env_name" in="env_list">
    <sequence>
        <message log="STAXMessageLog">
           'Preparing to launch tests on %s' % env_name
        </message>
        <tcstatus result="'info'">
           'Reading environment information from %s' % env_name
        </tcstatus>
        <script>
           file_path = "%s/CVT/config/%s.properties" % (temp_dir, env_name)
        </script>
        <call function="'read_properties'">
            {'properties_file' : file_path}
        </call>
        <script>
            props_dict = STAXResult
            try:
               mach_name = props_dict.get('STAF_MACHINE')
            except:
               raise Exception('Property STAF_MACHINE not found in Env %s' % env_name)
        </script>

	 … prepare remote environment for tests

    </sequence>
</paralleliterate>

リモート・ディレクトリーを作成する

テストを実行するための準備として、ディレクトリーを 1 つ以上作成し、そのディレクトリーに STAX スクリプトと、必要なライブラリーや製品イメージを配置できるようにする必要もあります。推奨されるディレクトリー構造の一例は以下のとおりです。

  • <TEMP_DIR>/CVT_TEMP/PRODUCT → ライブラリーと必要なイメージを配置するディレクトリー
  • <TEMP_DIR>/CVT_TEMP/CVT → 補助 STAX スクリプトおよびテストに必要なその他のリソースを配置するディレクトリー

システムの一時ディレクトリーの場所を取得するには、この場所の値を持つ STAF 変数を解決する必要があります (リスト 3 を参照)。

リスト 3. STAF 変数の解決
<stafcmd>
    <location>mach_name</location>
    <service>'VAR'</service>
    <request>'RESOLVE STRING {STAF/Env/TEMP}'</request>
</stafcmd>
<script>
    temp_dir = STAFResult
    product_dir = 'CVT_TEMP/PRODUCT/%s' % temp_dir
</script>

ディレクトリーを作成するには、ファイルシステム・サービス (FS) を使用します (リスト 4 を参照)。

リスト 4. ディレクトリーの作成
<stafcmd>
    <location>mach_name</location>
    <service>'FS'</service>
    <request>'CREATE DIRECTORY %s FULLPATH' % (product_dir)</request>
</stafcmd>

必要なイメージと前提条件をリモート環境にコピーする

リモート環境を準備する際には、圧縮したイメージと前提条件をコピーして宛先ディレクトリーで解凍します。ファイルをコピーするには、リスト 5 の COPY リクエストを使用します。

リスト 5. 圧縮イメージおよび前提条件のコピー
<stafcmd>
     <location>'LOCAL'</location>
     <service>'FS'</service>
     <request>'COPY FILE %s/%s TODIRECTORY %s TOMACHINE %s' % \
         (local_directory, zip_file, remote_temp_dir, mach_name)</request>
</stafcmd>

イメージと前提条件をそれぞれ適切な場所に配置または解凍する

イメージを解凍するには、リスト 6 の ZIP サービスを使用します。

リスト 6. イメージの解凍
<stafcmd name="'Unzip %s on %s' % (zip_file, mach_name)">
    <location>mach_name</location>
    <service>'ZIP'</service>
    <request>'UNZIP ZIPFILE %s/%s TODIRECTORY %s REPLACE' % \
        (source_directory, zip_file, target_directory)</request>
</stafcmd>

データベースまたはアプリケーション・サーバーを起動する

プロセス要素は、ある特定のマシンで実行される STAF プロセスを表します。プロセス要素を使用して、スクリプトまたは実行可能コードを実行し、その実行が完了するまで待機することができます。他にも、例えば以下のオプションを指定することができます。

  • コマンド自体
  • コマンドのパラメーター
  • 作業ディレクトリー
  • プロセスで使用する環境変数

リスト 7 を参照してください。

リスト 7. プロセス要素
<script>
    ...
    cmd = 'C:/PROGRA~1/IBM/WebSphere85/profiles/Dmgr01/bin/startManager.bat'
    parms = '-username %s -password %s' % (user, passwd)
</script>
<process name="'cmd %s %s' % (cmd, parms)">
    <location>mach_name</location>
    <command mode="'shell'">cmd</command>
    <parms>parms</parms>
    <workdir>work_dir</workdir>
    <envs>envs</envs>
    <console use="console" />
    <stdout>stdoutFile</stdout>
    <stderr>stderrFile</stderr>
    <returnstdout />  
    <returnstderr />  
</process>

プロセス要素は、スクリプトまたは実行可能コードを実行する際の基本ツールです。テストの実行中にいくつもの異なるスクリプトを実行する場合は、呼び出しをラップする補助 STAX 関数を作成し、実行されたコマンドとそのパラメーターをログに記録して、終了コードをチェックするのが賢明です。

データベースを作成する

データベースを作成するスクリプトを実行する場合にも、プロセス要素を使用することができます。リスト 8 に、DB2 データベースを作成するコードを記載します。

リスト 8. DB2 データベースの作成
<script>
    script_name = 'db2Setup.bat'
    db_script_dir = 'C:/CVT_TEMP/PRODUCT/bin'
    cmd_str = 'db2cmd -w -i -c %s %s -d %s -u %s -p %s' % \
        (script_name, migrate, db_name, db_user, db_pswd)
</script>
<process name="'cmd %s %s' % (cmd, parms)">
    <location>mach_name</location>
    <command mode="mode">cmd</command>
    <workdir>db_script_dir</workdir>
    <console use="console" />
    <returnstdout />  
    <returnstderr />  
</process>

アプリケーションをインストールする

インストール・プロセスでは通常、非対話モードでスクリプトまたは実行可能コードを呼び出すことになります。このプロセスは、リスト 8 に記載した、データベースをセットアップするスクリプトを呼び出す方法と同様です。

テスト・ケースを実行する

STAF/STAX はテスト環境をセットアップするのに役立つとは言え、同じシナリオのさまざまなバリエーションをテストするとなると、テスト・コード (STAX スクリプトや Python スクリプト) が複雑になったり、繰り返しが多くなったりします。テスト・コードが複雑だと保守が困難になりますが、これはすべてのテスターと開発者に十分なプログラミング・スキルがあるとは限らない場合はなおのことです。STAF/STAX は堅固な基本フレームワークを提供しますが、他の言語で以前に作成されたテストを再利用して、レポート作成ツールを統合すれば、テスターは、直感的に理解できない場合がある STAX ログに目を通す必要がなくなります。Java 言語の場合、最もよく使われているテスト・フレームワークは JUnit です。ほとんどの開発ソフトウェアは、JUnit と統合することで、テスト・コード作成時の生産性を向上させる興味深い関連フレームワークを利用できるようになります。例えば、DDTUnit によって、テスト・ロジックとテスト・データを切り分けることも可能です。ANT で生成された JUnit レポートも、レポートを整理してテスト・ケースでの失敗を見つけるのに役立ちます。

STAX スクリプトから JUnit を呼び出す

単純な Java クラスとして JUnit を直接起動することもできますが、それよりも簡単なのは、ANT を使って呼び出す方法です。JUnit ANT タスクは JUnit の呼び出しをカプセル化し、クラス・パスを設定し、テストの実行を XML ファイル形式で記録します。この XML ファイルを junitreport という別のタスクで使用すれば、HTML 形式のレポートを生成することができます。

一連のテスト・ケースまたはテスト・スイートで JUnit を呼び出すには、サンプル・ファイルの JUnitUtil.xml に定義されている run_junit_ant 関数を使用することができます。この関数は、クラス・パス定義 junit.tmp.classpath を設定した一時 ANT プロジェクトを作成し、そのプロジェクトに lib_dirs および libs パラメーターに指定されているすべての JAR ファイルを含めます。続いて、クラス・パスを参照して、サンプル・ファイル JUnitRunner.xml に定義されたターゲット junit.run を実行します (JUnitRunner.xml および JUnitUtil.xml サンプル・ファイルを入手するには、「ダウンロード」を参照してください)。このターゲットが、JUnit タスクを起動します (リスト 9 を参照)。

リスト 9. JUnit タスクの起動
<project name="cvt.junit.runner" default="junit.run" basedir=".">
  <import file="${junit.tmp.classpath.import}" />
  <target name="junit.run" description="Runs the unit test cases.">
    <echo message="Generating JUnit output at ${output.dir}"/>    
    <junit dir="${work.dir}" fork="yes" forkmode="once" printsummary="on" 
           haltonfailure="no" haltonerror="no" showoutput="true" 
           failureproperty="ut.failed">            
      <jvmarg value="-Djava.util.logging.config.file=${java.util.logging.config.file}"/>
      <sysproperty key="net.sourceforge.cobertura.datafile"
        file="{net.sourceforge.cobertura.datafile}" />
      <classpath refid="junit.tmp.classpath" />            
      <test name="${cvt.test.class}" haltonfailure="no" 
        outfile="TEST-${cvt.test.class}" todir="${output.dir}">
        <formatter type="xml"/>
      </test>
    </junit>       
    <fail if="ut.failed" 
          message="Some of the tests failed. Check the JUnit report for details." />
  </target>
</project>

カバレッジ情報を生成するには、net.sourceforge.cobertura.datafile プロパティーを使用することができます (詳細については、Cobertura プロジェクトを参照してください)。このプロパティーの値は、run_junit_ant 関数の引数 jvm_args に指定することができます。

情報 (結果、カバレッジ情報、ログ) を収集する

この場合も、単一のファイルを 1 つずつ転送するより、圧縮ファイルを転送したほうが効率的です。リモート・マシンのディレクトリーを圧縮するには、ZIP リクエストを使用します。リスト 10 では、マシン mach_name 内でディレクトリー ‘C:/CVT_TEMP/CVT/logs’ を ZIP ファイル ’C:/CVT_TEMP/testcase_123_results.zip’ に圧縮しています。

リスト 10. ZIP リクエストを使用したリモート・マシンのディレクトリーの圧縮
<script>
   zip_file = 'C:/CVT_TEMP/testcase_123_results.zip'
   results_dir = 'C:/CVT_TEMP/CVT/logs'
</script>
<stafcmd name="'Compressing results'">
   <location>mach_name</location>
   <service>'ZIP'</service>
   <request>'ADD ZIPFILE %s DIRECTORY %s RECURSE RELATIVETO %s' % \
       (zip_file, results_dir, results_dir)</request>
</stafcmd>

圧縮が完了したら、COPY FILE リクエストを使用して、その結果を取得することができます (リスト 11 を参照)。

リスト 11. COPY FILE リクエストの使用
<script>
    local_results_dir = 'C:/CVT_TEMP/results'
</script>
<stafcmd>
    <location>mach_name</location>
    <service>'FS'</service>
    <request>'COPY FILE %s TODIRECTORY %s' % (zip_file, local_results_dir)</request>
</stafcmd>

異なるネットワークに分散された複数のマシンでテストを実行する場合には、ファイアウォールの問題が持ち上がる可能性があります。その場合、より安全な方法として、GET BINARY リクエストを使用して、呼び出しによる結果としてファイル全体をバイナリー形式で取得してください。この方法の利点は、リモート・マシンがローカル・マシンを解決してそのマシンにアクセスする必要がなくなることです。その一方、ファイルのサイズが大きい場合には、転送する前にファイルを小さく分割しなければ取得できないという欠点もあります。

リソースを解放する

ディレクトリーを削除するためのリクエストは至って簡単です。削除するディレクトリーと、そのディレクトリーが存在するマシンを指定するだけで、該当ディレクトリーを削除することができます (リスト 12 を参照)。

リスト 12. ディレクトリー削除のリクエスト
<stafcmd name="'Delete remote directory'">
   <location>mach_name</location>
   <service>'FS'</service>
   <request>'DELETE ENTRY %s RECURSE CONFIRM' % \
      (file, ignore_param)</request>
</stafcmd>

データベースの削除、サーバーの停止、またはその他のアクションを実行するには、リスト 12 で説明したプロセス要素を使用します。

結果からレポートを作成する (JUnit レポート)

JUnit レポートを作成するには、JUnit テスト・ケースを実行する場合と同じ手法を使用します。つまり、JUnit レポートを作成するタスクを起動するための補助 ANT プロジェクトを作成します (リスト 13 を参照)。

リスト 13. 補助 ANT プロジェクトの作成
<project name="cvt.junit.report" basedir=".">
   <target name="junit.report">
        <echo message="Generating JUnit Report at ${junit.report.todir}"/>
        <echo message="Reading results from ${junit.report.dir}"/>
        <mkdir dir="${junit.report.todir}" />
        <junitreport todir="${junit.report.todir}">
            <fileset dir="${junit.report.dir}">
                <include name="TEST-*.xml" />
            </fileset>
            <report todir="${junit.report.todir}" />
        </junitreport>
        <echo message="JUnit Report Generated"/>
    </target>
</project>

このスクリプトを実行するには、プロセス要素を使ってスクリプトを呼び出します。

リスト 14. プロセス要素を使用したスクリプトの実行
<script>
    from java.io import File
    f = File(STAXJobXMLFile)
    ant_script = File(f.getParentFile(),'utilities/JUnitReport.xml').getAbsolutePath()
    ant_script = ant_script.replace('\\','/')
    java_envs = ''
    java_envs = '%s -Djunit.report.todir=%s' % (java_envs, output_dir)
    java_envs = '%s -Djunit.report.dir=%s' % (java_envs, work_dir)
    parms = '%s -f %s junit.report' % (java_envs, ant_script)
</script>
<process name="'cmd %s %s' % (ant_cmd, parms)">
    <location>mach_name</location>
    <command mode="'shell'">ant_cmd</command>
    <parms>parms</parms>
    <workdir>work_dir</workdir>
    <console use="console" />
    <stdout>stdout</stdout>
    <stderr>stderr</stderr>
    <returnstdout />  
    <returnstderr />  
</process>

結果をローカルまたはリモート・サーバーに格納する (FTP または共有フォルダーを使用)

テスト結果の検証に役立つレポートをすべて実行した後、これらのレポートを 1 つまたは複数のファイルに圧縮します。圧縮したファイルを開発者やテスターが直接アクセスできる Web サーバーに格納すれば、結果にアクセスしやすくなります。リスト 15 に一例を記載します。

リスト 15. レポートの圧縮
<stafcmd>
    <location>'local'</location>
    <service>'FTP'</service>
    <request>'PUT HOST %s URLPATH %s FILE %s USER %s PASSWORD %s' % \
        (CVT_FTP_SERVER, remotePath, localPath, ftp_user, ftp_passwd)
    </request>
</stafcmd>

通知 (e-メール) を送信する

インクリメンタル・テストまたはリグレッション・テストに関する通知を開発者やテスターに送信するには、EMAIL サービスを使用することができます。staf.cfg (bin ディレクトリーにある STAF 構成ファイル) に定義されたこのサービスの構成は単純なもので、指定する必要があるのは e-メール・サーバーと、サービス実装が含まれる JAR ファイルのパスだけです。これらのファイルは、以下のようにして STAF ダウンロード・ページからダウンロードすることができます。

SERVICE email LIBRARY JSTAF EXECUTE c:/staf/services/email/STAFEmail.jar \
              PARMS "MAILSERVER na.relay.ibm.com"

リスト 16 に、e-メール送信のリクエストの構造を記載します。

リスト 16. e-メール送信のリクエストの構造
<stafcmd name="'send_email'">
    <location>'local'</location>
    <service>'EMAIL'</service>
    <request>email_cmd</request>
</stafcmd>

ここで、email_cmd のフォーマット (Email Service User's Guide による) はリスト 17 のとおりです。

リスト 17. email_cmd のフォーマット
SEND < TO <Address> | CC <Address> | BCC <Address> >...
     [FROM <user@company.com>] [CONTENTTYPE <contenttype>]
     < MESSAGE <Message> | FILE <File> [MACHINE Machine] >
     [SUBJECT <subject>] [NOHEADER] [TEXTATTACHMENT <file>]...
     [BINARYATTACHMENT <file>]... [ATTACHMENTMACHINE <machine>]
     [RESOLVEMESSAGE | NORESOLVEMESSAGE]
     [AUTHUSER <User> AUTHPASSWORD <Password>]

STAF/STAX で継続的インテグレーションを実施する

開発者の観点からすると、継続的インテグレーションとは、新しいコードや変更をコード・リポジトリーに頻繁に統合し、変更によって既存のコードが壊れていないことを継続的に検証する作業です。

一般に、検証を実行するのは、自動化されたビルド・システムです。自動化されたビルド・システムでは、変更が行われたのを検出することや、スケジューリングした時刻にビルドを実行することができます。また、壊れている可能性があるコードを検証し、可能であれば基本となる関数の正常な動作が維持されていることを検証するために、一連のユニット・テストを実行します。ビルドは頻繁に行うことも、長時間実行することもできます。通常、継続的インテグレーション・システムにコンポーネント・テストを含めるようにはしません。ビルドのたびにコンポーネント・テストを実行するまでのことはないからです。

コンポーネント・テストを継続的に実行する場合の 1 つのソリューションは、別個のシステムを使用することです。そのシステムで、現在のコード・ベースに対して自動テストを実行するか、リクエストに応じて特定のテストを実行します。例えば、以下の処理を行う単一ループを STAX から実行するケースを考えてみましょう。

  1. 最新の本番イメージとテスト・イメージを取得する
  2. あらかじめスケジューリングされたリグレッション・テストの予定を確認する
  3. テスト・コード (各テスト・ケースの STAX スクリプト) の変更を検出する
  4. インクリメンタル・テストからのリクエストへの対応が予定されているか確認する

すべてのテストが含まれるリグレッション・テストは、1 日に 1 回実行してください。インクリメンタル・テストについては、テストを必要とするコードの変更 (修正や新しい機能など) が発生するたびに実行することができます。例えば、既存のコマンドライン・インターフェースに対する新規パラメーターをテストするには、そのコマンドライン・インターフェースに固有のインクリメンタル・テストを実行します。インクリメンタル・テストを実行すると、夜間にリグレッション・テストが行われるまでは検出されないはずの障害を、もっと早い時点で検出できるため、チームの生産性が向上します。

イメージ (テスト対象のソフトウェアが含まれたバンドル、またはテスト・リソース) が更新されているかどうかを確認するには、ファイルの変更時刻を取得して、ローカル・ファイルに格納されている前回の変更時刻と比較します。FTP サーバーに置かれているファイルの変更時刻を取得するための Python コマンドは以下のとおりです。

ftp.cwd(ftp_url_path)
ftpMDTM = ftp.sendcmd('MDTM %s' % file)
#Example of result: '213 20101129060511'

前回確認をしたとき以降にファイルの変更があった場合には、STAX FTP サービスまたは Python FTP モジュールを使用して、そのファイルをダウンロードすることができます。リグレッション・テストを実行する時刻であるかどうかの確認は、スケジューリングされたリグレッション・テストの時刻と、現在の時刻を比較するだけの簡単な処理にすることができます。スケジューリングされたリグレッション・テストの時刻を、現在の時刻が過ぎている場合は、リグレッション・テストを実行します。

より複雑な関数では、インクリメンタル・テストを実行することができます。インクリメンタル・テストは、テスト・ケースのリストか、事前に定義されたテスト・ケースのグループを、選択された一連の環境で実行するためのリクエストです。これを実装する一例として、Web サーバーで共有されているファイルに新しいリクエストがあるかどうかを定期的に確認する方法があります。このファイルにリクエストを含めるには、ローカル Web サーバーが提供する HTML ページを使用することができます。リクエストには、例えば以下の情報が含まれます。

  • リクエスト (事前に定義されたテスト・ケースのグループか、個々のテスト・ケースのリスト)
  • 製品のバージョン
  • テスト・ケースを実行する環境のリスト
  • sessionID
  • リクエストの ID
  • リクエストを処理するために必要なその他の内部情報

以下の例では、この記事のフォーマット上の制約のため、コードが複数の行になっていますが、通常は連結された 1 行のコードです。

t||testcase_nop||FRS-1.0.0||LinuxDB2Websphere85,ZLinuxDB2Websphere8||false||true|
|4EF60DC3B825707D6BAE349047B4E664||fnegre@br.ibm.com||ready||20121023220123||default

図 1 に、インクリメンタル・テストを要求するために使用するページの例を示します。

図 1. リクエスト・ページ
インクリメンタル・テストのリクエストを示すページのスクリーン・キャプチャー

継続的インテグレーションを実行する STAF/STAX スクリプトとのインターフェースとして、Apache Tomcat のような Web サーバーを使用すると、エンド・ユーザーが選択可能なオプションの数を、例えば以下のように増やすことができます。

  • カスタマイズしたイメージ (開発者/テスター/サポート・アナリストがローカルで生成したイメージ) を指定する
  • FTP サーバーから直接イメージをダウンロードする
  • 実行中のリクエストをキャンセルする
  • 現在の実行に関する STAX ユーザー・ログを表示する
  • ログと履歴、さらにはその他のレポートを表示する

図 2 に、システムの main 関数へのリンクを提供するメイン・ページの実装を示します。Web サーバーは、以下のような継続的インテグレーション・システムのステータスを示すのにも役立ちます。

  • 実行中のテスト・ケース
  • 開始時刻
  • リクエストの送信者
  • テスト対象の環境
  • 結果へのリンク (テストが完了している場合)
図 2. 継続的インテグレーション・システムのメイン・インデックス
システムの main 関数へのリンクを提供するメイン・ページのスクリーン・キャプチャー

ユーザーは図 3 に示すページから、以前に実行した結果にアクセスすることができます。結果は、環境名別に構成されています。結果には、テスト・ケースのログ、JUnit レポート、カバレッジ・レポートなど、テストによって生成されたあらゆる有用な情報が含まれています。図 3 のレポートには、6 つの環境が示されていることに注意してください。これらの環境ではすべてのテスト・ケースが夜間に実行されるため、日中にインクリメンタル・テストを実行することができます。使用可能な環境には、Linux for System z マシン、Windows マシン、Linux (Red Hat) マシンなどがあります。新しい環境をシステムに接続するには、新規環境ごとにプロパティー・ファイルを作成します。

図 3. リグレッション・テストのログへのアクセス
リグレッション・テストのログにアクセス可能なページのスクリーン・キャプチャー

基本となる関数が含まれる継続的インテグレーション・システムは、以下のシーケンスに沿って少しずつ構築することができます。

  1. 個々のテスト・ケースをマシンで実行する STAX スクリプト
  2. 複数の環境を更新/準備した後、これらの環境で複数のテスト・ケースを実行する STAX スクリプト
  3. 上記のスクリプトを夜間に実行する STAX スクリプト
  4. HTML ページおよびステータスを表示するページからインクリメンタル・テストを実行し、現在の実行状況を表示する機能

まとめ

STAF/STAX を使用して、テスト・ケースと継続的インテグレーション用インフラストラクチャーの両方を構築する大きなメリットの 1 つは、テスト自動化システムに統合可能な新しい関数やスクリプトを作成することによって、必要に応じてテスト自動化システムを拡張できる柔軟性にあります。プロジェクトで、アジャイル開発を採用し、STAF/STAX ですべてのテストを自動化できるようにして継続的インテグレーション・システムに統合すれば、新しい関数や修正をタイミング良くテストできるようになります。さらに、ユーザーの要求に応じて各種の環境でインクリメンタル・テストを並行して実行することで、開発期間を短縮できるとともに、ソフトウェアの品質を向上させることができます。


ダウンロード

内容ファイル名サイズ
Sample files: JUnitRunner.xml and JUnitUtil.xmlsamples.zip3KB

参考文献

学ぶために

  • STAF ホーム・ページ: STAF および STAX について詳しく調べてください。
  • Apache Tomcat Web サーバー: Java Servlet および JavaServer Pages テクノロジーのオープンソース・ソフトウェア実装をダウンロードしてください。ドキュメントとチュートリアルも用意されています。
  • JUnit テスト・フレームワーク: 繰り返し可能なテストを作成するためのシンプルなフレームワークをダウンロードして、ドキュメントを読んでください。
  • 「DDTUnit - A Data Driven Approach to Unit Testing」: DDTUnit とそのドキュメントをダウンロードしてください。DDTUnitは、コード化したテスト・メソッドに基づき複数のテスト・ケースをカバーするデータ中心の手法です。
  • オープンソース技術を使用して開発し、IBM の製品と併用するときに役立つ広範囲のハウツー情報、ツール、およびプロジェクト・アップデートについては、developerWorks Open source ゾーンを参照してください。
  • さまざまな IBM 製品や IT 業界のトピックに焦点を絞った developerWorks テクニカル・イベントで最新情報を入手してください。
  • developerWorks 最新イベント情報のページで、IBM の製品およびツールについての情報や IT 業界の動向についての情報を迅速に把握してください。
  • developerWorks podcasts で、ソフトウェア開発者向けの興味深いインタビューとディスカッションを聞いてください。
  • Twitter で developerWorks をフォローしてください。
  • 初心者向けの製品のインストールおよびセットアップから熟練開発者向けの高度な機能に至るまで、さまざまに揃った developerWorks デモを見てください。

製品や技術を入手するために

  • IBM ソフトウェア評価版を試し、次のオープンソース開発プロジェクトには開発者専用ソフトウェアを使って革新してください。IBM ソフトウェア評価版は、ダウンロードまたは DVD で入手できます。

議論するために

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Open source, Industries, Web development, Java technology, Cloud computing, DevOps
ArticleID=932584
ArticleTitle=STAF/STAX によるテストの自動化と継続的インテグレーション
publish-date=06062013