【功能测试技巧2】dubbo引起的数据精度的思考

1.引言

1.1引入背景

我们目前使用的所熟知的公司的保险系统,好多涉及计算金额的字段,开发都将这类变量定义为Double类型,举例请看下表:

字段

定义类型

来源系统

Premium【保费】

double

承保系统

PlanFee【应收应付金额】

double

收付系统

EstimateLoss【估损金额/报案金额

double

理赔系统

1.2场景重现

所在项目涉及的是接口测试,寺库商户系统每向样光信保发送一笔订单,在阳光信保进行承保;有承保自然会出现理赔场景;当寺库商户将一笔订单的逾期报案信息发送到阳光信保理赔系统时,信保接口接收一笔索赔金额时报错;自己测试也没有问题,进行查找后发现是double类型精度问题所导致;

2.分析

2.1产生原因

接口传送过来的报文以JSON形式进行交互,每个字段都定义为String类型;寺库逾期报案金额=逾期本金+逾期利息之和即[EstimateLoss=balance+int]

具体举例如下:

Balance=121.57

Int=4.83

此时EstimateLoss=balance+int=121.57+4.83=126.40;但是当balance本金与int利息进入理赔系统,按照double方式进行接收相加的结果如下图在Eclipse里运行的结果:

了然了吧,理赔系统会拿126.39999999999999与接口报文中实际传送的129.40做比较,肯定不相等,从而触发了报案的报案金额一定要和本金+利息之和相等这条需求;

2.2解决方案

采用Java 浮点数精确计算 BigDecimal方式进行处理;

第一:即先将两个String类型的本金和利息直接接收到理赔系统;

      String类型的EstimateLoss报案金额直接接收到理赔系统,

Double类型;

第二:将String类型的本金和利息分别转换为BigDecimal

第三:将本金与利息之和是BigDecimal类型的,在还原成理赔系统识别的Double类型,在拿去和EstimateLoss报案金额做比较;

最后在构造为BigDecimal实现相加。

即按照如下代码实现:涉及减法、乘法、除法的浮点型精度也需要考虑测试的是哪种数据类型;

 public static double sub(double v1,double v2){

        BigDecimal b1 = new BigDecimal(Double.toString(v1));

        BigDecimal b2 = new BigDecimal(Double.toString(v2));

        return b1.subtract(b2).doubleValue();

    }

运用BigDecimal进行运算结果如下:

 

2.3分享说明

希望今后大家测试接口或者其他涉及金额的问题时,一定要事先向开发咨询其定义的和金额有关的变量,定义的数据类型是什么,如果是浮点型的FloatDouble,那么这样的变量进行运算的时候就会出现精度问题,需要格外注意;

一般情况下:

两个(或以上)的Float类型的数据进行数学运算,会产生精度丢失问题;

两个(或以上)的Double类型的数据进行数学运算,会产生精度丢失问题;

一个Float类型与另一个Double类型的数据进行数学运算,会产生精度丢失的问题;

所以测试涉及小数(一般是金额相加减的时候)需要明确的内容:

1.两个相加字段,在开发程序里定义的数据类型是什么;

  一般直接定义为BigDecimal,不要想当然的认为就没有问题,要看它是否自始至终都是BigDecimal类型的数据进行操做,如果不是,请注意:因为只有String直接转BigDecimal才不会有精度丢失错误,将float或者double转成BigDecimal也会出现数据精度丢失问题;

   2.熟悉一般类型哪些小数进行数学运算会报数据精度丢失问题,数据精度丢   失原因这里不做介绍,可以自行百度;一般给自己准备上几组,遇到这类问题的时候将这几组数据套用进去验证一下;

3.一般容易出现这种问题的数据验证组合如下(包括但不局限以下实例):

323.34-4.85

121.54-4.83

121.57+4.83

4.015*100

123.3/100

2.4延伸扩展

从精度问题引申到我们平时需要注意有些字段,开发定义的数据类型会影响精度;

有时还要留意JAVA数据内部默认赋值的特性;

Int数据类型默认值为0

String类型默认值为NULL

Boolean类型的默认值为false

当我们测试规则引擎的时候,有些时候定义只有某一个值为0的时候才会触发规则,当系统处理异常时有可能不能返回正常数据的值,此时如果默认为int型的数据将会默认返回0,使得系统默认这条数据触发了规则,从而使风控规则失真;

3.希望

希望通过本文档的书写,使得在测试金额等涉及精度问题的时候,能够快速的意识到精度风险,当然也不要草木皆兵,先向开发了解清楚程序内部定义的数据类型是什么。总之,希望大家都能耳聪目明,叫精度丢失问题在我们面前无所遁形;

转载于:https://www.cnblogs.com/haibaowang/p/6733498.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值