摘要:本文介绍了一种针对关系型数据库的复杂计算代码逻辑测试方法,该方法借助关系型数据库提供的存储过程服务,可以在不依赖代码逻辑的情况下,直接编写自动验证用例,并保存整个计算流程的中间计算结果,提供简单可依赖运算正确性质量保证。

  1、引言

  在许多报表和统计类产品中,存在大量的复杂计算功能,这些公式往往有数十步的计算过程,上万条数据统计记录,以及跨多个关系型数据库的数据依赖,甚至是多种语言的混合实现。更棘手的是:往往为了节省数据存储资源,数据库不存储这些复杂计算逻辑的中间结果,而是直接存储终计算结果,为前端提供数据。

  在运营产品“盘古”系统中,为了衡量一个销售人员近期的业绩情况,要经过一系列的统计和计算为每个销售人员打一个综合评分,根据综合评分对销售人员分配销售任务,整个公式如下(具体业务参数和公式内涵与本文主题无关,不再冗述):

  上面列举的计算还不包括大量的查询、排序、求大值和小值、求平均值等逻辑运算。在持久层的设计中,从原始的数据记录到终的得分,中间没有存储任何的计算过程中间值,这点设计上没有问题,任何数据型系统都应该在不影响性能的情况下尽量节约存储空间。但是,复杂的运算导致了功能实现的软件质量风险,也给QA设计相应的测试用例带来的一定困难,下文将详细介绍,该类问题的测试解决方案。

  2、针对复杂计算功能的测试方法

  对于此类复杂计算的功能测试,一般采用以下两种方式进行测试:

  (一)手工用例核算的测试方法。账单、财务报表等系统的测试,QA很多采用这种手工核算的测试方法,对每一个计算项目进行手工计算核对,以此来保证代码逻辑的计算正确性。但是这种愚公移山的办法,用在上述这种没有计算过程中间值的情况下,十分不可靠而又低效了。第一,对于万级别以上的数据查询、排序,求大值、小值和平均值都是不可能完成的任务;第二,即使我们结合SQL语句进行查询、排序等逻辑运算,计算结果经过上述10个公式的手工计算难以保证用例计算的正确性;第三,手工计算效率太低且成功率没有保障,每次升级后,回归测试人力开销太大。

  (二)基于单元测试框架的测试方法。这种方法是对各个逻辑接口进行插桩,根据条件分支通过等价类划分和排列组合设计各种条件组合用例来进行测试。这种方式复用性强,用例可长期维护和自动化回归测试,是种较好的解决方案。但是,对于一些数据依赖性强的系统,需要大量准备测试数据,且这些数据互相之间有逻辑关联,数据构造带来了很大的工作量,并且还要对数据本身进行验证,降低了测试效率。

  3、基于存储过程的测试方法

  上述两种方案为目前针对复杂计算功能所常采用的三种方法,各有长短优劣。在盘古系统相关模块的测试中,结合了手工核算的手工用例和基于单元测试框架的自动化用例的测试思想,采用了一种基于存储过程的自动测试结合手工核算的方法,实现的基本思路如下:

  Step 1. 将复杂的数学计算逻辑拆分成若干个计算片段,保证每个计算片段都可以较容易的计算出来,每个计算片段生成一个中间值。

  Step 2. 在测试环境中,如表1所示,构建一张测试数据表,除ID外,为每个计算片段设置一个表字段,用于存储每个记录的计算片段中间值。