3.2.2. データベースを使用するクラスのテスト

3.2.2.1. 概要

データベースアクセスクラスなど、データベースを使用するクラスをテストする方法を記載する。

データベースを使用するクラスをテストする場合、本フレームワークで用意されたクラスを使用することでデータベースに関する操作(テストデータ投入、データ確認)を行うことができる。

3.2.2.1.1. 全体像

../../../../../_images/class_structure.png

3.2.2.1.1.1. 主なクラス, リソース

名称 役割 作成単位
テストクラス テストロジックを実装する。DbAccessTestSupportを継承すること。 テスト対象クラスにつき1つ作成
テストデータ(Excelファイル ) テーブルに格納する準備データや期待する結果など、テストデータを記載する。 テストクラスにつき1つ作成
テスト対象クラス テストされるクラス。
DbAccessTestSupport 準備データ投入などデータベースを使用するテストに必要な機能を提供する。また、テスト実行前後にデータベーストランザクションの開始・終了処理を行う( デフォルト以外のトランザクションを使用したい )。

3.2.2.2. 基本的なテスト方法

目的に応じた、本フレームワークのAPIの使用方法を以下に記載する。

3.2.2.2.1. 参照系のテスト

参照系のテストにおいて、テスト対象クラスが期待通りにデータを取得していることを確認する場合、以下の手順でデータベースからの参照結果を確認できる。

  1. データベースに準備データを登録する。
  2. テスト対象クラスのメソッドを起動する。
  3. 戻り値として受け取った検索結果が期待した値であるか確認する。

3.2.2.2.1.1. シーケンス

../../../../../_images/select_sequence.png

3.2.2.2.1.2. テストソースコード実装例

public class DbAccessTestSample extends DbAccessTestSupport {

    /**
     * 全件検索のテスト。<br/>
     * 従業員テーブルに登録されたレコードを
     * 全件取得できることを確認する。
     */
    @Test
    public void testSelectAll() {

        // データベースに準備データを登録する。
        //引数にはシート名を記載する。
        setUpDb("testSelectAll");

        // テスト対象メソッドを起動する。
        EmployeeDbAcess target = new EmployeeDbAccess();
        SqlResultSet actual = target.selectAll();

        // 結果確認
        // Excelに記載した期待値と実際の値が等しいことを確認する
        // 引数には期待値を格納したシート名, 期待値のID, 実際の値を指定
        assertSqlResultSetEquals("testSelectAll", "expected", actual);
    }
}

3.2.2.2.1.3. テストデータ記述例

3.2.2.2.1.3.1. データベースに事前登録する準備データ

以下のようにデータを記載する。

  • 1行目 : SETUP_TABLE=<登録対象のテーブル名>
  • 2行目 : そのテーブルのカラム名
  • 3行目~ : 登録するレコード(2行目のカラム名と対応)

SETUP_TABLE=EMPLOYEE

ID EMP_NAME DEPT_CODE
00001 山田太郎 0001
00002 田中一郎 0002

SETUP_TABLE=DEPT

ID DEPT_NAME
0001 人事部
0002 総務部
3.2.2.2.1.3.2. テスト実行後に期待する値

以下のようにデータを記載する。

  • 1行目 : LIST_MAP=<シート内で一意になる期待値のID(任意の文字列)>
  • 2行目 : SELECT文で指定したカラム名または別名
  • 3行目~ : 検索結果(2行目のカラム名と対応)

LIST_MAP=expected

ID EMP_NAME DEPT_NAME
00001 山田太郎 人事部
00002 田中一郎 総務部

3.2.2.2.2. 更新系のテスト

テスト対象クラスが期待通りにデータを更新していることを確認する場合、以下の手順でデータベースの更新結果を確認できる。

  1. データベースに準備データを登録する。
  2. テスト対象クラスのメソッドを起動する。
  3. トランザクションをコミットする。
  4. データベースの値が期待通り更新されていることを確認する。

重要

Nablarch Application Frameworkでは複数種類のトランザクションを併用することが前提となっている。 そのため、テスト対象クラス実行後にデータベースの内容を確認する際には、 トランザクションをコミットしなければならない。トランザクションをコミットしない場合、 テスト結果の確認が正常に行われない。

補足

参照系のテストの場合はコミットを行う必要はない。

3.2.2.2.2.1. シーケンス

../../../../../_images/update_sequence.png

3.2.2.2.2.2. テストソースコード実装例

public class DbAccessTestSample extends DbAccsessTestSupport {
    @Test
    public void testDeleteExpired() {

        // データベースに準備データを登録する。
        // 引数にはシート名を記載する。
        setUpDb("testDeleteExpired");

        // テスト対象メソッドを起動する。
        EmployeeDbAcess target = new EmployeeDbAccess();
        SqlResultSet actual = target.deleteExpired();  // 期限切れデータを削除

        // トランザクションをコミット
        commitTransactions();

        // 結果確認
        // Excelに記載した期待値と実際の値が等しいことを確認する
        // 引数には期待値を格納したシート名, 実際の値を指定
        assertTableEquals("testDeleteExpired", actual);
    }

3.2.2.2.2.3. テストデータ記述例

3.2.2.2.2.3.1. データベースに事前登録する準備データ

以下のようにデータを記載する。

