はじめに
Dataform には unit test を記述出来ます。
ただし、テストに用いるデータは SQL で書く必要があり冗長なものになりがちです。
Dataform は JavaScript を記述、読込みできるので wrapper を書きました。
Dataform の Unit test について
Dataform の Unit test はこのように記述できます。
example_originals
table からデータを参照する example.sqlx
があったとします。
config {
type: "view",
name: "example_tables"
}
SELECT
id,
title
FROM
${ref("example_originals")}
この example.sqlx
に対する Unit test を用意すると以下のようになります。
config {
type: "test",
dataset: "example_tables"
}
SELECT
1 AS id,
"title1" AS title
UNION ALL
SELECT
2 AS id,
"title2" AS title
UNION ALL
SELECT
3 AS id,
"title3" AS title
input "example_originals" {
SELECT
1 AS id,
"title1" AS title
UNION ALL
SELECT
2 AS id,
"title2" AS title
UNION ALL
SELECT
3 AS id,
"title3" AS title
}
test データを用意したいだけですが、 UNION ALL
を何度も記載する必要があります。
面倒ですし、可読性も悪い状態になってしまいます。
苦し紛れではありますが、JavaScript を用いて UNION ALL
のラッパー関数を作成しました。
JavaScript の wrapper を書いた
Dataform は includes
以下の ディレクトリに JavaScript ファイルを置くことで、
SQLX 内から JavaScript に記載した処理を呼び出すことができます。
作成した JavaScript はこちらです。
渡されたデータを UNION ALL
で join
するだけの簡単な処理です。
エスケープ処理等いくつか省略しています。
function build(data) {
if (data.length === 0) {
return "";
}
const keys = Object.keys(data[0]);
return data.map((item) => {
const values = keys.map((key) => {
if (typeof item[key] !== "string") {
return `${item[key]} AS ${key}`;
}
return `'${item[key]}' AS ${key}`;
});
return `SELECT ${values.join(", ")}`;
}).join(" UNION ALL ");
}
module.exports = {
build,
};
SQLX ファイルから処理を呼び出す場合は以下のように記載します。
${
sql.build([
{ id: 1, title: "title1" },
{ id: 2, title: "title2" }
])
}
すると以下のような SQL に変換します。
SELECT
1 as id,
"title1" as title
UNION ALL
SELECT
2 as id,
"title2" as title
最後に
今回記事を書くために記載したテストデータの件数は3件程でした。
Dataform で処理するデータ次第ですが、テストデータの件数はもっと多くなるはず。
ちょっとした JavaScript を書くだけで、すこしメンテナンスしやすなります。
いい塩梅が求められる部分なので、やり過ぎは禁物です。
References