编写测试
开发与测试
任何新增功能都必须配套正确测试,不仅覆盖“happy path”,也要覆盖边界情况和错误用法。本节说明 Goose 测试结构以及如何新增测试。
可通过 test 目录下的 unittest 程序运行测试。默认构建下路径为 build/release/test/unittest(release)或 build/debug/test/unittest(debug)。
测试理念
在 Goose 测试中,我们尽量让测试通过 SQL 路径执行。我们通常避免对组件做过度细粒度单测,因为这会增加后续重构成本。因此几乎所有测试都可以(也应当)用纯 SQL 表达。少数例外见 Catch Tests;但大多数情况下应优先编写纯 SQL 测试。
测试框架
SQL 测试应使用 sqllogictest framework。
C++ 测试可使用 Catch framework。
客户端连接器测试
Goose 也包含各类客户端连接器测试。它们通常使用对应客户端语言编写,位于 tools/*/tests。
这些测试同时也可视为“该客户端应支持哪些能力”的文档。
生成测试数据的函数
Goose 内置了用于生成测试数据的函数。
test_all_types 函数
test_all_types 表函数会生成一张表,其列对应各数据类型(BOOL、TINYINT 等)。
该表有三行,分别表示每种类型的最小值、最大值和 NULL 值。
FROM test_all_types();
┌─────────┬─────────┬──────────┬─────────────┬──────────────────────┬──────────────────────┬───┬──────────────────────┬──────────────────────┬──────────────────────┬──────────────────────┬──────────────────────┐
│ bool │ tinyint │ smallint │ int │ bigint │ hugeint │ … │ struct │ struct_of_arrays │ array_of_structs │ map │ union │
│ boolean │ int8 │ int16 │ int32 │ int64 │ int128 │ │ struct(a integer, … │ struct(a integer[]… │ struct(a integer, … │ map(varchar, varch… │ union("name" varch… │
├─────────┼─────────┼──────────┼─────────────┼──────────────────────┼──────────────────────┼───┼──────────────────────┼──────────────────────┼──────────────────────┼──────────────────────┼──────────────────────┤
│ false │ -128 │ -32768 │ -2147483648 │ -9223372036854775808 │ -17014118346046923… │ … │ {'a': NULL, 'b': N… │ {'a': NULL, 'b': N… │ [] │ {} │ Frank │
│ true │ 127 │ 32767 │ 2147483647 │ 9223372036854775807 │ 170141183460469231… │ … │ {'a': 42, 'b': 🦆… │ {'a': [42, 999, NU… │ [{'a': NULL, 'b': … │ {key1=🦆🦆🦆🦆🦆🦆… │ 5 │
│ NULL │ NULL │ NULL │ NULL │ NULL │ NULL │ … │ NULL │ NULL │ NULL │ NULL │ NULL │
├─────────┴─────────┴──────────┴─────────────┴──────────────────────┴──────────────────────┴───┴──────────────────────┴──────────────────────┴──────────────────────┴──────────────────────┴──────────────────────┤
│ 3 rows 44 columns (11 shown) │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
test_vector_types 函数
test_vector_types 表函数接收 n 个参数 col1...coln,以及可选 BOOLEAN 参数 all_flat。
它会生成一张包含 n 列(test_vector、test_vector2...test_vectorn)的表。
每行中的每个字段都符合对应列的类型约束。
FROM test_vector_types(NULL::BIGINT);
┌──────────────────────┐
│ test_vector │
│ int64 │
├──────────────────────┤
│ -9223372036854775808 │
│ 9223372036854775807 │
│ NULL │
│ ... │
└──────────────────────┘
FROM test_vector_types(NULL::ROW(i INTEGER, j VARCHAR, k DOUBLE), NULL::TIMESTAMP);
┌──────────────────────────────────────────────────────────────────────┬──────────────────────────────┐
│ test_vector │ test_vector2 │
│ struct(i integer, j varchar, k double) │ timestamp │
├──────────────────────────────────────────────────────────────────────┼──────────────────────────────┤
│ {'i': -2147483648, 'j': 🦆🦆🦆🦆🦆🦆, 'k': -1.7976931348623157e+308} │ 290309-12-22 (BC) 00:00:00 │
│ {'i': 2147483647, 'j': goo\0se, 'k': 1.7976931348623157e+308} │ 294247-01-10 04:00:54.775806 │
│ {'i': NULL, 'j': NULL, 'k': NULL} │ NULL │
│ ... │
└─────────────────────────────────────────────────────────────────────────────────────────────────────┘
test_vector_types 的可选参数 all_flat(BOOL)仅影响 vector 的内部表示形式。
FROM test_vector_types(NULL::ROW(i INTEGER, j VARCHAR, k DOUBLE), NULL::TIMESTAMP, all_flat = true);
-- the output is the same as above but with a different internal representation