开发与测试
任何新增功能都必须有正确的测试,这些测试不仅要测试“顺利路径”,还要测试边缘情况和功能的错误使用。在本节中,我们将描述DuckDB测试的结构以及如何为DuckDB创建新的测试。
可以通过运行位于test
文件夹中的unittest
程序来运行测试。对于默认的编译,这通常位于build/release/test/unittest
(发布版)或build/debug/test/unittest
(调试版)中。
哲学
在测试DuckDB时,我们的目标是通过SQL路由所有测试。我们尽量避免单独测试组件,因为这样会使这些组件在以后更难更改。因此,几乎所有的测试都可以(也应该)用纯SQL表达。有一些例外情况,我们将在Catch Tests中讨论。然而,在大多数情况下,你应该用纯SQL编写测试。
框架
SQL测试应使用sqllogictest框架编写。
C++ 测试可以使用 Catch 框架 编写。
客户端连接器测试
DuckDB 也有针对各种客户端连接器的测试。这些测试通常用相关的客户端语言编写,可以在 tools/*/tests
中找到。
它们也作为从给定客户端应该能够实现的功能的文档。
生成测试数据的函数
DuckDB 内置了生成测试数据的函数。
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
。这只会影响向量的内部表示。
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