返回知识库

数据质量测试实战:从数据流转到数据质量保障

从源系统一路追到报表、BI与AI应用,证明每一次抽取、转换、加载和汇总都没有让业务事实走样。

12 个章节SQL + 数据仓库金融 / BI / AI 数据链路
🧭

为什么需要 ETL 测试

页面正确,不代表数据可信

用户看到一行数据,背后可能经过五层加工

业务数据通常要经过源数据库、抽取任务、清洗转换、数据仓库、接口与缓存,最后才出现在页面、报表或AI应用中。任何一层出错,都可能让最后的数字看起来合理、实际上却是错的。

业务系统
ODS 原始数据层
DWD 明细数据层
DWS 汇总数据层
ADS 应用数据层
报表 / BI / AI应用

各层职责与测试重点

层级主要职责测试关注
业务系统订单、客户、贷款、合同等原始业务数据源数据是否完整、时间和状态是否可信
ODS 原始层按源结构落地,尽量保留原貌抽取数量、批次、重复、缺失、原始快照
DWD 明细层清洗、标准化、补充业务维度字段映射、类型转换、空值和异常处理
DWS 汇总层按主题聚合形成可复用指标口径、时间窗口、去重、关联和聚合结果
ADS 应用层为报表、BI、风控或AI提供数据最终指标与业务规则、页面、接口是否一致

ETL 测试的目标

  • 数据没有无故丢失、重复或被错误过滤。
  • 字段、类型、金额精度和业务状态转换正确。
  • 明细、汇总、接口与页面使用同一指标口径。
  • 跑批失败、重复执行和迟到数据都能被安全处理。
  • 异常可追溯到具体批次、规则、业务键和数据层。
🔄

ETL 三个阶段

Extract / Transform / Load

每个阶段分别测什么

阶段作用测试重点
Extract 抽取从数据库、文件、接口或消息获取数据是否漏抽、重抽、错批次;时间范围和水位线是否正确
Transform 转换清洗、计算、关联、去重、标准化业务规则、边界、空值、异常值和精度是否正确
Load 加载把结果写入目标表或数据集市数量、字段、主键、分区、重复加载和失败恢复

抽取

验证“该来的都来了,而且只来一次”。重点关注时间窗口、水位线、连接失败和断点恢复。

转换

验证“业务规则没有把数据加工错”。重点关注边界、空值、精度、关联和异常分流。

加载

验证“正确结果落到正确位置”。重点关注主键、分区、提交事务和重复跑批。

🗺️

先建立字段 Mapping

没有映射表,就没有可执行测试

字段映射表示例

源字段转换规则目标字段质量规则
loan_order.customer_id原值传递dwd_loan.cust_id非空;必须存在于客户维表
loan_order.loan_amount分转元,保留2位小数dwd_loan.asset_amountDECIMAL;金额不可为负
loan_order.overdue_days> 90 标记为不良dwd_loan.asset_status边界90与91分别验证
loan_order.created_at转换为业务时区日期dwd_loan.biz_date跨日、夏令时和空值规则明确

Mapping 表至少包含

  • 源系统、源表、源字段与数据类型。
  • 过滤条件、转换公式、字典映射和默认值。
  • 目标表、目标字段、主键、分区和精度。
  • 空值、异常值、重复值与无关联数据的处理方式。
  • 规则负责人、需求版本和生效日期。
🔍

ETL 六类核心校验

数量只是第一步

核心验证矩阵

检查项验证目标常用方法
数量一致性源数据经过合法过滤后与目标数量相符count(*)、按批次/分区分组对账
字段映射源字段正确写入目标字段逐字段抽样、全量差异查询
转换逻辑业务计算和分类正确等价类、边界值、异常值
唯一性主键或业务键没有重复count(*) 与 count(distinct key)
完整性必填字段和关联数据齐全NULL率、孤儿记录、缺失维度
聚合准确性总额、数量、比率与明细一致sum、count、group by、反向下钻
SQL / 对账基础
-- 按业务日期核对源数据量
select count(*)
from loan_info
where created_at >= '2026-08-09 00:00:00'
  and created_at <  '2026-08-10 00:00:00';

-- 核对目标批次数量、唯一键和金额控制总额
select
  count(*) as row_count,
  count(distinct loan_id) as unique_count,
  sum(asset_amount) as control_amount
