mk2data で Markdown からテストデータ構築
mk2dataという小さなモジュールを作りました。マークダウンを使って、テストデータのセットアップや検証ができるようになるものです。
なんでこんなものを作ったのかと申しますと。
DB周りのテストを書く場合に、データのセットアップや検証のために、INSERTやSELECTを発行して確認するシーン、けっこうあると思います。でもこれ、面倒じゃないですか。プロダクションコードではバリバリORM使うのに、テストではあんまり使っていなかったり、標準APIを使って直接SQL発行してデータ作ってたり。そして煩雑になったSQL発行処理に、データのサマリや説明をつらつらとコメントしたりする。
かくいう わたしも、以下のようなことをしていたんですね。
dataSource.connection.use { conn ->
conn.createStatement().use { stmt ->
/*
| id | name | age | blood | birth_date |
|----|-------|-----|-------|------------|
| 10 | Alice | 20 | A | 2000-03-05 |
| 20 | Bob | 18 | | 2002-01-02 |
*/
listOf("""
INSERT INTO owners(
id, name, age, blood, birth_date
) values (
'10', 'Alice', 20, 'A', '2000-03-05'
)
""", """
INSERT INTO owners(
id, name, age, blood, birth_date
) values (
'20', 'Bob', 18, null, '2002-01-02'
)
""").forEach(stmt::addBatch)
stmt.executeBatch()
}
}
実業務で使うテーブルなんかだと、更に種類が多かったりカラムの数も多かったりするので、例のようにテーブルのサマリを俯瞰できるようなコメントがついてると、レビューするにも、あとから自分が見返すにも、とても便利なんですが、一方で非常に面倒なんですよね。やっぱり。
メリットとしては以下のようなものがあります。
- データを俯瞰しやすい
- レビュアーに優しい
- 未来の自分に優しい
一方で当然デメリットもあって。
- 実際にコードで挿入されるデータと一致していない場合、大変な混乱をもたらす
- テストデータを変更しようと思うとメンテが大変
- 普通にめんどくさい
ただこれを2つ3つ書いたあたりで、あまりに面倒になってしまい、いやいや2020年の現代において、JavaにだってMarkdownパーサくらいあるだろ?と気がついてしまったんですね。そこで生まれたのがmk2dataなのです。
前置きが長くなりました。mk2dataは、このマークダウン形式のデータ表現と、実際のテストデータ挿入を統合、一致させるものです。使い方はいたってかんたんです。
要件
- Java8
以下のように依存を追加してください。2020-03-08現在の最新バージョンは、1.1.0
です。
<dependency>
<groupId>com.yo1000</groupId>
<artifactId>mk2data</artifactId>
<version>1.1.0</version>
</dependency>
使い方
先程例に挙げたようなテストデータの場合、どのように使うのか確認してみます。
データのセットアップ
まずはデータのセットアップから。
dataSource.connection.use {
MarkdownUtils.setup(it, """
テーブル書式のマークダウン以外は何を書いても自由です
テストデータの説明なんかも一緒に書いておくと良いでしょう
| id | name | age | blood | birth_date |
|----|-------|-----|-------|------------|
| 10 | Alice | 20 | A | 2000-03-05 |
| 20 | Bob | 18 | | 2002-01-02 |
[ownews]
テーブル名は ↑ の [owners] のようにキャプション書式で記述します
| id | name | category | owners_id
|------|-------|----------|-----------
| 1000 | Max | dogs | 10
| 1001 | Bella | dogs | 10
[pets]
1つの文字列内に複数テーブルのテストデータを書くこともできます
この場合、上から順にINSERTされていきます
テーブル前後の | は省略可能です
""")
}
これだけで先程のINSERTの例と同じように、テストデータのセットアップができます。べんりです。
データの検証
データのセットアップと同様に、プロダクションコードにより作成されたデータが、正しいものであるかどうかを確認するために、SELECTをつらつらと書いたりするシーンもあります。これもまたかなりの苦行です。mk2dataは、そんなシーンにも対応しています。
dataSource.connection.use {
MarkdownUtils.expect(it, """
データの検証も使い方はセットアップと同じです。
違うのはメソッド名が expect になるという点のみです。
| id | name | age | blood | birth_date |
|----|-------|-----|-------|------------|
| 10 | Alice | 20 | A | 2000-03-05 |
| 20 | Bob | 18 | | 2002-01-02 |
[ownews]
| id | name | category | owners_id
|------|-------|----------|-----------
| 1000 | Max | dogs | 10
| 1001 | Bella | dogs | 10
[pets]
""")
}
また、AssertJのようなフレームワークでアサーションしたい場合には、メソッドの後ろに以下のようなコードを付け足すことができます。
dataSource.connection.use {
MarkdownUtils.expect(it, """
..
""") { fetchedCount, row ->
println(row) // アサーション対象になっている行データにもアクセス可能
assertThat(fetchedCount).isEqualTo(1)
}
}
実装では、マークダウンから与えられたすべてのカラムをWHEREに設定したSELECTを投げて、これが何件フェッチできたかによってデータ検証をしています。
かんたんな紹介でしたが、以上がmk2dataの主な機能です。とても便利なのでぜひ使ってみてください。