单元测试新势力——Spock的简单介绍

发表于:2021-8-20 09:38

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:Carleslucky    来源:掘金

  提起单元测试(这里特指Java的单元测试),很多人可能第一时间想到的是junit、mockito等等的框架,或者可能压根你的项目都没写过单测,得益于本地可以方便的运行项目,所以很多人就直接人肉测试了一下就交给QA了,然后被各种bug劈头盖脸而来。倒不是说写单元测试可以完全规避bug,能规避50%以上吧,而且对于后续的改动是持续有效的,因为很多人会觉得我就改了一行代码,怎么会有问题呢?往往问题就来自于此。
  单元测试的价值我也无需多言,今天主要是安利一个单测的新势力框架——spock。单元测试的框架层出不穷,最终的目的就是让开发者可以方便的验证自己的代码。这可能是Java领域为数不多的可以不用标榜性能的框架了,因为单测最重要的是方便,方便的运行、方便的mock、方便的开发,慢点真倒不重要。junit相对原始一些,可能也是众多框架中最靠近java语法的,mockito之类的就封装了很多方法,也可以称之为DSL,一系列的give,when等等方法,给人最简单的直觉,减少了代码量,也更容易书写和理解。
  方便就是单测框架的发展方向,而今天要介绍的spock更是把这一理念又想向前推进了一大步。spock的官网是这么形容自己的:
  What makes it stand out from the crowd is its beautiful and highly expressive specification language.
  spock是基于行为驱动开发(BDD)的思想,提供了各种标签,并采用简单、通用、结构化的描述语言(DSL),甚至直接使用了groovy作为单测的开发语言。不用担心学习成本,几乎是看一眼就可以学会的语法,甚至可以认为没有语法。下面举一个简单的例子来说明为什么spock很好用。
  这是一个典型的if/else场景,也不知道为了什么很多人都很讨厌if/else,写if/else很low吗?只要逻辑清晰,也没什么问题吧。这是计算个人所得税的案例,不用if/else能用什么呢?
public double calc(double income) {
        BigDecimal tax;
        BigDecimal salary = BigDecimal.valueOf(income);
        if (income <= 0) {
            return 0;
        }
        if (income > 0 && income <= 3000) {
            BigDecimal taxLevel = BigDecimal.valueOf(0.03);
            tax = salary.multiply(taxLevel);
        } else if (income > 3000 && income <= 12000) {
            BigDecimal taxLevel = BigDecimal.valueOf(0.1);
            BigDecimal base = BigDecimal.valueOf(210);
            tax = salary.multiply(taxLevel).subtract(base);
        } else if (income > 12000 && income <= 25000) {
            BigDecimal taxLevel = BigDecimal.valueOf(0.2);
            BigDecimal base = BigDecimal.valueOf(1410);
            tax = salary.multiply(taxLevel).subtract(base);
        } else if (income > 25000 && income <= 35000) {
            BigDecimal taxLevel = BigDecimal.valueOf(0.25);
            BigDecimal base = BigDecimal.valueOf(2660);
            tax = salary.multiply(taxLevel).subtract(base);
        } else if (income > 35000 && income <= 55000) {
            BigDecimal taxLevel = BigDecimal.valueOf(0.3);
            BigDecimal base = BigDecimal.valueOf(4410);
            tax = salary.multiply(taxLevel).subtract(base);
        } else if (income > 55000 && income <= 80000) {
            BigDecimal taxLevel = BigDecimal.valueOf(0.35);
            BigDecimal base = BigDecimal.valueOf(7160);
            tax = salary.multiply(taxLevel).subtract(base);
        } else {
            BigDecimal taxLevel = BigDecimal.valueOf(0.45);
            BigDecimal base = BigDecimal.valueOf(15160);
            tax = salary.multiply(taxLevel).subtract(base);
        }
        return tax.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
    }
  对于这个方法的test case用spock写是这样的:
@Unroll
def "个税计算,收入:#income, 个税:#result"() {
  expect: "when + then 的组合"
  CalculateTaxUtils.calc(income) == result

  where: "表格方式测试不同的分支逻辑"
  income || result
  -1     || 0
  0      || 0
  2999   || 89.97
  3000   || 90.0
  3001   || 90.1
  11999  || 989.9
  12000  || 990.0
  12001  || 990.2
  24999  || 3589.8
  25000  || 3590.0
  25001  || 3590.25
  34999  || 6089.75
  35000  || 6090.0
  35001  || 6090.3
  54999  || 12089.7
  55000  || 12090
  55001  || 12090.35
  79999  || 20839.65
  80000  || 20840.0
  80001  || 20840.45
}

  这样简单快捷的单测写法,节省时间又大幅降低出bug的概率,不尝试一下吗?
本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号