from dwd_loan
where biz_date = '2026-08-09';

数量不一致时不要直接判Bug

源表100000条、目标表99998条,只能证明存在2条差异。还要结合合法过滤、去重、异常分流和软删除规则,定位是抽取失败、转换过滤还是加载失败。

🧪

数据转换逻辑测试

ETL 测试的核心

转换规则用例设计

类型测试数据预期
正常值贷款金额 500000,逾期 30 天金额正确,资产状态为正常
边界值逾期 90 天、91 天90 天不误判;91 天按规则进入不良
空值逾期天数为 NULL按约定置默认值、进入异常表或拒绝处理
非法值金额为负数、日期格式错误不能静默写入正常目标表
精度金额换算、利率和比例计算小数位、舍入方式与财务口径一致
编码中英文、特殊字符、身份证号前导零不乱码、不截断、不丢前导零

不良资产规则示例

规则:逾期天数大于90天时,资产状态标记为 BAD。

SQL / 差异检查
select loan_id, overdue_days, asset_status
from dwd_loan
where (overdue_days > 90 and asset_status <> 'BAD')
   or (overdue_days <= 90 and asset_status = 'BAD');

测试原则

  • 从业务规则反推输入,不只抽查生产数据。
  • 每个比较符号都测试边界两侧和边界本身。
  • 金额、利率和比例明确精度与舍入方式。
  • 异常数据必须有去向:拒绝、默认、隔离或告警,不能静默消失。
♻️

增量同步、幂等与重跑

生产事故高发区

增量任务必须覆盖的场景

场景执行方式核心断言
首次全量目标为空,执行完整批次所有合法历史数据只加载一次
正常增量新增、更新、删除各准备一条只处理水位线后的变化
重复跑批同一批次再次执行结果不重复,控制总额不变化
中途失败重跑加载50%后模拟失败从断点恢复或安全重跑,不漏不重
迟到数据昨天业务日期的数据今天才到按规则回补正确分区并更新汇总
乱序更新旧版本晚于新版本到达不会用旧状态覆盖新状态

水位线测试

  • 起始时间是否包含边界,结束时间是否排除下一批次。
  • 时间字段使用创建时间、更新时间还是业务日期。
  • 时区转换、跨日、月末和节假日跑批是否正确。
  • 水位线推进必须与任务提交成功保持一致。

幂等的判断标准

同一批次执行一次和执行多次,最终业务结果必须相同。不能只看任务返回成功,还要核对行数、唯一键、金额总额、版本号和下游汇总是否保持不变。

🧩

关联、聚合与指标口径

数字对上,还要口径对上

关联测试

  • inner join 是否错误丢弃无匹配数据。
  • left join 是否因一对多关系放大数据量。
  • 维表缺失时使用默认值、异常表还是拒绝加载。
  • 历史维度是否按业务时间匹配正确版本。

聚合测试

  • sum、count、distinct、平均值的分母和去重口径。
  • 自然日、账务日、滚动窗口和累计值的时间范围。
  • 明细向上汇总与指标向下钻取结果一致。
  • 空集合、负数冲正和撤销记录处理正确。
SQL / 孤儿记录与关联放大
-- 目标事实表中找不到客户维度的记录
select f.loan_id, f.cust_id
from dwd_loan f
left join dim_customer d on f.cust_id = d.cust_id
where d.cust_id is null;

-- 检查关联后业务键是否被意外放大
select loan_id, count(*) as joined_rows
from dws_customer_loan
group by loan_id
having count(*) > 1;
📊

把ETL校验升级为数据质量体系

从一次测试变成持续监控

六个数据质量维度

维度含义参考指标
完整性必填字段不缺失、数据批次齐全NULL率、应到/实到批次数
唯一性业务主键不重复重复键数量
准确性值符合真实业务事实金标样本正确率、对账差异
一致性不同层、不同系统表达同一事实跨表、跨系统差异率
及时性数据在SLA内可用延迟、跑批完成时间
有效性格式、范围、枚举符合规则非法值率、异常表数量

质量阈值要分层

  • P0:资金、余额、贷款本金等控制总额必须零差异。
  • P1:关键字段完整率、唯一率必须达到明确阈值。
  • P2:非关键描述字段允许少量异常,但要进入趋势监控。
  • 任何阈值都要有业务负责人和处置动作,不能只展示红绿灯。

