테스트 선택 예시
테스트 선택 예시 (Test selection examples)
테스트 선택은 다른 리소스 선택과는 조금 다르게 동작해요. 테스트는 직접(direct) 또는 DAG 관계를 통한 간접(indirect) 방식으로 선택되며, 이 페이지에서는 test_type 셀렉터와 다양한 실제 예시를 보여 드릴게요.
출처: 문서
본문
테스트 선택은 다른 리소스 선택과는 조금 다르게 동작해요. 이를 통해 다음을 매우 쉽게 할 수 있어요:
- 특정 모델의 테스트 실행
- 하위 디렉터리의 모든 모델 테스트 실행
- 모델의 상·하류에 있는 모든 모델 테스트 실행 등
모든 리소스 유형과 마찬가지로 테스트는 그 속성(이름, 속성, 태그 등) 중 하나를 포착하는 메서드와 연산자로 직접 선택할 수 있어요.
다른 리소스 유형과 달리, 테스트는 DAG 안의 관계를 통해 간접적으로도 선택될 수 있어요. 선택 메서드나 연산자가 테스트가 의존하는 모델을 포함하면 dbt는 그 테스트도 선택해요. 예를 들어 dbt test --select model_b를 실행하면 model_b에 정의된 테스트뿐 아니라 model_b를 참조하는 관련 모델(예: model_a)의 테스트도 포함돼요. 이 동작 제어에 대한 자세한 내용은 Indirect selection을 참고하세요.
테스트 선택은 강력하지만 까다로울 수 있다는 걸 알고 있어요. 그래서 아래에 많은 예시를 준비했어요:
직접 선택 (Direct selection)
test_type 셀렉터를 사용해 모델 선택에 의존하지 않고 특정 범주의 테스트를 실행할 수 있어요. 이는 단위 테스트와 데이터 테스트를 분리하고 싶을 때 유용해요 — 예를 들어 개발 중 빠른 피드백을 위해 단위 테스트만 실행하거나, 단위 테스트 컴퓨팅이 필요 없는 프로덕션에서 데이터 테스트만 실행하는 경우예요. test_type 셀렉터는 모든 엔진(dbt v1 및 dbt v2)에서 동작해요.
다음 구성은 test_type 셀렉터와 함께 사용해 일치하는 테스트 노드를 실행하지 않고 컴파일할 수 있어요. 명령 동작에 대해서는 About dbt compile command를 참고하세요.
모델을 materialize하기 전에 SQL 로직을 검증하기 위해 개발 또는 CI에서 단위 테스트만 실행:
dbt test --select "test_type:unit"
모든 데이터 테스트(generic과 singular 모두) 실행 — 예를 들어 프로덕션 파이프라인에서 단위 테스트를 완전히 건너뛰려면:
dbt test --select "test_type:data"
generic 데이터 테스트만 실행 — .yml 파일에 정의된 스키마 레벨 단언(예: not_null, unique)만 실행하고 사용자 지정 SQL 테스트 파일은 실행하지 않으려면:
dbt test --select "test_type:generic"
singular 데이터 테스트만 실행 — generic 스키마 테스트를 실행하지 않고 tests/ 디렉터리의 사용자 지정 SQL 테스트 파일만 실행하려면:
dbt test --select "test_type:singular"
모든 경우에 test_type은 테스트 자체의 속성을 검사해요 — 이는 "직접" 테스트 선택의 한 형태예요.
간접 선택 (Indirect selection)
간접 선택 모드는 선택한 모델과 DAG 안의 관계를 기준으로 어떤 테스트가 실행될지 제어해요. 이 모드들은 선택한 모델을 직접 또는 상·하류 관계를 통해 참조하는 테스트를 dbt가 어떻게 처리할지 결정해요.
다음 모드를 사용할 수 있어요(eager가 기본값). 테스트 제외는 항상 탐욕적이에요: 부모 중 ANY 하나라도 명시적으로 제외되면 테스트도 함께 제외돼요.
DAG의 하위 집합 빌드하기 — buildable과 cautious 모드는 DAG의 일부만 빌드할 때 유용해요. eager 모드에서 빌드되지 않은 리소스 때문에 테스트가 실패하는 것을 피하고 싶다면요. 이는 deferral로도 달성할 수 있어요.
Eager mode (기본값) — 가장 포괄적이며, 모든 의존성이 충족되지 않더라도 부모 노드 중 하나라도 선택되면 테스트를 실행해요. 선택한 노드를 참조하는 테스트는 다른 선택되지 않은 노드도 참조하더라도 모두 포함돼요. 예를 들어 dbt test --select model_b를 실행하면 eager 모드는:
- model_b에 직접 붙은 테스트
- model_b를 참조하는 업스트림 모델(예: model_a)의 테스트
- model_b를 참조하는 다운스트림 모델의 테스트
를 실행해요. dbt는 선택한 모델에 의존하는 모델을 빌드해요. 이 모드에서는 빌드되지 않은 리소스에 의존하는 테스트가 오류를 발생시켜요.
Buildable mode — cautious와 eager 사이의 중간 지점으로, 선택한 노드(또는 그 조상)를 참조하는 테스트만 실행해요. 각 참조가 선택한 노드(또는 그 조상) 안에 있는 테스트를 포함하기 때문에 cautious보다 약간 더 포괄적이에요. 이 모드는 테스트가 모델과 그 모델의 직접 조상에 의존할 때, 예를 들어 집계 결과가 입력과 같은 총계인지 확인할 때 유용해요.
Cautious mode — 가장 배타적인 모드로, 선택한 모델의 모든 필수 의존성이 충족될 때만 테스트를 실행하고 모델을 빌드해요. 선택한 노드만 독점적으로 참조하는 테스트로 제한해요. 테스트가 의존하는 노드가 모두 선택된 경우에만 실행되므로, 부모 노드 중 하나라도 선택되지 않아(따라서 빌드되지 않아) 테스트가 실행되지 않는 것을 방지해요.
Empty mode — 테스트를 실행하지 않고 선택한 노드만 빌드하도록 제한하며 모든 간접 의존성을 무시해요. 선택한 노드에 직접 붙은 테스트든 아니든 어떤 테스트도 실행하지 않아요. empty 모드는 대화형 컴파일에서 자동으로 사용돼요.
간접 선택 예시 (Indirect selection examples)
이 메서드들을 시각화하기 위해 model_a, model_b, model_c와 연관된 데이터 테스트가 있다고 가정해 봐요. 다음은 dbt build를 다양한 간접 선택 모드로 실행할 때 어떤 테스트가 실행될지 보여줘요.
- Eager (default) — 가장 포괄적
- Buildable — 중간 지점
- Cautious — 가장 배타적
- Empty — 테스트 없음
이 예시에서 빌드 과정 중 선택된 "orders" 모델이나 그 의존 모델에 의존하는 모든 테스트는 다른 모델에도 의존하더라도 실행돼요.
dbt test --select "orders"
dbt build --select "orders"
이 예시에서 dbt는 선택된 노드(또는 그 조상) 안에서 "orders"를 참조하는 테스트를 실행해요.
dbt test --select "orders" --indirect-selection=buildable
dbt build --select "orders" --indirect-selection=buildable
이 예시에서는 "orders" 모델에만 독점적으로 의존하는 테스트만 실행돼요:
dbt test --select "orders" --indirect-selection=cautious
dbt build --select "orders" --indirect-selection=cautious
이 모드는 선택한 노드에 직접 붙은 테스트든 아니든 어떤 테스트도 실행하지 않아요.
dbt test --select "orders" --indirect-selection=empty
dbt build --select "orders" --indirect-selection=empty
테스트 선택 문법 예시 (Test selection syntax examples)
indirect_selection 설정은 yaml 셀렉터에서도 지정할 수 있어요.
다음 예시들은 별도 모드(예: --indirect-selection=cautious)를 지정하지 않는 한 간접 선택에 기본적으로 eager 모드를 사용해요.
선택 연산자(+, 태그 등)는 어떤 모델이 선택될지 결정하고, 간접 선택 모드는 그 모델들에 대해 어떤 테스트가 실행될지 결정해요.
# Run tests on a model (indirect selection)
dbt test --select "customers"
# Run tests on two or more specific models (indirect selection)
dbt test --select "customers orders"
# Run tests on all models in the models/staging/jaffle_shop directory (indirect selection)
dbt test --select "staging.jaffle_shop"
# Run tests downstream of a model (note this will select those tests directly!)
dbt test --select "stg_customers+"
# Run tests upstream of a model (indirect selection)
dbt test --select "+stg_customers"
# Run tests on all models with a particular tag (direct + indirect)
dbt test --select "tag:my_model_tag"
# Run tests on all models with a particular materialization (indirect selection)
dbt test --select "config.materialized:table"
# To change the indirect selection mode, add the flag:
dbt test --select "customers" --indirect-selection=cautious
같은 원리를 다른 리소스 유형에 정의된 테스트로 확장할 수 있어요. 이 경우 source: 선택 메서드를 통해 특정 소스에 정의된 모든 테스트를 실행해요:
# tests on all sources
dbt test --select "source:*"
# tests on one source
dbt test --select "source:jaffle_shop"
# tests on two or more specific sources
dbt test --select "source:jaffle_shop source:raffle_bakery"
# tests on one source table
dbt test --select "source:jaffle_shop.customers"
# tests on everything _except_ sources
dbt test --exclude "source:*"
더 복잡한 선택 (More complex selection)
직접 선택과 간접 선택의 조합을 통해 같은 결과를 달성하는 방법은 여러 가지가 있어요. payments라는 모델에 의존하는 assert_total_payment_amount_is_positive라는 데이터 테스트가 있다고 가정해 봐요. 다음 모두 해당 테스트를 정확하게 선택하고 실행할 수 있어요:
dbt test --select "assert_total_payment_amount_is_positive" # directly select the test by name
dbt test --select "payments,test_type:singular" # indirect selection, v1.2
리소스 그룹의 공통 속성을 선택할 수 있으면 간접 선택으로 그 리소스들의 모든 테스트도 실행할 수 있어요. 위 예시에서 모든 table materialize된 모델을 테스트할 수 있다는 것을 봤어요. 이 원리는 다른 리소스 유형에도 확장할 수 있어요:
# Run tests on all models with a particular materialization
dbt test --select "config.materialized:table"
# Run tests on all seeds, which use the 'seed' materialization
dbt test --select "config.materialized:seed"
# Run tests on all snapshots, which use the 'snapshot' materialization
dbt test --select "config.materialized:snapshot"
이 기능은 dbt의 향후 버전에서 변경될 수 있음을 참고하세요.
태그된 컬럼의 테스트 실행 (Run tests on tagged columns)
컬럼 order_id에 my_column_tag가 태그되어 있으므로 테스트 자체도 my_column_tag 태그를 받아요. 그 때문에 이는 직접 선택의 예시예요.
models/
models:
- name: orders
columns:
- name: order_id
config:
tags: [my_column_tag] # changed to config in v1.10 and backported to 1.9
data_tests:
- unique
dbt test --select "tag:my_column_tag"
현재 테스트는 컬럼, 소스, 소스 테이블에 적용된 태그를 "상속"해요. 모델, 시드, 스냅샷에 적용된 태그는 상속하지 않아요. 그런 테스트들은 태그가 부모를 선택하기 때문에 대부분 여전히 간접적으로 선택될 거예요. 이는 미묘한 차이이며, dbt의 향후 버전에서 변경될 수 있어요.
태그된 테스트만 실행 (Run tagged tests only)
이것은 직접 선택의 더 명확한 예시예요. 테스트 자체가 my_test_tag로 태그되어 있고 그에 따라 선택돼요.
models/
models:
- name: orders
columns:
- name: order_id
data_tests:
- unique:
config:
tags: [my_test_tag] # changed to config in v1.10
dbt test --select "tag:my_test_tag"
더 알아보기 (Learn more)
- Indirect selection — 간접 선택 구성
- Node selection syntax — 선택 문법 개요