单元测试实践小结

jUnit测试框架入门详解(加强版) 单元测试是针对最小的功能单元编写的测试代码。Java程序最小的功能单元是方法,因此单元测试就是针对单个Java方法的测试。 阅读详情

(同步自http://www.blogjava.net/AndersLin/archive/2006/06/12/52298.html)
在系统开发过程种使用单元测试,会带来很多的的好处,最明显为:
When you become convinced of the value of comprehensive unit testing, you’ll find that it begins to influence how you write code, and the frameworks you choose to use。

应用单元测试,首先要解决的是单元测试的关注点。
测试的关注点在于测试逻辑,只要有逻辑就要写测试代码。测试的手段就是验证所有被测试方法的所有产出物,包括:
1. 测试方法的返回值
2. 测试方法的执行流程
例如:

public class DomainService {
private static TheDAO dao = new TheDAO ();
public ReturnObject findByCond(String) {
        return (ReturnObject)dao.getBeanByCondition("select * from ReturnObject where cond="+ paramter, ReturnObject.class);
    }
}


在对于测试findByCond方法,有两个测试用例:
A.测传递给TheDAO.getBeanByCondition的参数的正确性,如果参数不是”select * from ReturnObject where cond=?”和ReturnObject.class则返回为null。
B.测返回的对象正确性。
 
特别是第二点,在商业应用上比较常见的。通常有些方法无明显output,通常是执行写表操作的。对于这样的方法就是测试它的执行流程。当然这些方法本身包含逻辑的。
一个简单的解决方法是利用Access Log来实现(虽然这样的测试不多,而写的case代码也看着怪怪的)。

public class ServiceExample{
    private DatabaseDao1 dao1;
    private DatabaseDao2 dao2;
 
    public void noOutputMethod(){
if(...)
            dao1.update(...);
    if(...)
            dao2.delete();
}
}


 
相关的测试代码可以这样:

public class MockDatabaseDao1 implements DatabaseDao1 {
private Map map;
public void setMap(Map map){
     this.map = map;
 }
 
public void update(args){
     map.put("MockDatabaseDao1.update", args);
}
}


   

public class MockDatabaseDao2 implements DatabaseDao2 {
    private Map map;
 
    public void setMap(Map map){
        this.map = map;
    }
 
    public void delete(args){
        map.put("MockDatabaseDao2.delete", args);
}
}


 

public class ServiceExampleTestCase{
    private Map map = new HashMap();
    public void testNoOutputMethod(){
        DaoTest test = new DaoTest();
   DatabaseDao1 dao1 = new MockDatabaseDao1();
   dao1.setMap(map);
   dao2.setMap(map);
   DatabaseDao2 dao2 = new MockDatabaseDao2();
    test.setDao1(dao1);
    test.setDao2(dao2);
    test.noOutputMethod();
    assertEquals(new Boolean(true), new Boolean(map.containsKey("MockDatabaseDao1.update")));
    assertEquals(new Boolean(true), new Boolean(map.containsKey("MockDatabaseDao2.delete"))); 
    }
}
 

例子只测试执行流程,实际实践中还可以验证所有的参数。 
我们还可以考虑利用AOP来改进这个测试方法。then, we needn't to do the same work,each time. We repeat it only once.

讨论完测试的关注点后,需要看看实际面临的具体困难
职责不明确 
   类或类方法的职责不明确,违反SRP原则.一个类或方法处理了本不该有它处理的逻辑,使得单元测试需要关心过多的外部关联类
静态方法
    静态方法使得调用者直接面对实际的服务类,难以通过其他方式替换其实现,也难以扩展
直接访问对象实例
调用者直接实例化服务对象,从而使用服务对象提供的服务.同静态方法一样,直接面对其服务类
J2se和J2ee标准库或者其他类库
    标准类库中有非常多的接口调用使得调用者难以测试 e.g JNDI, JavaMail, JAXP
准备数据及其困难
    编写测试用例需要外部准备大量的数据

针对这些困难,可用解决方法如下: 
重构系统。
    对于职责不明确的代码,只有通过重构才可以达到单元测试的目的。
Self-Delegate test pattern
   针对于class的测试,使用自代理测试模式, 使得测试时,可以重写被测试类的一些方法.达到测试的目的.通过extend class override methods来实现。Inner class mock方法也一样。不过这种方法比较别扭
编写Stubs和Mock object 
   1.   接口的mock比较容易,测试时,编写stubs和mock object来辅助测试,是非常重要的技术. Mock object分动态mock和静态mock.采用EasyMock可以很好的实现动态mock。 
   2.  具体类的mock,也很简单,通常利用子类继承的方式实现,利用cglib框架可以很好大达到测试目的。 
   3.  静态方法的mock。静态方法由于是直接面对服务对象,比较麻烦。不过,并非不可以测试,实际我们可以利用classpath的特点来实现。
方法很简单,mock类与建立一个将被mock的类的package,class name以及方法签名完全一样,但方法实现却是mock过的。在运行测试用例时,把mock类打成jar(不一定要这么做), 在配置classpath时确保,该jar的位置在当前class之前,就可以实现替换。代码如下:StaticMock.rar
使用成熟单元测试框架
   除了最基本的Junit外,Opensource提供了很多非常有价值的单元测试框架,熟练使用这些工具,可以提高测试的效率。包括对准备大量的数据,以及j2ee的框架代码。
   现有代码的可选自动化测试工具:
   1. POJO:JUnit, JMock或者EasyMock
   2. Data Object:DDTUnit。准备大量数据。
   3. Dao:DBUnit。初始化数据库。批量产生数据库数据。
   4. EJB: MockEJB或者MockRunner
   5. Servlet:Cactus
   6. Struts:StrutsUnitTest
   7. XML:XMLUnit
   8. J2EE: MockRunner
   9. GUI: JFCUnit, Marathor
   10. Other: JTestCase(采用XML定义测试过程)

分层架构下的单元测试
1 Web层的单元测试
主要测试Controller的数据结构化逻辑
如果View是利用模板引擎的,需要测试页面的控制脚本是否正确。

2 Domain Service的单元测试
包括业务规则和业务流程。
Service有四种参与对象,如下:
   1. Domain Object
   2. Dao对象
   3. 其它Service服务。
   4. 工具类
产出物:
   1. 返回值包括POJO,和结构化的数据(如XML)
   2. 传递给流程节点的参数值。
特点:
   概念上,业务逻辑和业务流程是相对独立的。实际代码,虽然一些业务逻辑是相对独立的。但是有一些业务逻辑与流程合在一起。由于业务逻辑有明确的返回值,业务规则可以独立成一个方法,其是有显示的返回值,这样UnitTest就可以focus在业务规则的测试上。而业务流程通常没有显示的返回值,在很多实践中表现为写表动作,测试比较麻烦。
   同时,不过的实际情况是业务规则和业务流程是合并在一起的。

测试的应覆盖:
1. 返回值包括POJO,或者结构化的数据如XML可以利用XMLUnit来解决。
2. 流程节点的访问,以及传递给流程节点的参数值。即对业务流程的测试,可以使用上面的访问点的方法。

3.Dao的单元测试
第一个面临的问题是:做Dao数据访问层的单元测试时机。another word也就是要不要做单元测试。
几种情况是不用测试的
1. 如果Dao就是简单的CRUD,那么不用测;在未来当我们使用1.5的范型后,这些CRUD只要在父类做一边里就可以了。
2. 如果hbm文件是自动生成的,那也不用测。
以下是要测的情况:
1. 如果hbm文件是手工写的,那么需要你保证hbm的正确性。如何测试,后面再说。
2. 如果Dao中包括了一些组合查询,那么这是一种逻辑,就应该去测;如果Dao的查询还包含了某个排序机制,这个排序逻辑依据的是业务字段,那么也是要测的。(理由是:这些逻辑可以在java代码实现,不过是性能太差了,但是既然java代码的逻辑要测,那么我们没有理由不去测在sql中的逻辑)。

第二个问题如何测试:
0. 测试数据准备
可以将BA准备的数据导出。在利用Excel编辑产生一批数据。
但是每个UnitTest测试本身应该focus一个关注点上,所以每个UnitTest的数据保持在较少的水平上。
另外由于DBUnit导入数据的顺序是依据sheet的顺序的,请注意把所有外键表在前,否则插入数据时,会报外键不存在错误。

1. 数据库的选择
a.可以直接用小组用的开发数据库。优点:现成的, 所有schema都建好了。缺点:目前数据库的数据干净性无法保证,连接速度太慢。
b.使用hsqldb。优点:利用其内存模式,可以随测试程序启动,简单小巧,schema可以自行定义,每人各自一套互不影响。 缺点:无法提供PLSQL支持。出于UnitTest本身的要求,以及性能上考量,大部分情况下,建议使用hsqldb,对于涉及到PLSQL的,需要mock处理。

2.测试hbm
利用hsqldb内存数据库,在setup的时候,利用hibernate的SchemaExport工具类,将hbm导出成数据库的schema,如果有确实有潜在问题,那么测试程序将不通过。

3.测试Dao
很简单了,调用dao程序操作。对于save,update和delete操作的。需要利用原始的connection执行查询验证。对于组合查询的和逻辑排序的,就是一般的做法了。

4.在使用DBUnit时,测试非只读操作时,我们经常会采用 DatabaseOperation.CLEAN_INSERT 策略.在关联表比较多时,效率会很差.因为每次setUp,tearDown时都会重新先Delete,再Insert所有的数据.另外,我们还有一种数据库操作测试的策略,就是使用真实数据库,在每次操作完毕后都回滚事务.

单元测试实践小结(很详细) 单元测试实践小结单元测试实践小结,很好的一个单元测试实践小结总结,希望对大家有帮助 立即下载

相关推荐

单元测试实践小结[5]

单元测试实践小结[5]   软件测试  7.XML:XMLUnit  8.J2EE:MockRunner  9.GUI:JFCUnit,Marathor  10.Other:JTestCase(采用XML定义测试过程)  分层架构下的单元测试  1Web层的单元测试  主要测试Controller的数据结构化逻辑  如果View是利用模板引擎的,需要测试页面的控制脚本是否正确。  2DomainService的单元测试  包括业务规则和业务流程。  Service有四种参与对象,如下:  1.DomainObject  2.Dao对象  3.其它Service服务。  4.工具类原文转自:ht

单元测试实践总结

1、A\B测试 1、是什么 一个好的产品都是迭代出来的,而我们很可能不清楚这次的迭代最终是好是坏(至少我们是觉得迭代对用户是好的,是有帮助的,对公司的转化也是好的),但是我们的用户未必就买账。 ABTest最主要做的就是一个分流: 将10%流量分给用户群体A 将10%流量分给用户群体B 我们需要保证的是:一个用户再次请求进来,用户看到的结果是一样的 一般可以这样做: 对 用 户 ID( 设 备 ID/CookieId/userId/openId) 取hash值,每 次 Hash 的 结 果 都 是 相

脚踏实地 789

PE启动盘结合360杀毒离线版:深度清除顽固病毒实战指南

在系统安全维护领域,离线查杀是一种在独立于宿主操作系统的环境下进行病毒扫描和清除的核心技术。其原理是通过一个预启动环境(如PE)加载杀毒软件,从而绕过可能已被感染或受保护的系统核心,直接访问和扫描磁盘文件。这项技术的核心价值在于能够彻底处理那些在正常系统运行时难以清除的深度隐藏病毒、Rootkit和驱动级木马。典型的应用场景包括应对勒索软件、顽固感染型病毒以及系统启动项被劫持等情况。本文以“PE启动盘”和“360杀毒离线版”这一经典组合为例,详细解析了从工具选型、环境部署到深度查杀策略的全流程,为系统维护人

weixin_29741447的博客 410

单元测试实践

我们开发都知道单元测试的重要性,而且每个开发都有要写单元测试的意识 ;单元测试和代码编写结构息息相关业界常用专业名词TDD(测试驱动开发),言外之意我们开始编写代码的时候就已经想好单元测试应该怎么写?

qq_35932990的博客 1687

GEE|基于时间序列特征的山东省玉米随机森林分类代码

主题思路: 本实验为二分类实验,分类目标包括:玉米、其他(建筑、水体、水稻、 裸地、森林、小麦、道路、大蒜等),采用人工设计的特征指数的时间序列特征为分类依据,选取分类器为:随机森林分类器,并选取样本集中 70%作为训练样本,30%作为测试样本,通过调整随机森林棵数,调整分类器结构。选取以下参数进行分类: ⚫ 时间尺度:1990 年 4 月 15 日 - 1990 年 9 月 30 日 ⚫ 空间尺度:山东省 ⚫ 影像融合时间间隔:16天 ⚫ 特征值选择:['nir','ndvi'...

weixin_46493028的博客 7467

嵌入式开发实战:LWIP中PPP协议配置全流程(含CHAP认证避坑指南)

本文是一份嵌入式开发实战指南,详细解析了如何在STM32平台上配置LWIP协议栈中的PPP协议,实现从串口到IP网络的完整连接。内容涵盖工程搭建、源码整合、关键配置、串口驱动绑定、状态管理以及CHAP认证等核心流程,并重点提供了CHAP认证失败的排查与避坑指南,帮助开发者高效打通嵌入式设备的网络连接。

plant的博客 464

单元测试的最佳实践

本文将介绍基于集成Mockito + PowerMock + H2 + EmbededRedis 的单元测试实践方案,整套单元测试环境将完全脱离Spring框架进行,使得功能验证更加纯粹简单。

TanzJ的博客 2141

基于DFT的scanshift sdc模板(DFT)

摘要:本文详细介绍了DFT测试模式下的SDC约束方法。

murphyrong的博客 887

单元测试实践小结1

在系统开发过程种使用单元测试,会带来很多的的好处,最明显为: When you become convinced of the value of comprehensive unit testing, you’ll find that it begins to influence how you write code, and the frameworks you choose to use。 应

wssmao的专栏 555

51-14 Retentive Network,RetNet 多尺度保留机制序列建模论文精读

RetNet 提出了多尺度保留机制序列建模,该机制支持三种计算范式,即并行、循环和分块循环。RetNet有更好的全局注意力建模、高效的计算效率、对遮挡的鲁棒性、支持基于注意力的图像生成、与置信度相关的门控机制和多任务学习等特点,对不同视觉任务可以共享历史注意力记忆,可以同时进行分类、分割、检测等任务。RetNet在视觉领域应该有广阔的应用前景。

AIgraphX 1614

海洋捕食者算法(MPA)详解:从海洋生态智慧到高性能优化

摘要: 海洋捕食者算法(MPA)是一种基于海洋生态觅食行为的元启发式优化算法,模拟捕食者(如鲨鱼)的布朗运动和莱维飞行策略进行全局与局部搜索。算法分为三阶段:高速比阶段(全局探索)、单位速度比阶段(平衡搜索)和低速比阶段(局部开发),通过精英矩阵和FADs效应(概率扰动)避免早熟收敛。MPA具有参数少、收敛快、寻优能力强等特点,适用于复杂优化问题,其数学模型将生物行为转化为随机游走与自适应策略,并通过收敛因子动态调整探索-开发平衡。实验表明,MPA在多个基准问题上表现优异。

qq_42212808的博客 274

关于Java单元测试实践的小结

单元测试在线上运行时,感觉像空气(AIR)一样感觉不到,但在测试质量的保障上,却是非常关键的。好的单元测试宏观上来说,具有自动化、独立性、可重复执行的特点。

小人物的草稿本 1767

【图像超分】论文复现:CVPR 2024 | 轻量化超分 | 窗口注意力改进 | CAMixerSR的Pytorch源码复现,跑通源码,获得指标和超分结果,计算复杂度,架构梳理拆解,逐行注释!

本文介绍了超分辨率重建方法CAMixerSR的代码实现与运行指南。文章亮点包括:完整跑通源码获取PSNR/SSIM指标和可视化结果;详细解析模型架构与关键代码注释,帮助快速复现基线模型。实验部分提供了测试配置文件和训练设置说明,支持2K/4K/8K大图像超分和x2/x4轻量化超分。环境依赖PyTorch和BasicSR框架,数据集包含DIV2K等常用基准。测试结果与论文指标一致,可视化输出保存至指定目录。训练配置可自定义数据集路径、GPU数量等参数。该实现突出了CAMixerSR在降低W-MSA复杂度方面的

主要更新底层视觉(去噪、超分等)相关的科研内容,形式为【论文精读】+【论文复现】 438

单元测试实践小结3

使用成熟单元测试框架     除了最基本的Junit外,Opensource提供了很多非常有价值的单元测试框架,熟练使用这些工具,可以提高测试的效率。包括对准备大量的数据,以及j2ee的框架代码。 现有代码的可选自动化测试工具: 1. POJO:JUnit, JMock或者EasyMock 2. Data Object:DDTUnit。准备大量数据。 3. Dao:DBUnit。初始化数据库。批量

wssmao的专栏 513

使用GitLab限制开发者使用CI/CD的权限,三种方案

使用三种方案来限制开发人员的CI/CD权限。

知无涯 5097

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

单元测试实践小结2

讨论完测试的关注点后,需要看看实际面临的具体困难 职责不明确     类或类方法的职责不明确,违反SRP原则.一个类或方法处理了本不该有它处理的逻辑,使得单元测试需要关心过多的外部关联类 静态方法     静态方法使得调用者直接面对实际的服务类,难以通过其他方式替换其实现,也难以扩展 直接访问对象实例     调用者直接实例化服务对象,从而使用服务对象提供的服务.同静态方法一样,直接面对其服务类

wssmao的专栏 502

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

持续集成实践小结[2] —单元测试

前文提到,在UI自动化之外,我们着力探索了如何实施单元测试(unittest)   相对于UI自动化,单元测试方面的实践还是不够充分的,因此,这里也只是小结一下我们的经验   概述   首先明确一下,此处单元测试概念与经典意义有所不同,泛指所有:   由开发工程师编写的,可以在开发本地一键运行的,运行时间在分钟级别的测试用例,用例执行会依赖不多的,但...

weixin_33763244的博客 138

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

Android实战——单元测试从吹水到实践

本文从到底要不要单元测试开始讨论,说明了单元测试的好处,并列举了自己进行单元测试的路程,希望可以帮助到大家。

willwaywang6 3298

golang及beego框架单元测试小结

单元测试是保证开发质量的一个重要手段,提及golang开发,要保证开发质量,则难以回避单元测试的使用。golang开发语言有原生提供单元测试相关代码及工具,不足之处是代码实现层面不是太友好,写单元测试不大便利;有第三方,依据大家习惯使用的断言方式,给出了开源解决方案testify,为大家写单元测试提供了便利;具体到beego框架,鉴于其实现机制,实现单元测试,也需要进行适当的调整,下面将依次进行说明。.....................

cfh0081的专栏 1493

Spring Boot之DAO层的单元测试小结

DAO层 dao是data access object的简写,基于Java对象访问数据库中的数据,这是应用中必备的系统模块。 测试注解 DataJpaTest 主要用以测试DAO的业务功能 DAO层的实体定义 实体Bean定义如下: @Entity @Data public class GameEntity { @Id @GeneratedValue(strategy=Gene...

木小鱼的笔记 6958

Java JUnit 单元测试小结

测试类型 单元测试(Unit test) 单元测试关注单一的类. 它们存在的目的是检查这个类中的代码是否按照期望正确运行. 集成测试(Integration test) 集成测试是检查开发的模块和其他模块整合时是否正常工作. 虽然集成测试的代码影响范围比单元测试要广, 但是集成测试和单元测试一样, 也是针对于开发者而言的. 端到端测试(End-to-End test) 端到端测试是将整个系统作为一个整体, 然后从用户的角度进行测试的. 端到端测试的目的是测试系统在实际使用的是否正常的, 因此通常

taoy86的博客 961
上一篇: 单元测试实践小结
下一篇: 《分析模式》笔记之分析手段
林仪明
博客等级 码龄25年 313粉丝 61原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值