开源软件DBT中文社区
微信号:DBT_CN
QQ群:551308350

增强模型:测试
-
概述
测试是您对 dbt 项目中的模型和其他资源(例如源、种子和快照)所做的断言。当你运行时,dbt 会告诉你项目中的每个测试是通过还是失败。dbt test您可以使用测试通过对生成的结果进行断言来提高每个模型中 SQL 的完整性。开箱即用,您可以测试模型中的指定列是否仅包含非 null 值、唯一值或在其他模型中具有相应值的值(例如,a for a 对应于模型中的 a)以及指定列表中的值。您可以扩展测试以适应特定于您的组织的业务逻辑 - 您可以以选择查询的形式对模型做出的任何断言都可以转换为测试。customer_idorderidcustomers
更新日志
像 dbt 中的几乎所有内容一样,测试是 SQL 查询。特别是,它们是试图抓住“失败”记录的陈述,这些陈述反驳了你的断言。如果断言列在模型中是唯一的,则测试查询会选择重复项;如果断言列从不为 null,则测试将查找 null。如果测试返回零个失败行,则测试通过,并且您的断言已经过验证。select在 dbt 中定义测试有两种方法:
-
单一测试以最简单的形式进行测试:如果可以编写返回失败行的 SQL 查询,则可以将该查询保存在测试目录中的文件中。它现在是一个测试,它将由命令执行。.sqldbt test
-
通用测试是接受参数的参数化查询。测试查询在特殊块(如宏)中定义。定义后,您可以在整个文件中按名称引用通用测试 - 在模型、列、源、快照和种子上定义它。DBT 内置了四个通用测试,我们认为您应该使用它们!test.yml
定义测试是确认代码是否正常工作的好方法,有助于防止代码更改时出现回归。因为您可以一遍又一遍地使用它们,以微小的变化做出类似的断言,所以通用测试往往更常见——它们应该构成 dbt 测试套件的大部分。也就是说,定义测试的两种方式都有其时间和地点。
单一测试
定义测试的最简单方法是编写将返回失败记录的确切 SQL。我们称这些为“单一”测试,因为它们是可用于单一目的的一次性断言。这些测试在文件中定义,通常在目录中(由测试路径配置定义)。您可以在测试定义中使用 Jinja(包括和),就像创建模型时一样。每个文件包含一个语句,它定义一个测试:.sql tests ref source .sql select
tests/assert_total_payment_amount_is_positive.sql
-- Refunds have a negative amount, so the total amount should always be >= 0.
-- Therefore return records where this isn't true to make the test fail
select
order_id,
sum(amount) as total_amount
from {{ ref('fct_payments' )}}
group by 1
having not(total_amount >= 0)此测试的名称是文件的名称:。足够简单。assert_total_payment_amount_is_positive
单一测试很容易编写 — 如此简单,以至于您可能会发现自己一遍又一遍地编写相同的基本结构,只是更改列或模型的名称。到那时,测试就不是那么单一了!在这种情况下,我们建议...
通用测试
某些测试是通用的:它们可以一遍又一遍地重复使用。一般测试在块中定义,该块包含参数化查询并接受参数。它可能看起来像:test{% test not_null(model, column_name) %}
select * from {{ model }} where {{ column_name }} is null
{% endtest %}
您会注意到有两个参数,和 ,然后模板化到查询中。这就是使测试“通用”的原因:它可以在任意数量的列上定义,跨任意数量的模型定义,dbt 将相应地传递 和 的值。定义通用测试后,可以将其添加为任何现有模型(或源、种子或快照)的属性。这些属性将添加到与资源位于同一目录中的文件中。
开箱即用,dbt 附带了四个已定义的通用测试:、 和 。下面是在模型上使用这些测试的完整示例:version: 2models:
- name: orders
columns:- name: order_id
tests:- unique
- not_null
- name: status
tests:- accepted_values:
values: ['placed', 'shipped', 'completed', 'returned']
- accepted_values:
- name: customer_id
tests:- relationships:
to: ref('customers')
field: id
- relationships:
- name: order_id
用简单的英语来说,这些测试翻译为:
unique:模型中的列应该是唯一的order_idorders
not_null:模型中的列不应包含空值order_idorders
accepted_values:中的列应该是 、 、 或 中的列之一statusorders'placed''shipped''completed''returned'
relationships:模型中的每个都作为customer_idordersidcustomers 桌子(也称为参照完整性)
在后台,dbt 使用通用测试块中的参数化查询为每个测试构造一个查询。这些查询返回您的断言不为 true 的行;如果测试返回零行,则断言通过。 -