테스트 작성하기

테스트 작성하기 (Writing Tests)

출처: 문서

본문

개발과 테스트 (Development and Testing)

새 기능이 추가되면 "행복한 경로(happy path)"뿐 아니라 엣지 케이스와 잘못된 사용법까지 테스트하는 올바른 테스트가 있는 게 매우 중요해요. 이 섹션에서는 DuckDB 테스트가 어떻게 구성되는지, DuckDB용 새 테스트를 어떻게 만드는지 설명할게요.

테스트는 test 폴더에 있는 unittest 프로그램으로 실행할 수 있어요. 기본 컴파일에서는 build/release/test/unittest(release) 또는 build/debug/test/unittest(debug)에 있어요.

철학 (Philosophy)

DuckDB를 테스트할 때 우리는 모든 테스트를 SQL로 라우팅하는 것을 목표로 해요. 컴포넌트를 개별적으로 테스트하는 것은 나중에 그 컴포넌트를 바꾸기 더 어렵게 만들기 때문에 피하려고 해요. 따라서 거의 모든 테스트가 순수 SQL로 표현될 수 있고(또는 그래야 하고), 특정 예외는 Catch Tests에서 다룰게요. 하지만 대부분의 경우 테스트를 일반 SQL로 작성해야 해요.

프레임워크 (Frameworks)

SQL 테스트는 sqllogictest 프레임워크로 작성해야 해요.

C++ 테스트는 Catch 프레임워크로 작성할 수 있어요.

클라이언트 커넥터 테스트 (Client Connector Tests)

DuckDB는 다양한 클라이언트 커넥터에 대한 테스트도 있어요. 이들은 보통 해당 클라이언트 언어로 작성되며 tools/*/tests에서 찾을 수 있어요. 또한 주어진 클라이언트에서 무엇이 가능해야 하는지에 대한 문서 역할도 해요.

테스트 데이터 생성 함수 (Functions for Generating Test Data)

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);
-- 출력은 위와 같지만 내부 표현이 다름

더 알아보기 (Learn more)