数据血缘

当ADS报表数字错误时,必须能反查到DWS聚合、DWD明细、ODS原始记录和源系统。测试报告应记录表级、字段级血缘以及对应规则版本,避免只知道“数字错了”,不知道从哪一层开始查。

🛠️

ETL 测试流程

先理解链路,再写SQL

1. 梳理链路

  • 确认数据源、加工层、目标表和最终消费方。
  • 画出数据流转图,标注任务依赖与事实来源。
  • 明确全量、增量、实时或批处理方式。

2. 分析规则

  • 建立字段Mapping与指标口径表。
  • 确认过滤、去重、关联、聚合和异常处理。
  • 标记资金、权限、合规等高风险字段。

3. 设计数据

  • 正常、边界、异常、重复、迟到和乱序数据。
  • 为每条数据分配可追踪业务键与批次号。
  • 记录期望落层和最终指标。

4. 执行与复测

  • 任务前记录源数据快照和控制总额。
  • 任务后逐层核对数量、字段、规则和汇总。
  • 修复后使用同一批数据重跑并验证幂等。
🏦

金融AI交付案例:不良资产数据链

OCR + ETL + 业务规则
银行贷款数据
合同 / OCR识别
结构化字段
资产明细表
风险聚合
清收策略 / AI分析页面

贯穿验证

  • OCR准确性:合同金额、客户、日期和编号与原件一致。
  • 结构化入库:类型、精度、必填字段和重复合同处理正确。
  • 风险规则:逾期天数、贷款余额和担保信息计算正确。
  • 控制总额:源贷款余额、DWD资产余额、报表总额零差异。
  • 页面与AI:展示指标来自正确版本的数据,AI引用的资产事实可追溯。

高风险场景

  • OCR把500000识别为50000,格式合法但金额错误。
  • 同一合同重复上传,导致资产金额重复累计。
  • 迟到的还款数据没有回补,风险等级长期偏高。
  • 旧维度数据覆盖新客户状态,导致清收策略错误。
  • AI分析使用过期ADS快照,却没有展示数据时间。

这类测试本质上是 AI数据质量测试 + ETL测试 + 业务规则测试。模型输出是否可信,首先取决于进入模型的数据是否可信。

🤖

ETL 测试自动化

规则配置化,差异可追踪
建议目录结构
etl-tests/
  mappings/        # 字段映射与规则配置
  queries/         # 源、目标、差异SQL
  fixtures/        # 正常、边界、异常测试数据
  checks/          # 数量、唯一性、完整性、控制总额
  runners/         # 批次执行与任务状态轮询
  reports/         # 差异明细和质量报告

适合自动化的检查

  • 按批次核对源、过滤、目标数量。
  • 唯一键、必填字段、枚举和数值范围。
  • 金额、数量和余额控制总额。
  • Mapping规则和差异SQL回归。
  • 重复跑批、断点重跑和迟到数据回补。
  • 质量阈值越界时阻断或告警。

自动化边界

脚本擅长发现差异,不擅长决定差异是否符合业务。指标口径变化、监管规则和异常数据处置仍需要产品、数据开发与测试共同确认。

报告模板与检查清单

让每次跑批都有证据

ETL 测试报告

项目记录内容
批次信息任务名、批次号、业务日期、代码与规则版本
对账结果源数量、过滤数量、目标数量、差异数量与控制总额
质量结果完整性、唯一性、准确性、一致性、及时性指标
异常明细业务键、源值、目标值、规则、错误类型与关联日志
测试结论通过、不通过、有条件通过及风险说明
可追溯证据SQL、数据快照、任务日志、血缘、截图和复测结果

测试前

  • 数据链路与事实来源明确
  • Mapping和口径已评审
  • 批次、水位线与SLA明确
  • 测试数据可追踪

测试中

  • 逐层记录数量和控制总额
  • 转换边界与异常分流已验证
  • 增量、重跑、迟到数据已覆盖
  • 差异保留业务键和日志

测试后

  • 目标与消费端结果一致
  • 质量阈值全部达标
  • 失败数据可重放和复测
  • 高风险规则进入持续监控