トラブルシューティング
DB Tester使用時の一般的な問題に対する実践的な解決策を提供します。 例外の仕様についてはエラーハンドリングを参照してください。
クイック診断
以下のチェックリストで問題のカテゴリを特定してください。
| 症状 | カテゴリ | ジャンプ先 |
|---|---|---|
| "Dataset directory not found" | データ読み込み | DataSetLoadException |
| "File is empty" またはパースエラー | データ読み込み | DataSetLoadException |
| "Table name conflict detected in AUTO format mode" | データ読み込み | DataSetLoadException |
| "Assertion failed: N differences" | 検証 | ValidationException |
| "No default data source registered" | 設定 | DataSource の問題 |
| テストの実行が遅い | パフォーマンス | パフォーマンス最適化 |
| 予期しないテスト失敗 | よくあるミス | よくあるミス |
DataSetLoadException
クラスパス上にディレクトリが見つからない
症状:
Dataset directory not found on classpath: 'com/example/UserRepositoryTest'
Expected location: src/test/resources/com/example/UserRepositoryTest診断:
src/test/resources/{パッケージ}/{テストクラス名}/にディレクトリが存在するか確認- パッケージパスがスラッシュ区切りになっているか確認
- テストクラス名が完全に一致しているか確認(大文字小文字を区別)
解決策:
# ディレクトリ構造を作成
mkdir -p src/test/resources/com/example/UserRepositoryTest規約
ディレクトリパスはデフォルトで {パッケージ}/{テストクラス名}/ に従います。 カスタマイズするには、設定で baseDirectory を構成してください。
サポートされるファイルが見つからない
症状:
Dataset directory exists but contains no supported data files: '/path/to/datasets'
Supported file extensions: [.csv, .tsv, .json, .yaml]
Hint: Add at least one data file (for example, TABLE_NAME.csv)...
Found files: [README.txt, notes.md]Found files行はディレクトリ内の全ファイルを列挙し、問題の診断に役立ちます。ディレクトリが空の場合、この行は省略されます。
診断:
Found filesリストで拡張子が正しくないファイルを確認- ファイル拡張子が設定された
dataFormatと一致しているか確認 - ファイルが隠しファイルでないか確認(
.プレフィックスなし)、正しいディレクトリ階層にあるか確認
解決策:
| dataFormat 設定 | 期待される拡張子 |
|---|---|
DataFormat.AUTO(デフォルト) | .csv、.tsv、.json、.yaml |
DataFormat.CSV | .csv |
DataFormat.TSV | .tsv |
DataFormat.JSON | .json |
DataFormat.YAML | .yaml |
ファイル形式の詳細はデータフォーマットを参照してください。
空のファイルエラー
症状:
File is empty: /path/to/USERS.csv解決策: 少なくともヘッダー行と1つのデータ行を追加してください。
ID,NAME,EMAIL
1,Alice,alice@example.comパース失敗
症状:
Failed to parse file: /path/to/USERS.csv診断:
- エスケープされていない特殊文字(カンマ、クォート)がないか確認
- 全行でカラム数が一致しているか確認
- ファイルエンコーディングを確認(UTF-8 推奨)
解決策:
- 値内のカンマをエスケープ:
"value, with comma" - クォートをエスケープ:
"value ""with quotes""" - データに多くのカンマが含まれる場合は TSV 形式を使用
AUTOモードでのテーブル名競合
症状:
Table name conflict detected in AUTO format mode.
The following table names are defined in multiple files with different formats:
Table 'USERS':
- USERS.csv
- USERS.yaml
Each table name must be unique across all file formats in a directory.
To resolve, remove duplicate files or specify a concrete format:
DataFormat.CSV, DataFormat.TSV, DataFormat.JSON, or DataFormat.YAML診断: DataFormat.AUTO(デフォルト)を使用すると、フレームワークはデータセットディレクトリから全サポート形式のファイルを読み込みます。同一テーブル名が異なる拡張子のファイルに存在する場合、使用すべきファイルを判断できません。
解決策:
| 方法 | 対応 |
|---|---|
| 重複ファイルを削除 | テーブル名ごとに1つのファイルのみ残す(例: USERS.csv が存在する場合 USERS.yaml を削除) |
| 特定の形式を指定 | ConventionSettings で DataFormat.CSV、DataFormat.TSV、DataFormat.JSON、または DataFormat.YAML を設定 |
// 方法 1: データセットディレクトリから重複ファイルを削除
// 方法 2: 特定の形式を指定
var conventions = ConventionSettings.builder()
.dataFormat(DataFormat.CSV)
.build();データフォーマット - 自動フォーマット検出の詳細を参照。
読み込み順序ファイルエラー
症状:
Failed to read load order file: /path/to/load-order.txt診断: TableOrderingStrategy.LOAD_ORDER_FILE を使用する場合、 load-order.txt ファイルが必須です。
解決策: データセットディレクトリに load-order.txt を作成:
PARENT_TABLE
CHILD_TABLE
GRANDCHILD_TABLE詳細はデータフォーマット - 読み込み順序を参照。
ValidationException
YAML 出力の理解
検証が失敗すると、DB Testerは構造化されたYAMLを出力します。
Assertion failed: 2 differences in USERS
summary:
status: FAILED
total_differences: 2
tables:
USERS:
differences:
- path: row_count
expected: 3
actual: 2
- path: "row[0].EMAIL"
expected: john@example.com
actual: jane@example.com行数の不一致
症状:
- path: row_count
expected: 3
actual: 2診断:
[Scenario]カラムのフィルタリングを確認- CSV にすべての期待行が含まれているか確認
- テストロジックが予期せず行を削除していないか確認
解決策:
| 原因 | 対応 |
|---|---|
[Scenario] 値の欠落 | [Scenario] カラムにテストメソッド名を追加 |
| シナリオ名の誤り | テストメソッド名と完全に一致させる |
| 余分な行がフィルタされた | [Scenario] カラムを削除してすべての行を読み込む |
セル値の不一致
症状:
- path: "row[0].EMAIL"
expected: john@example.com
actual: jane@example.com診断:
- 期待 CSV を実際のデータベース状態と比較
- テストロジックが値を更新していないか確認
- 行の順序が一致しているか確認
解決策:
| 原因 | 対応 |
|---|---|
| 行順序が異なる | rowOrdering = RowOrdering.UNORDERED を使用 |
| タイムスタンプ精度 | 日付カラムの比較戦略を確認 |
| 浮動小数点 | イプシロン(1e-6)内の値は自動的に一致 |
excludeColumns と columnStrategies の使用
優先順位ルール: excludeColumnsがcolumnStrategiesより優先されます。
@ExpectedDataSet(sources = @DataSetSource(
excludeColumns = {"CREATED_AT"}, // 最初に除外される
columnStrategies = {
@ColumnStrategy(name = "UPDATED_AT", strategy = Strategy.IGNORE)
}
))この例では、CREATED_ATは完全に除外されます。 UPDATED_ATはIGNORE戦略で比較されます。
アノテーションの詳細はパブリックAPIを参照してください。
DataSource の問題
デフォルト DataSource が登録されていない
症状:
No default data source registered診断:
@BeforeAllメソッドのシグネチャにExtensionContextが含まれているか確認registerDefault()が呼び出されているか確認- 登録中に例外が発生していないか確認
解決策:
@BeforeAll
static void setUp(ExtensionContext context) throws SQLException {
var dataSource = new JdbcDataSource();
dataSource.setURL("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1");
DatabaseTestExtension.getRegistry(context).registerDefault(dataSource);
}def setupSpec() {
def dataSource = new JdbcDataSource()
dataSource.setURL("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1")
dbTesterRegistry.registerDefault(dataSource)
}override val dbTesterRegistry = DataSourceRegistry()
@BeforeAll
fun setup() {
val dataSource = JdbcDataSource().apply {
setURL("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1")
}
dbTesterRegistry.registerDefault(dataSource)
}名前付き DataSource が見つからない
症状:
No data source registered for name: secondary_db解決策: 名前付き DataSource を登録:
registry.register("secondary_db", secondaryDataSource);アノテーションで参照:
@DataSet(sources = @DataSetSource(dataSourceName = "secondary_db"))パフォーマンス最適化
大規模データセットの最適化
症状: 行数が多いテストの実行が遅い。
解決策:
| 最適化 | 影響 | 方法 |
|---|---|---|
RowOrdering.ORDERED を使用 | 最速の比較(O(n)) | @ExpectedDataSet で設定 |
TRUNCATE_INSERT を使用 | CLEAN_INSERT より高速 | @DataSet で設定 |
load-order.txt を作成 | メタデータ探索をスキップ | データセットディレクトリにファイル追加 |
| データセットサイズを削減 | 処理行数が減少 | [Scenario] フィルタリングを使用 |
RowOrdering のパフォーマンス
RowOrdering.UNORDERED は最悪の場合 O(n*m) の比較を行います。 行順序が予測可能な場合は ORDERED を使用してください。
データベース操作で操作の詳細を参照。
コネクションプール設定
症状: 接続タイムアウトまたはプール枯渇。
注意: コネクションプールはDB Testerの外部依存です。 使用中のコネクションプール(HikariCP、c3p0など)を設定してください。
推奨事項:
- 並列テスト実行に対応する
maximumPoolSizeを設定 - 遅いデータベース接続に対応する
connectionTimeoutを設定 - H2インメモリデータベースには
DB_CLOSE_DELAY=-1を使用
メモリ管理
症状: 大規模データセットでOutOfMemoryError。
解決策:
- 大きなCSVをシナリオごとに小さなファイルに分割
[Scenario]カラムで関連する行のみを読み込む- テスト用のJVMヒープサイズを増加:
-Xmx512m
よくあるミス
クラスパス配置エラー
ミス: データセットファイルをsrc/test/resourcesの外に配置。
正しいディレクトリ構造:
src/test/resources/
└── com/example/UserRepositoryTest/
├── USERS.csv
└── expected/
└── USERS.csvシナリオカラム名の不一致
ミス: 設定と異なるシナリオマーカーを使用。
デフォルト: [Scenario]カラム
カスタム設定:
Configuration.builder()
.conventions(ConventionSettings.builder()
.scenarioMarker("[TestCase]") // カスタムマーカー
.build())
.build();拡張子の不一致
ミス: 特定のDataFormatを設定しているのに、サポートされない拡張子のファイルを使用。
DataFormat.AUTO(デフォルト)ではすべてのサポート拡張子(.csv、.tsv、.json、.yaml)を受け付けます。特定の形式を設定した場合、一致する拡張子のファイルのみが読み込まれます。
解決策: DataFormat.AUTO(デフォルト)を使用してすべてのサポート形式を読み込むか、一致する形式を設定します。
ConventionSettings.builder()
.dataFormat(DataFormat.TSV)
.build();または、ファイルの拡張子を設定された形式に合わせてリネームします。
期待値サフィックスの不一致
ミス: 期待ファイルが expected/ サブディレクトリにない。
デフォルト: 期待データセットには expected/ サフィックス。
カスタム設定:
ConventionSettings.builder()
.expectationSuffix("verify/") // カスタムサフィックス
.build();設定ですべての設定を参照。
テーブル名の大文字小文字
ミス: CSVファイル名の大文字小文字がテーブル名と一致しない。
例:
- テーブルは
USERSとして作成(H2は大文字) - CSVは
users.csv(小文字)
解決策: データベーステーブル名の大文字小文字に一致させます。 H2は引用符なしの識別子を大文字に変換します。
外部キー順序
ミス: 親レコードより先に子レコードを挿入。
解決策: データセットディレクトリに load-order.txt を作成:
PARENT
CHILD
GRANDCHILDテーブル順序戦略を設定します。
@DataSet(tableOrdering = TableOrderingStrategy.LOAD_ORDER_FILE)デバッグワークフロー
ステップ 1: DEBUG ロギングを有効化
# application.properties または logback.xml
logging.level.io.github.seijikohara.dbtester=DEBUGステップ 2: データセット読み込みを確認
DEBUG出力には以下が表示されます。
- 読み込まれているファイル
- テーブル順序の決定
- シナリオによる行フィルタリング
ステップ 3: データベース状態を確認
@DataSet準備後にデータベースを直接クエリします。
@Test
@DataSet
void debugTest() throws SQLException {
try (var conn = dataSource.getConnection();
var stmt = conn.createStatement();
var rs = stmt.executeQuery("SELECT * FROM USERS")) {
while (rs.next()) {
System.out.println(rs.getString("NAME"));
}
}
}ステップ 4: 期待値と実際の値を比較
検証が失敗した場合、YAML出力は正確な差異を示します。 この出力から、問題が以下のどこにあるかを特定します。
- 期待データ(CSV)
- テストロジック
- データベース状態