接上篇内容,如果是对DBT不太熟悉的朋友,建议从DBT介绍这篇文章开始阅读。
测试
概要
测试是您对模型和dbt项目中的其他资源(例如源、种子和快照)所做的断言。当您运行dbt测试时, dbt将告诉您项目中的每个测试是通过还是失败。
您可以测试模型中的指定列是否只包含非空值、唯一值,或者在另一个模型中具有相应值的值(例如,订单的 customer_id对应于customers模型中的id),以及来自指定列表的值。以上四个测试是DBT内置的。与dbt中的几乎所有内容一样,测试也是SQL查询。特别是,它们是一些select语句,它们试图获取“失败 的”记录,即反驳您的断言的记录。如果您断言一个列在模型中是唯一的,那么测试查询将选择重复的列; 如果您断言一个列从不为空,那么测试将查找空值。如果测试返回零失败行,则测试通过,您的断言已经得到验证。
在dbt中有两种定义测试的方法:
- 单一测试是以最简单的形式进行测试:如果您可以编写返回失败行的SQL查询,则可以将该查询保存 在
test
目录中的. SQL文件中。它将由dbt test
命令执行。 - 通用测试是接受参数的参数化查询。测试查询定义在一个特殊的test块中(如宏)。定义之后,您可以 在.yml文件中通过名称引用通用测试—在模型、列、源、快照和种子上定义它。
单一测试
定义测试的最简单方法是编写将返回失败记录的SQL。 我们称这些“单一”测试,因为它们是一次性断言,可用于单一目的。
这些测试在.sql 文件中定义,通常在您的tests目录中(由您的test-paths配置定义)。 您可以在测试定义中使用 Jinja(包括 ref 和 source),就像在创建模型时一样。 每个 .sql 文件包含一个 select 语句, 它定义了一个测试:
这个测试的名称是文件的名称:assert_total_payment_amount_is_positive。
执行命令:
dbt test -s [test_name]
单一测试很容易编写,您可能会发现自己反复编写相同的基本结构,只是更改了列或模型的名称。此时,测试就不那么单一了!那样的话,建议使用通用测试。
通用测试
某些测试是通用的:它们可以一遍又一遍地重复使用。 通用测试在test块中定义,包含参数化查询并接受参数。 它可能看起来像:
注意到有两个参数,model 和 column_name。 这就是使测试“通用”的原因:它可以在任意多的列上定义,跨越任意多的模型,并且 dbt 将相应地传递model和column_name 的值。 一旦定义了通用测试,就可以将其作为属性添加到任何现有模型(或source、seed或snapshot) 上。 这些属性添加到资源所在目录中的 .yml 文件中。
dbt附带四个已经定义的通用测试:unique、not_null、accepted_values
和relationships
。
简单地说:
- unique:orders模型中的order_id列应该是唯一的
- not_null:orders模型中的order_id列不应该包含空值
- accepted_values:orders中的状态列应该是'placed'、'shipped'、'completed'或'returned'中的一个
- relationships:orders模型中的每个customer_id都作为customers中的id存在(也称为引用完整性)
dbt使用来自通用测试块的参数化查询为每个测试构造一个select查询。这些查询返回断言不为真的行;如果测试返回零行,则测试通过。
示例
向项目中添加通用测试:
- 向models目录中添加一个.yml文件,例如models/schema.yml,其中包含以下内容:
- 运行
dbt test
命令
存储测试失败的结果
如果您设置了可选的 --store-failures 标志或 store_failures 配置,dbt 首先将测试查询的结果保存到数据库中的一个表中,然后查询该表以计算失败的数量。 此工作流程允许您在开发过程中更快地查询和检查失败记录: 请注意,如果您选择存储测试失败:
- 默认情况下,测试结果表在后缀或命名为 dbt_test__audit 的schema中创建。 可以通过设置schema配置来更改此值。 (有关模式命名的更多详细信息,请参阅使用自定义模式。)
- 测试的结果将始终替换相同测试的先前失败的结果。
FAQs:
-
如何一次测试一个模型?
dbt test --select customers
-
如果测试失败了,怎样debug?
要调试失败的测试,请查找 dbt 运行的 SQL:
-
dbt CLI: 打开作为错误消息的一部分返回的文件路径。 导航到所有已编译测试查询的 target/compiled/schema_tests 目录
将 SQL 复制到查询编辑器中,然后运行查询以查找失败的记录。
-
我可以将我的测试存储在项目中的 tests 目录以外的目录中吗?
默认情况下,dbt 期望您的单一测试文件位于项目的
tests
子目录中,而通用测试定义位于tests/generic
或macros
中。 要更改此设置,请更新 dbt_project.yml 文件中的 test-paths 配置,如下所示: test-paths: ["my_cool_tests"] 然后,您可以在 my_cool_tests/generic/ 中定义通用测试,并在 my_cool_tests/ 中定义其他的单一测试。 -
如何仅对我的源运行测试?
测试所有的源:
dbt test --select source:*
在一个源(及其所有表)上运行测试:
dbt test --select source:jaffle_shop
仅在一个源表上运行测试:
dbt test --select source:jaffle_shop.orders
-
我可以测试两列的唯一性吗?
(1). 在模型中创建一个唯一键并对其进行测试
(2). 测试表达式
(3).使用dbt_utils.unique_combination_of_columns测试