Wings-让单元测试智能全自动生成
前言
单元测试是保证软件质量非常有效的手段,无论是从测试理论早期介入测试的理念来看或是从单元测试不受UI影响可以高速批量验证的特性,所以业界所倡导的测试驱动开发,这个里面提到的测试驱动更多的就是指单元测试驱动。但一般开发团队还是很少的系统化的执行单元测试,针对应用软件的测试更多是由专业测试团队来执行黑盒测试。单元测试的最大的难点不在于无法确定输入输出,这毕竟是模块开发阶段就已经定好的,而在于单元测试用例的编写会耗费开发人员大量的工时,按照相关统计单元测试用例的时间甚至会远超过功能本身开发的时间。以下是几个最常见的开发不写单元测试的理由:
●需求总是无穷尽的,还有下阶段功能需求要实现,没空补单元
●要补的单元测试太多,无从下手,主观上抗拒。
●单元测试编写难度大。一方面原因可能是功能函数实现上不够合理,另一方面是没有(或者不知道)好用的单元测试框架和mock框架。
●单元测试不算入工作量内。
其次,功能需求还不稳定,写单元测试的性价比不高。换句话说,万一明天需求一变,那不光功能代码废了,单元测试也废了。如果不写单元测试,那这部分工夫就不会白费。
上述几点其实分析根本原因是单元测试编写太耗时,最终导致测试驱动的发动机失去了动力,致使测试驱动开发的美好愿景在现实场景熄火,因为构建这个驱动用的发动机实在是难度和成本太大了。 市场上的各种“x”Unit,单元测试框架仅仅解决了生成测试驱动的外框,没有任何基于深度程序理解的用例逻辑和数据的产生能力。因此在各种开发相关场景中都让开发人员产生抵触情绪。Wings的发布(目前针对C语言)则解决了这个困扰程序员的一个最大的难题,同时也有可能从根本上改变单元测试的现状,充分的、高效率的单元测试将有效缓解基于海量人力的系统级黑盒测试以及自动化测试的压力。
制约测试用例采用程序自动生成,最关键的底层技术是复杂的参数解析技术。即:能够在编译器层面对于任意复杂的类型,任意定义嵌套层级的递归解析。如果没有这个关键技术的突破,那么测试用例自动生成系统要么无法商用,要么将以极低的效率来演化、产生合规的测试数据。例如著名的模糊测试工具American Fuzzy Lop,它并不能够识别用户的程序所需要的结构类型,需要从最外层进行基于搜索算法的演化。程序的特性是接口层面的输入和内部某个模块的数据要求距离很远,外部数据通常是经过层层复杂转换才可以成为内部模块所需要的数据结构类型,因此从外层探索所需要的计算量和时间将是难以想象的。基于American Fuzzy Lop,为了能够生成一个合法的SQL 语句,让程序内部模块能够通过外围数据校验需要探索时间以天数计,远非分钟或者小时可以生成。另外一个制约性条件是:每个程序能够接手的输入都是经过精心结构编制、含有大量规则的数据,而这些数据通过随机+探索的方式生成是非常不现实和极其耗时的。所以,从黑盒以及最外层输入产生自动产生用例是不可行的。
如果从软件内部结构分析产生用例驱动,就需要对软件的编译结构进行深度理解。可行的测试用例生成系统,应该是基于程序的中间(关键入口)作为测试切入最为合适。这些模块的输入,已经将模糊的输入转化为高度结构化的参数。只要能够识别这些复杂结构,将复杂数据类型一步步降解为简单数据类型,同时完成参数构造,就可以自动完成驱动用例的生成。
基于模块的测试,可以划归为传统的单元测试,它是将缺陷发现并遏制在研发阶段最好的方法。但受限于单元测试需要开发大量的驱动程序,在行业内的推广和应用受到了极大的限制。当然单元测试也可以在系统集成完毕后执行,避免构建虚拟的桩程序。
星云测试日前全球首发的Wings产品,是一个智能的、全自动的单元测试用例生成系统,研究并解决了如下难点,现分享给大家。
(1) 程序参数深度分析问题
Wings通过编译器底层技术,将输入的源文件,按照函数为单位,形成模块对象。对象中包含函数的输入参数,返回值类型等信息,供驱动函数模块和测试用例模块使用。每个文件作为一个单元,针对其中的每个函数的每个参数进行深度解析,对于嵌套类型,复杂类型等都可以实现精确的解析和分解,将复杂类型逐层讲解为基础数据类型,并产生参数结构的描述文件(PSD)。
(2) 函数驱动自动生成模块
依据PSD文件的格式信息,自动生成被测源程序的所有驱动函数,单元测试过程不再依赖开发人员手动编写测试函数,只需将生成的驱动函数和被测源文件一起编译,即可执行测试并查看测试结果。测试驱动自动生成程序基于PSD描述,全自动构建驱动被测程序运行的所有参数,必须的全局变量,并可根据复杂变量的层级结构产生结构化的测试驱动程序,可以节省大量的单元测试用例的编写时间。
(3) 测试数据自动生成与管理
用于自动生成测试数据,测试数据与被测函数提取的信息相互对应,数据以一定的层次逻辑关系存储在json文件中。数据和经过分解和展开后的数据类型是一一对应的。这些数据用户可以根据业务要求随意边际,并且用json文件进行结构化,层次化展示,非常的清晰。其中的测试数据包括全局变量值、被测函数调用时的参数值。
Wings提供了一种自动生成驱动函数的单元测试方法,其中主要包含以下几个步骤:
图一:单元测试驱动生成流程
1 被测程序信息提取
通