  • 1行目 : SETUP_TABLE=<登録対象のテーブル名>
  • 2行目 : そのテーブルのカラム名
  • 3行目~ : 登録するレコード(2行目のカラム名と対応)

SETUP_TABLE=EMPLOYEE

ID EMP_NAME EXPIRED
00001 山田太郎 TRUE
00002 田中一郎 FALSE
3.2.2.2.2.3.2. テスト実行後に期待する値

以下のようにデータを記載する。

  • 1行目 : EXPECTED_TABLE=<確認対象のテーブル名>
  • 2行目 : 確認対象テーブルのカラム名
  • 3行目~ : 期待する値

EXPECTED_TABLE=EMPLOYEE

ID EMP_NAME EXPIRED
// CHAR(5) VARCHAR(64) BOOLEAN
00002 田中一郎 FALSE

3.2.2.3. データベーステストデータの省略記述方法

データベースの準備データおよび期待値を記述する際、テストに関係の無いカラムについては記述を省略できる。 省略したカラムには、自動テストフレームワークによりデフォルト値が設定される。 この機能を使用することにより、テストデータの可読性が向上する。また、テーブル定義が変更された場合でも、関係無いカラムであればテストデータ修正作業は発生しなくなる為、保守性が向上する。

この機能は特に更新系テストケースに有効である。多くのカラムのうち1カラムだけが更新される場合、不要なカラムを記述する必要がなくなる。

重要

データベース検索結果の期待値を記述する際は、検索対象カラム全てを記述しなければならない(レコードの主キーだけを確認する、というような確認方法は不可)。

また、登録系テストの場合も、新規に登録されたレコードの全カラムを確認する必要があるので、カラムを省略できない。

3.2.2.3.1. DBに準備データのカラムを省略する場合

データベース準備データを記述する際にカラムを省略すると、省略されたカラムにはデフォルト値が設定されているものとして扱われる。

ただし、主キーカラムは省略できない

3.2.2.3.2. DB期待値のカラムを省略する場合

DB期待値から単純に無関係なカラムを省略すると、省略されたカラムは比較対象外となる。更新系テストの場合には、「無関係なカラムが更新されていないことを確認する」という観点も必要である。 この場合、データタイプにEXPECTED_TABLEではなく、EXPECTED_COMPLETE_TABLEを使用する。 EXPECTED_TABLEを使用した場合、省略されたカラムは比較対象外となるが、EXPECTED_COMPLETE_TABLEを使用した場合は、省略されたカラムにはデフォルト値が格納されているものとして比較が行われる。

3.2.2.3.3. 具体例

全カラムを記載した場合と、関係のあるカラムのみを記載した場合の記述例を以下に示す。

3.2.2.3.3.1. テストケース例

以下のテストケースを例として使用する。

「有効期限」を過ぎたレコードは「削除フラグ」が1に更新されること。[1]

[1]本テスト実施時の日付は2011/01/01とする。

使用するテーブル(SAMPLE_TABLE)には、以下のカラムがあるものとする。

カラム名 説明
PK1 主キー
PK2 主キー
COL_A テスト対象の機能では使用しないカラム
COL_B テスト対象の機能では使用しないカラム
COL_C テスト対象の機能では使用しないカラム
COL_D テスト対象の機能では使用しないカラム
有効期限 有効期限を過ぎたデータが処理対象となる
削除フラグ 有効期限を過ぎたレコードの値を‘1’に変更する

3.2.2.3.3.2. 省略せずに全カラムを記載した場合(悪い例)

全カラムが記載されており可読性に劣る[2]。 また、テーブル定義に変更があった場合、無関係なカラムであっても修正しなければならない。

[2]カラムCOL_A, COL_B, COL_C, COL_Dは本テストケースに無関係である。

準備データ

SETUP_TABLE=SAMPLE_TABLE

PK_1 PK_2 COL_A COL_B COL_C COL_D 有効期限 削除フラグ
01 0001 1a 1b 1c 1d 20101231 0
02 0002 2a 2b 2c 2d 20110101 0

期待値

EXPECTED_TABLE=SAMPLE_TABLE

PK_1 PK_2 COL_A COL_B COL_C COL_D 有効期限 削除フラグ
01 0001 1a 1b 1c 1d 20101231 1
02 0002 2a 2b 2c 2d 20110101 0

3.2.2.3.3.3. 関係のあるカラムのみを記載した場合(良い例)

関係のあるカラムのみを記載することで可読性、保守性が向上する。 このテストケースに関係のあるカラムは以下のとおり。

