java项目自动化单元测试

对于我们开发人员来说,单元测试一定不会陌生,但在各种原因下会被忽视,尤其是在我接触到的项目中,提测阶段发现各种各样的问题,我觉得有必要聊一下单元测试。

为了写而写的单元测试没什么价值,但一个好的单元测试带来的收益是非常客观的。问题是怎么去写好单元测试?怎么去驱动写好单元测试?

一 现状

现状一:多个项目完全没有单元测试。

现状二:开发人员没有写单元测试的习惯,或者由于赶业务记录而没有时间去写。

现状三:单元测试写成了集成测试,比如容器、数据库,导致单元测试运行时间长,失去了意义。

现状四:太依赖集成测试。

在gitlab上随便找两个项目的测试情况,基本不考虑单元测试就合并发布,形同虚设。

站在开发的角度讲,导致以上问题的原因大概有以下几点:

  1. 开发成本

    对于系统初期,可能要花很多时间去写新业务,对于老系统又太过庞大,无法下手。

  2. 维护成本

    每修改相关的类,或者重构一次代码,我们就要去修改相应的单元测试。

  3. ROI

​ 投入产出是不是正收益?可能无论是管理者还是我们开发自己都回质疑这个问题,所以有时候没有强有力的动力。

二 怎么解决

说来说去都是成本的问题,所以我们怎么去解决成本呢?

那么,我们一切从最开始说起:开发的成本

一个单元测试的传统写法,包含以下几个方面:

  1. 测试数据 (被测数据,和依赖对象)
  2. 测试方法
  3. 返回值断言
  • 示例
  @Test  
public void testAddGroup() {    
      // 数据    
      BuyerGroupDTO groupDTO = new BuyerGroupDTO();    
      groupDTO.setGmtCreate(new Date());    
      groupDTO.setGmtModified(new Date());    
      groupDTO.setName("中国");    
      groupDTO.setCustomerId(customerId);    
      // 方法    
      Result<Long> result = customerBuyerDomainService.addBuyerGroup(groupDTO);    
      // 返回值断言    
      Assert.assertTrue(result.isSuccess());    
      Assert.assertNotNull(result.getData());  
  }

一个简单的测试还好,但如果是一逻辑复杂,且入参数据复杂的时候,那写起来其实挺头痛的。怎么解放我们程序员的双手?

“工欲善其事必先利其器”

我们以最大的努力降低我们的开发成本,这就涉及到我们测试框架和工具的选择问题

1 、测试框架选择

首先第一个问题就是junit4和junit5的选择,【从junit4到junit5】 我觉得最便利的一个好处就是可以参数化测试,并且基于参数化测试我们可以更加灵活的配置我们的参数。

效果如下:

@ParameterizedTest
@ValueSource(strings = { "racecar", "radar", "able was I ere I saw elba" })
void palindromes(String candidate) {    
    assertTrue(StringUtils.isPalindrome(candidate));
}

更好的是,junit5提供了扩展,比如我们常用的json格式。这里我们使用json文件作为输入:

@ParameterizedTest  
@JsonFileSource(resources = {"/com/cq/common/KMPAlgorithm/test.json"})   
public void test2Test(JSONObject arg) {    
    Animal animal = JSONObject.parseObject(arg.getString("Animal"),Animal.class);     
    List<String> stringList = JSONObject.parseArray(arg.getString("List<String>"),String.class);    
    when(testService.testOther(any(Student.class))).thenReturn(stringArg);    
    when(testService.testMuti(any(List.class),any(Integer.class))).thenReturn(stringList);    
    when(testService.getAnimal(any(Integer.class))).thenReturn(animal);    
    String result = kMPAlgorithm.test2();    //todo verify the result  
}

2、 mock框架

mock类的框架

Mockito: 语法特别优雅,对于容器类的模拟比较合适,且对于返回值为空的函数调用也提供比较好的断言。缺点是不能模拟静态方法(3.4.x以上版本已支持)

EasyMock: 使用方法类似,但是更严格

Powe

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值