最近写了一个针对数据仓库ETL的测试框架,baidu google了一下发现还没有非常靠谱的同类型框架或解决方案,就忍不住提前分享一下(其实是因为周五下午不想干活)。
首先分享一下我们过去测试ETL的方法:很简单,就是写两段SQL分别query上下两层数据,然后通过数据库的minus方法来得到不符合预期的数据,进而进行分析。例如
-- Source
select
src1.pk
, case
when src1.lkp_ky is null then
-2 -- not available
else
case
when src2.some_ky is null then
0 -- not found
else
src2.some_ky
end
end some_ky
from
(select * from source_table_1 where lgcl_del_fg = 'n') src1
left join
source_table_2 src2 on src1.lkp_ky = src2.lkp_ky
minus
-- Target
select
pk
, some_ky
from
target_table
用SQL写测试用例是可行的的,但是有很多我认为不够好的问题:
1. SQL可读性非常差。
一个ETL的mapping有十几二十个字段很正常,写出来的SQL最后一看超过二百行也很正常,但是如果能让别人一眼看懂就不正常了:对于数据集之间的连接,是在from下面进行,而对于连接好的数据的操作,是在select下面,from上面进行(即上例中的case when语句),这种憋屈的语法结构会让review的人很头疼,导致后期维护也会痛不欲生。
2. SQL写ETL逻辑的时候有点捉急……
SQL毕竟不能完全算是编程语言,虽然提供了很多数据的操作方法,但是比起正儿八经的编程语言还是略逊一筹……相信用SQL测过ETL的人都有过力不从心的感觉。我认为这也是ORM出现的根本原因!
3. SQL一点都不灵活!
这点一时不知道怎么说才好,因为我根本不知道SQL跟灵活有什么关系。不过看完我们提供的方案后,希望读者能感受到:这TMD才是灵活!
总之篇幅关系,我就不继续埋汰SQL了,重点还是介绍我们的方案:提供一套取代SQL的方法来编写测试用例。
先看一下我们实现上面sql的方式:
mapping("test_etl") do
declare_target_table 'target_table', :t
declare_source_table "select * from source_table_1 where lgcl_del_fg='n'", :src1
m t.pk, src1.pk
m t.some_ky do
declare_source_table 'source_table_2', :src2
left_join src2, "src1.lkp_ky = sr2.lkp_ky"
if src1.lkp_ky.nil?
-2 # not available
else
if src2.some_ky.nil?
0 # not found
else
src2.some_ky
end
end
end
end
这里说明一下,框架用ruby开发,用例就是ruby代码,如果看官您不懂ruby,请不要转身离开,我们做了最够多的工作在框架本身,暴露给编写用例的测试人员的都是最基础的,既普通的if else一类的控制语句以及字符串数字的操作,所以完全不用为了使用此框架来额外学习很多ruby知识。
开始解释我们的用例:
mapping表示着我们用例的开始,后面的“test_etl”相当于这个用例的名字,后面生成报告时会用到这个名字。mapping后面的do ... end中编写我们一个mapping的所有逻辑。
declare_source(target)_table 方法用来定义我们使用到的表(或者sql),第一个参数是表名,第二个参数是别名,定义好别明后,下面的代码即可应用别名来代替包。
比如declare_source_table "wo_qu_nian_mai_le_ge_biao", :biao
之后就可以用biao.id, biao.name 来表示表的id跟name字段。(顺便一提,我们还提供了CTE的定义。)
m方法用来表示target表的column跟source是怎么对应的。如果没有任何处理直接照搬过去可以用“m t.pk, src1.pk”来表示。
如果要经过转换才能得到目标column,可以把转换逻辑写在m后面的 do end里,如
m t.some_ky do
declare_source_table 'source_table_2', :src2
left_join src2, "src1.lkp_ky = sr2.lkp_ky"
if src1.lkp_ky.nil?
-2 # not available
else
if src2.some_ky.nil?
0 # not found
else
src2.some_ky
end
end
end
do end里是纯的ruby代码(其中的left_join是框架自己的方法),可以非常清晰的表达转换逻辑。
看到这里可能有人会说:这不是换汤不换药么?看不出比上面那段SQL强在哪里。
首先我们的用例可以直接把source target的mapping关系非常直观的表现出来,其次,我们能做到join表跟使用表写在一起,即我能清楚的知道我join这张表是干什么用的。如果用例需要join非常多的表,这种设计对于用例可读性的提升是巨大的!同时如我之前说的,do end里面可以用ruby代码写逻辑,而ruby比SQL操作数据轻松,比如ruby可以轻松实现字符串的split功能,据我所知oracle目前还没有提供split功能。‘
当然这还不是全部,我刚才还说我们的方案非常灵活。
1. 首先可以非常方便添加参数:比如再etl实际运行中可能会用到sysdate(系统时间),但是测试运行时sysdate很可能跟之前sysdate不一样,我们测试时要赋一个值给sysdate,这时我们就可以把sysdate作为一个参数。
2. 可以添加动态的变量:比如我们每次测试时需要找到最新的数据,即每次都要得到一个max(date),这个过程可以非常方便得定义在用例里。
3. 可以引用外部数据:测试过程中有可能需要读取一个文件的数据,或者访问webservice得到数据,这个过程也可以定义到用例中!只要ruby能解决的问题,框架都能解决……
4. 引用之前的计算结果:写sql时,经常发现之前得到的计算结果,后面居然没有办法直接用。如我的source有一个学生的各科成绩,首先我要得到学生的总分,然后要根据学生的总分来判断学生是优等生还是差生。如果用sql的话我要这样写:
select
std_id
, (score1 + score2 + score3 .... + scoren) total_score
, case
when (score1 + score2 + score3 .... + scoren) >= 600 then
'NB'
when (score1 + score2 + score3 .... + scoren) >= 400 (score1 + score2 + score3 .... + scoren) < 600 then
'Normal'
else
'SB'
end grade
from
score
当然也可以用CTE
with t as(
select
std_id
, (score1 + score2 + score3 .... + scoren) total_score
from
score)
select
std_id
, t.total_score total_score
, case
when t.total_score >= 600 then
'NB'
when t.total_score >= 400 t.total_score < 600 then
'Normal'
else
'SB'
end grade
from
score inner join t on score.std_id = t.std_id
嗯,再看看我们怎么做的
mapping("score_grade") do
declare_target_table 'target', :t
declare_source_table "score", :score
m t.std_id, score.std_id
m t.total_score do
score.score1 + score.score2 + score.score3 ... + scoren
end
m t.grade do
case
when row[:total_score] >= 600
'NB'
when row[:total_score] < 600 && row[:total_score] >= 400
'Normal'
else
'SB'
end
end
end
请容我先自我陶醉一会……
现在简单介绍一下我认为最牛逼的功能:测试覆盖率
我们的方案可以检测到数据是否能覆盖所有分支!!!从而能彻底杜绝很多传统测试方法难以检查到到的隐患。
请让我再陶醉一会……
现在我们提供了一套完全替代sql的书写用例方法,这种用例书写方法不仅灵活,而且可读性极强。我做这个框架的灵感就来源于看到设计文档时,想如果文档能当用例运行起来就好了,现在我做到了……我们的用例跟ETL的设计文档相似度已经很高了。
用例管理/运行/数据验证/报告生成方面,包括给user提供扩展的接口我们也做了,但是感觉没有太大的新意,就不详细介绍了。
我们的框架现在还在测试中,如果稳定了,我会把gem(ruby的代码包)pull到rubygems.org,还会有更详细的文档介绍上面提到或者没提到的功能,如果大家有兴趣可以联系我一起讨论。部分代码可以在https://github.com/piecehealth/ETLTester 得到
分享到:
相关推荐
总结起来,这两个压缩包提供了不同的功能:一个是ETL测试框架与数据库的集成,用于数据处理验证;另一个是集群管理工具,专为基于jasocket的应用程序配置复制数据库。这两个开源项目都体现了Java在数据处理和分布式...
* CloverETL测试框架:使用CloverETL工具来测试数据的正确性和可靠性。 * Fusion/Solr测试框架:使用Fusion/Solr工具来测试数据的正确性和可靠性。 * MongoDB测试框架:使用MongoDB数据库来测试数据的正确性和可靠性...
这个压缩包可能提供了针对MySQL数据库的ETL测试框架,使得开发者能够更有效地测试其数据处理流程的正确性和性能。 【havarunner.zip】是一个Java测试框架,名为HavaRunner,特别强调了它具有内置的并发支持。这意味...
5. 原型测试与结果分析:原型测试验证了改进后的框架实现了业务的自动化处理,有效减少了开支,并且提高了整体效率和用户体验。 6. 遥感云服务的定义:文章给出了遥感云服务的明确定义,即基于云计算整合了大规模...
CWM提供了一个统一的数据仓库元数据模型框架,旨在促进不同工具和平台之间的互操作性和一致性。基于CWM标准进行ETL工具的设计与开发,有助于提高工具的通用性和可维护性。 #### 设计思想与实现步骤 1. **分析现有...
5. **Npgsql.dll**:这是.NET框架下的PostgreSQL数据库驱动,表明此ETL工具可能支持与PostgreSQL数据库的交互。 6. **Mono.Security.dll** 和 **MySql.Data.dll**:前者是Mono项目的安全组件,可能涉及加密或认证;...
该资源内项目源码是个人的毕设,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! <项目介绍> 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! ...
本资源"Ruby的数据处理和ETL框架_Ruby_下载.zip"可能包含一个名为"kiba-master"的项目,它很可能是Kiba ETL框架的源代码。 Kiba是Ruby社区中广泛使用的轻量级ETL工具,它提供了灵活的管道架构来提取、转换和加载...
在本场景中,"etl插件开发模板" 提供了一个框架或基础,帮助开发者快速构建自己的ETL插件。 标题中的"etl插件开发模板"暗示了这是一个工具,可能包含了预设的代码结构、接口定义、样例代码等,目的是加速ETL流程中...
这个过程通常涉及到ETL(Electronic Test Language)的使用,ETL2254可能是指一种特定的ETL测试标准或规范,用于验证设计的正确性和可靠性,确保在实际制造中能够满足性能和质量要求。 "body2eh"可能是某种专有名词...
ETL(Extract, Transform, ...在实际操作中,ETL设计还涉及到元数据管理、性能优化、数据安全以及测试策略等方面。良好的ETL设计能够提高数据处理的效率,降低错误率,为后续的数据分析和决策支持提供可靠的数据基础。
- **SNMP网络管理模型**:描述了基于SNMP的网络管理框架。 通过以上详细的知识点梳理,可以看出R&S ETL 电视分析仪器是一款功能强大且操作灵活的设备,适用于各种复杂的电视信号分析场景。无论是手动操作还是远程...
Bi NBi是用于商业智能的测试框架(NUnit的附加组件)。 它支持大多数关系数据库(SQL Server,MySQL,postgreSQL ...)和OLAP平台(Analysis Services,Mondrian ...),还支持ETL和报告组件(Microsoft技术)。 该...
编写可靠,简洁,经过良好测试和可维护的数据处理代码非常棘手。 Kiba允许您使用Ruby定义和运行这样的高质量ETL( )作业。 入门 前往获取最新文档。 如果您需要帮助,请以便其他人可以从您的贡献中受益! 我会...
云技术、电信ETL方案、IBM刀片服务器、性能测试报告是本文档的关键词,其包含了关于在云技术环境下基于Hadoop的电信ETL解决方案,以及在IBM刀片服务器上进行性能测试的详细记录。接下来将对这些关键知识点展开详细...
- 介绍了ETL开发的整体流程,从需求分析到测试部署。 - 提供了实用的编程技巧和建议,帮助开发人员更高效地编写ETL代码。 - 强调了版本控制和文档记录的重要性。 #### 四、开发与运行维护 - **第八章:运行维护*...
- **迁移到生产系统**:指导如何将测试环境中的ETL流程顺利迁移到生产环境中。 - **监控ETL系统**:介绍了监控ETL系统的策略和技术,确保ETL过程的稳定性和可靠性。 - **ETL过程调优**:提供了优化ETL性能的具体方法...
- 编码与测试:实现ETL流程,进行单元测试和集成测试。 - 部署与监控:上线运行ETL流程,设置监控指标,确保数据的准确性和性能。 - 维护与优化:根据业务变化和性能反馈持续优化ETL流程。 6. 性能优化与错误...