本文翻译自《JUnit in Action 2nd Edition》第十六章,大家可以查看附件^_^。
主要有以下几个内容:
1. 数据库测试挑战;
2. 介绍DbUnit;
3. 高级DbUnit测试技术;
4. DbUnit最佳测试实践。
Dependency is the key problem in software development at all scales….
Eliminating duplication in programs eliminates dependency.
—Kent Beck, Test-Driven Development: By Example
(依赖是各种规模软件开发里的关键问题......在程序中通过消除重叠消除依赖)
持久化层(简单地讲就是:数据库访问代码)无疑是任何企业项目最重要的部分之一。且不说它的重要性,持久化层难于做单元测试,主要因为以下几点:
1. 单元测试必须实行代码孤立;但是持久层需要与外部实体(数据库)相互作用。
2. 单元测试必须容易写和运行;但是访问数据库的代码可能比较复杂。
3. 单元测试必须能够快速运行;但是数据库访问比较慢。
我们把这些问题叫做数据库单元测试阻抗不匹配--引用对象/关系阻抗不匹配(它描述了使用面向对象语言去写程序时,用关系数据库持久化数据的困难)。
数据库测试不匹配能通过使用专门的工具减少到最低,其中有个工具就是DbUnit。在这里,我们展示了DbUnit怎样去测试数据数据库代码,不仅描述了它的基本思想,也奉献了一些更好的使用方法,并且使代码更容易维护。
一、数据库单元测试阻抗不匹配
让我们更深入地看看构成数据库阻抗不匹配的三个问题。
1.1 测试必须实现代码孤立
严格地说,执行数据库访问的代码测试不是单元测试,因为它依赖于外部实体-数据库。那我们应该叫它什么呢?集成测试?功能测试?非单元测试?
答案就是:没有秘籍。也就是说,数据库测试依赖于环境,可以使用很多种合适的方式。
事实上,数据库访问代码能够被运用在单元和集成测试里。
●单元测试可用作测试直接操作数据库的类(例如DAOs)。这样的测试保证这些测试类执行了实际的SQL语句,加载了正确的对象等等。虽然这些测试依赖于外部环境(例如数据库或者持久化框架),但是他们保证了一个更大的程序的基础(因此是单元)。
●类似地,测试更高层(像Facades)也可以写单元测试,没有必要访问数据库——在这些测试里,可以通过mock或者stub模拟持久化层。
●即使持久层和更高层的单元测试都具备了,访问数据库的集成测试仍然是必需的,因为有些情形仅仅发生在一方到另一方的场景(比如经常出现在JPA应用程序里的可怕的延迟实例化异常)。
1.2 单元测试必须容易写和运行
不管公司、项目经理或者技术领导称赞单元测试多少次——如果它们不容易写和运行,开发人员就会抵制它。何况敲访问数据库的代码也不是一件吸引人的任务——不得不写那烦人的SQL语句,参杂多个嵌套的try/catch/finally代码,转换各种SQL类型。
因此,为了让数据库单元测试快速展开,必须减轻开发人员的“数据库压力”。幸运的是,有一些工具做到了,比如DbUnit就是其中之一。
1.3 单元测试必须快速运行
假如你克服了上面的两个问题并且有令人满意的配置环境,拥有数以百计的访问数据库的单元测试对象,而且开发人员也容易添加新的。所有的看起来非常好,但是当开发人员运行构建时(他们一天应该会构建很多次,至少在更新他们的workspase时和提交更改到源码控制系统前),需要10分钟去完成,其中9分钟都在运行数据库测试。你应该怎样做呢?
这是最难的问题,它也并不总是可以解决的。例如:由于数据库访问本身所引起延迟,因为数据库很可能是在远程服务器上,被几十个用户访问。一个可能的解决办法就是使这个数据库更接近开发人员,通过使用嵌入式数据库(如果使用标准的SQL可以切换一个数据库),或者本地安装一个精简版的数据库。
定义:嵌入式数据库
嵌入式数据库是一个绑定在应用程序内部的数据库,而不被外部服务器(一般情况下)管理。对于JAVA应用程序,有很多嵌入式数据库可以使用,他们大多数是开源的——比如HSQLDB(http://hsqldb.org), H2(http://h2database.com), Derby(http://db.apache.org/derby), 和JavaDB(http://developers.sun.com/javadb). 嵌入式数据库的基本特征是它被应用程序管理,但不是用编写应用程序的语言所写。例如:HSQLDB和Derby支持客户端/服务器模型(除了可以选择嵌入式之外),然而SQLite(它是基于C语言的产品)也可以嵌入到JAVA应用程序中。
在下一个部分,我们将看DbUnit是怎样解决数据库单元测试不匹配的(以及在较小的程度上,嵌入数据库)。
分享到:
相关推荐
数据库测试是软件测试中的一部分,随着数据库在软件系统中的重要性不断提高,数据库测试的重要性也日益凸显。数据库测试的目的是为了确保数据库的正确性、安全性和性能,以满足软件系统的需求。下面我们将对数据库...
它可以轻松地设置和清理测试数据库的状态,确保每次测试都在相同的数据环境中运行。 ##### 5.3 Spring TestContext Framework Spring TestContext Framework 是 Spring 框架提供的测试支持模块,旨在简化 Spring ...
JUnit虽然强大,但可能需要配合其他库,如PowerMock来模拟静态方法或私有方法,或使用DBUnit处理数据库测试。 ### 6. 结语 JUnit作为面向对象软件测试的重要工具,极大地推动了软件质量的提升。掌握JUnit的使用...
数据库测试也是Java EE应用中常见的需求,DBUnit是一个用于管理数据库状态的工具,特别是在测试前后需要保持一致性的场景。它可以导入和导出数据,设置测试数据,以及清理测试后的数据库状态。通过与JUnit结合,...
- **第16章:使用DBUnit进行数据库测试**:讲解如何测试数据库操作的有效性。 - **第17章:测试基于JPA的应用程序**:探讨Java Persistence API (JPA) 在测试中的应用。 - **第18章:JUnit的高级应用**:介绍如何...
3. **DBUnit**:数据库测试通常是一个挑战,因为我们需要确保测试不会影响实际数据。DBUnit可以用来设置和清理测试数据,它与JUnit结合使用,能够在每次测试前后恢复数据库到已知状态。 4. **Spring Test模块**:...
4. **测试工具**:熟练运用JUnit和DBUnit进行单元测试,配合EasyMock进行模拟测试,对Hamcrest、Suite和Stub等测试原理有深刻理解。 5. **操作系统**:熟悉Linux常用命令,能有效利用其进行开发和运维。 6. **版本...
测试方面,他运用了SpringTest、EasyMock和DBUnit进行单元测试和集成测试,保证了代码的质量。ECharts在他的项目管理系统中用于数据统计和可视化,提升了数据分析的直观性。他还熟练使用了POI库,实现了月总结报表的...
而SSH的单元测试与dbunit的整合,则是保证代码质量与系统稳定性的有效手段。 最后,文章提到了架构与设计文档的写作技巧,以及IBM网格计算和企业批处理任务架构,这些内容提升了架构师的软技能,有助于更好地规划和...