  • レコードを一意に特定する為の主キーカラム(PK_1,PK_2)
  • 更新対象レコードを抽出する条件となる「有効期限」カラム
  • 更新対象となる「削除フラグ」カラム

また、テーブル定義に変更があった場合でも、無関係なカラムであれば影響を受けない。

準備データ

実行テストに関係あるカラムのみを記述している。

SETUP_TABLE=SAMPLE_TABLE

PK_1 PK_2 有効期限 削除フラグ
01 0001 20101231 0
02 0002 20110101 0

期待値

期待値を記述する際、EXPECTED_TABLEの代わりにEXPECTED_COMPLETE_TABLEを使用する。

EXPECTED_COMPLETE_TABLE=SAMPLE_TABLE

PK_1 PK_2 有効期限 削除フラグ
01 0001 20101231 1
02 0002 20110101 0

3.2.2.3.4. デフォルト値

自動テストフレームワークのコンポーネント設定ファイルにて明示的に指定していない場合、デフォルト値には以下の値が使用される。

カラム デフォルト値
数値型 0
文字列型 半角スペース
日付型 1970-01-01 00:00:00.0

3.2.2.3.5. デフォルト値の変更方法

3.2.2.3.5.1. 設定項目一覧

nablarch.test.core.db.BasicDefaultValuesクラスを使用し、 以下の値をコンポーネント設定ファイルで設定できる。

設定項目名 説明 設定値
charValue 文字列型のデフォルト値 1文字のASCII文字
numberValue 数値型のデフォルト値 0または正の整数
dateValue 日付型のデフォルト値 JDBCタイムスタンプエスケープ形式 (yyyy-mm-dd hh:mm:ss.fffffffff)

3.2.2.3.5.2. コンポーネント設定ファイルの記述例

以下の設定値を使用する場合のコンポーネント設定ファイル記述例を示す。

設定項目名 設定値
charValue a
numberValue 1
dateValue 2000-01-01 12:34:56.123456789
<!-- TestDataParser -->
<component name="testDataParser" class="nablarch.test.core.reader.BasicTestDataParser">
  <!-- データベースデフォルト値 -->
  <property name="defaultValues">
    <component class="nablarch.test.core.db.BasicDefaultValues">
      <property name="charValue" value="a"/>
      <property name="dateValue" value="2000-01-01 12:34:56.123456789"/>
      <property name="numberValue" value="1"/>
    </component>
  </property>
  <!-- 中略 -->
</component>

3.2.2.4. 注意点

3.2.2.4.1. setUpDbメソッドに関する注意点

  • Excelファイルには必ずしも全カラムを記述する必要はない。 省略されたカラムには、デフォルト値が設定される。
  • Excelファイルの1シート内に複数のテーブルを記述できる。 setUpDb(String sheetName)実行時、指定されたシート内のデータタイプ”SETUP_TABLE”全てが登録対象となる。

3.2.2.4.2. assertTableEqualsメソッドに関する注意点

  • 期待値の記述で省略されたカラムは、比較対象外となる。
  • 比較実行時、レコードの順番が異なっていても主キーを突合して正しく比較ができる。 レコードの順序を意識して期待データを作成する必要はない。
  • 1シート内に複数のテーブルを記述できる。assertTableEquals(String sheetName)実行時、指定されたシート内のデータタイプ”EXPECTED_TABLE”であるデータが全て比較される。
  • 更新日付のようなjava.sql.Timestamp型のフォーマットは”yyyy-mm-dd hh:mm:ss.fffffffff”である(fffffffffはナノ秒)。ナノ秒が設定されていない場合でも、フォーマット上は0ナノ秒として表示される。例えば、2010年1月1日12時34分56秒ジャストの場合、2010-01-01 12:34:56.0となる。Excelシートに期待値を記載する場合は、末尾の小数点+ゼロを付与しておく必要がある。

3.2.2.4.3. assertSqlResultSetEqualsメソッドに関する注意点

  • SELECT文で指定された全てのカラム名(別名)が比較対象になる。ある特定のカラムを比較対象外にすることはできない。
  • レコードの順序が異なる場合は、等価でないとみなす(アサート失敗)。 これは以下の理由による。
    • SELECTで指定されたカラムに主キーが含まれているとは限らない為。
    • SELECT実行時はORDER BY指定がなされる場合がほとんどであり、順序についても厳密に比較する必要がある為。

3.2.2.4.4. クラス単体テストにおける登録・更新系テストの注意点

  • 自動設定項目を利用してデータベースに登録・更新する際は、ThreadContextにリクエストIDとユーザIDが設定されている必要がある。テスト対象クラス起動前にこれらの値をThreadContextに設定しておくこと。 ThreadContextの設定方法については、次の項を参照。( ThreadContextにユーザID、リクエストIDなどを設定したい
  • デフォルト以外のトランザクションを使用する場合は、本フレームワークにトランザクション制御を行わせる必要がある。トランザクション制御の設定方法については、次の項を参照。( デフォルト以外のトランザクションを使用したい

3.2.2.4.5. 外部キーが設定されたテーブルにデータをセットアップしたい

マスタデータ復旧機能 と同じ機能を用いて、テーブルの親子関係を判断しデータを削除及び登録する。 詳細は 外部キーが設定されたテーブルを使用する場合について を参照。

3.2.2.4.6. Excelファイルに記述できるカラムのデータ型に関する注意点

Excelファイルには、SqlPStatement で対応している型のカラムのみ テストデータとして記述できる。

そのため、それ以外のデータ型(例えば、OracleのROWIDやPostgreSQLのOIDなど)のカラムはテストデータとして記述できない点に注意すること。