如何在ETL过程中进行测试(单元测试)?

How to test (unit test) on ETL process?

我知道有几家小公司不做 ETL 过程的测试,但从软件工程的角度来看,这似乎不是最优的。

人们通常如何 testing/unit test/functional 测试 ETL 流程?

我们最近参与了一个项目,治理委员会要求 'You must have Unit Tests',所以我们尽了最大努力。

对我们有用的是每个 ETL 解决方案都以 QA/Test 包开始和结束。

这些包发现的任何意外情况都会记录到审核中 table,然后引发失败包事件以停止整个作业 - 我们认为最好 运行 使用昨天的良好数据而不是针对可能的不良 'today' 数据进行风险报告。

起始包将执行数据库架构和数据完整性检查。数据完整性涉及检查由于源系统中缺乏引用完整性而导致的重复或丢失数据。模式检查确保检测到在持续集成期间未应用的任何模式更改。

最终包将检查任何转换的结果。其中包括:

  • 比较源|目标之间的记录数
  • 检查特定的转换(例如:所有日期值更改为适当的 SK 值,所有字符串值 RTrimed)
  • 确保填充所有 SK 字段(-1 而不是空值)

这些测试中的大多数都是 SQL 语句,它们使用了我们数据库的内置模式对象,因此创建起来并不费力。

此外,作为我们开发过程的一部分,我们将创建具有我们正在进行的任何转换的最终结果的视图。我们将利用这些视图来验证我们的包转换。

这些检查中的每一项都在我们的特殊审核中创造了记录table。这样我们就可以提供一个完整的列表,其中包含我们在每个 运行 过程中所做的所有测试和检查,以满足治理人员的需求。

(我们还有一组单独的包,可以通过创建虚拟 tables、填充它们、运行ning 测试然后确认适当的审计记录来对每个 QA 测试进行单元测试写了。正如尼克所说,这是很多工作,没有什么实际价值)

我们已经建立了一个系统,在这个系统中,我们为每个 ETL 过程定义了一个输入数据集和一个预期结果数据集。然后我们创建了一个系统,利用 Robot Framework,为每个 ETL 过程运行三部分测试,其中第一部分将输入数据集插入源数据表,第二部分运行 ETL,第三部分比较实际结果与我们的预期结果。

这对我们来说效果很好,但也有一些缺点:首先,我们为每个 ETL 过程手动创建测试数据集,这需要一些工作,其次,这意味着测试 "unexpected" 输入未完成。

对于自动化单元测试,我们有一个单独的环境,我们可以在其中自动安装整个 DW 的构建。

ETL 的测试通常是个问题。更准确地说,测试不是问题,问题是如何得到合理的测试数据。 ETL 通常在生产数据上进行测试。除了安全问题之外,生产数据的问题是没有充分涵盖 ETL 的功能(通常大约 40% 的业务规则没有被生产数据样本涵盖)并且需要太多时间来处理。

最近我们开发了一个测试数据生成器(有关更多详细信息,请查找 GTL QAceGen:Informatica Market Place 上的业务逻辑驱动数据生成器),它根据业务规则规范生成基于源 tables/files 的测试数据.该工具考虑了任何应用的外键,它适用于任何主要的 ETL and/databases.

此工具有助于将测试周期加快至少 50%(与手动测试相比),并涵盖 100% 的所有业务规则。它还会生成非常详细的报告,更重要的是,这些测试可以随时重复(即回归测试)。

ETL过程中的测试分为以下几个阶段:

  1. 确定业务需求
  2. 验证数据源
  3. 准备测试用例
  4. 从不同来源提取数据
  5. 应用转换逻辑来验证数据
  6. 将数据加载到目的地
  7. 报告分析

我们还可以将ETL测试过程归类如下: 产品验证 源到目标数据测试 元数据测试 性能测试 集成和质量测试 报告测试

可以 单元测试 ETL。

End-to-end 测试很好,但速度慢、成本高且难以构建和保持稳定。

单元测试 ETL 非常需要能够测试所有数据排列,但通常放入 too-hard 篮子。然而,可以为 ETL 编写真正的单元测试,可以 运行 快速可靠。

我们发现关键是将 ETL 分解为两个独立的部分。由于 ETL 是 Extract-Transform-Load,关键是将 T 与 E&L 分开。创建一个将输入数据集转换为输出数据集的纯转换函数,然后从提取和加载模块调用此函数。

提取和加载模块不适合单元测试,因为它通常会涉及外部数据源和接收器、访问令牌和用户权限等。

但是所有可测试的逻辑都应该在 Transform 组件中。从任何单元测试框架测试此功能 - 您将能够传入预定义的数据集并根据预期结果测试转换后的输出。通过一些思考,我们甚至设法创建了单元测试来测试 multi-stage 数据集的相互更新。

我们的特定实现是在 Scala 中的 Databricks 上完成的,但该概念应该适用于任何平台。