CN115994085A - 代码覆盖率的测试处理方法、装置、设备及存储介质 - Google Patents
代码覆盖率的测试处理方法、装置、设备及存储介质 Download PDFInfo
- Publication number
- CN115994085A CN115994085A CN202111222862.5A CN202111222862A CN115994085A CN 115994085 A CN115994085 A CN 115994085A CN 202111222862 A CN202111222862 A CN 202111222862A CN 115994085 A CN115994085 A CN 115994085A
- Authority
- CN
- China
- Prior art keywords
- code coverage
- coverage rate
- code
- file
- data
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Pending
Links
Images
Abstract
本申请提供了一种代码覆盖率的测试处理方法、装置、电子设备、计算机可读存储介质及计算机程序产品;方法包括:获取多份代码覆盖率数据文件,其中,每份代码覆盖率数据文件包括:基于用例测试代码时产生的数据文件和对代码进行编译生成的符号文件;根据文件名对多份代码覆盖率数据文件进行匹配,得到多个数据集,其中,每个数据集包括对应的一份数据文件和一份符号文件;基于进程池包括的用于运行代码的多个进程,并行处理多个数据集,得到每个数据集对应的代码覆盖率信息子文件;基于任务标识将多份代码覆盖率信息子文件合并为代码覆盖率信息文件,并以键值对的形式存储多份代码覆盖率信息文件。通过本申请,能够有效提高代码覆盖率的测试效率。
Description
技术领域
本申请涉及计算机技术领域,尤其涉及一种代码覆盖率的测试处理方法、装置、电子设备、计算机可读存储介质及计算机程序产品。
背景技术
在软件开发过程中,开发人员需要对开发好的代码进行测试,而在测试的过程中,通常需要对软件测试过程的代码覆盖率进行统计。代码覆盖率(Code coverage)是软件测试中的一种度量,描述程序中源代码被测试的比例和程度,所得到的比例称为代码覆盖率。代码覆盖率是反映测试用例对被测软件覆盖程度的一个重要指标,是用来衡量测试完整性的一个参考值。通过代码覆盖率数据,可以评估测试是否充分,从而确定是否需要重复执行软件测试。
然而,相关技术提供的代码覆盖率的测试方法通常是首先获取当前目录下所有的Gcda文件和Gcno文件,接着将所获取的Gcda文件和Gcno文件处理成中间Gcov文件,最后遍历所有的中间Gcov文件,生成Info文件,并且上述计算过程是以单线程的方式执行的,且会落地很多无用的中间文件,导致代码覆盖率的测试效率较低,进而大大降低了开发/测试人员的工作效率。
发明内容
本申请实施例提供一种代码覆盖率的测试处理方法、装置、电子设备、计算机可读存储介质及计算机程序产品,能够有效提高代码覆盖率的测试效率。
本申请实施例的技术方案是这样实现的:
本申请实施例提供一种代码覆盖率的测试处理方法,包括:
获取多份代码覆盖率数据文件,其中,每份所述代码覆盖率数据文件包括:基于用例测试代码时产生的数据文件和对所述代码进行编译生成的符号文件;
根据文件名对所述多份代码覆盖率数据文件进行匹配,得到多个数据集,其中,每个所述数据集包括对应的一份所述数据文件和一份所述符号文件;
基于进程池包括的用于运行所述代码的多个进程,并行处理所述多个数据集,得到每个所述数据集对应的代码覆盖率信息子文件;
基于任务标识将多份所述代码覆盖率信息子文件合并为代码覆盖率信息文件,并以键值对的形式存储多份所述代码覆盖率信息文件。
本申请实施例提供一种代码覆盖率的测试处理装置,包括:
获取模块,用于获取多份代码覆盖率数据文件,其中,每份所述代码覆盖率数据文件包括:基于用例测试代码时产生的数据文件和对所述代码进行编译生成的符号文件;
匹配模型,用于根据文件名对所述多份代码覆盖率数据文件进行匹配,得到多个数据集,其中,每个所述数据集包括对应的一份所述数据文件和一份所述符号文件;
处理模块,用于基于进程池包括的用于运行所述代码的多个进程,并行处理所述多个数据集,得到每个所述数据集对应的代码覆盖率信息子文件;
合并模块,用于基于任务标识将多份所述代码覆盖率信息子文件合并为代码覆盖率信息文件;
存储模块,用于以键值对的形式存储多份所述代码覆盖率信息文件。
上述方案中,所述存储模块,还用于将所述多个数据集存入待处理队列中;所述处理模块,还用于从所述待处理队列中获取与所述多个进程相同数量的多个数据集,并将所述多个数据集分别分发给所述多个进程,通过每个所述进程各自处理分发到的一个数据集;当所述多个进程中的任一进程处理完成时,从所述待处理队列中获取剩余的一个数据集,通过所述任一进程处理所述剩余的一个数据集,直至所述待处理队列中存储的所有数据集均处理完成。
上述方案中,所述处理模块,还用于通过每个所述进程执行以下处理:获取所述数据集携带的参数,其中,所述参数包括输入路径、输出路径、以及格式参数;根据所述输入路径获取所述数据集包括的数据文件和符号文件;基于所述格式参数对所述数据集包括的数据文件和符号文件进行处理,得到符合格式需求的代码覆盖率信息子文件;将所述符合格式需求的代码覆盖率信息子文件存储至数据库中与所述输出路径对应的位置。
上述方案中,所述处理模块,还用于从所述数据集包括的数据文件和符号文件中获取代码覆盖率信息,其中,所述代码覆盖率信息是基于基本块和弧进行表征的;按照所述格式参数,对所述代码覆盖率信息进行格式转换;基于格式转换后的所述代码覆盖率信息,生成符合格式需求的代码覆盖率信息子文件。
上述方案中,所述处理模块,还用于从所述数据集包括的符号文件中获取程序流图信息,基于所述程序流图信息建立所述代码中每个函数的程序流图;从所述数据集包括的数据文件中获取已知的弧的执行次数,并将所述已知的弧的执行次数写入所述程序流图中;根据所述程序流图、以及所述已知的弧的执行次数,确定其他的弧与基本块的执行次数;基于所有弧与基本块的执行次数,确定所述代码对应的代码覆盖率信息,其中,所述代码覆盖率信息包括以下至少之一:函数信息、行数信息。
上述方案中,所述处理模块,还用于针对每个所述用例对应的多个代码覆盖率信息子文件,执行以下处理:获取所述用例对应的任务标识;将所述任务标识作为所述多个代码覆盖率信息子文件的前缀;其中,不同用例对应的任务标识不同。
上述方案中,所述处理模块,还用于针对每个所述代码覆盖率信息子文件,执行以下处理:为所述代码覆盖率信息子文件设置第一后缀和第二后缀,其中,所述第一后缀用于标识所述代码覆盖率信息子文件对应的所有的代码行,所述第二后缀用于标识所述代码覆盖率信息子文件对应的所有的代码行中被执行的代码行。
上述方案中,所述装置还包括创建模块,用于创建所述进程池;所述装置还包括确定模块,用于根据待处理的数据集的数量、以及用于运行所述进程池的性能条件,确定所述进程池包括的进程的数量。
上述方案中,所述创建模块,还用于创建连接池,其中,所述连接池包括多个连接;所述处理模块,还用于当接收到多个所述代码覆盖率信息文件分别对应的多个写入请求时,基于所述连接池包括的所述多个连接并行处理所述多个写入请求,以将多个所述代码覆盖率信息文件存入数据库中。
上述方案中,所述存储模块,还用于针对每个所述任务标识,执行以下处理:以所述任务标识为键、以所述任务标识对应的代码覆盖率信息文件为值进行存储。
上述方案中,所述代码为更新后的代码;所述装置还包括比较模块,用于将所述更新后的代码对应的代码覆盖率信息文件,与更新前的代码对应的代码覆盖率信息文件进行比较,得到增量的代码覆盖率信息文件;所述装置还包括生成模块,用于基于所述增量的代码覆盖率信息文件,生成代码覆盖率报告;所述确定模块,还用于根据所述代码覆盖率报告,确定所述更新后的代码对应的代码覆盖率测试结果。
本申请实施例提供一种电子设备,包括:
存储器,用于存储可执行指令;
处理器,用于执行所述存储器中存储的可执行指令时,实现本申请实施例提供的代码覆盖率的测试处理方法。
本申请实施例提供一种计算机可读存储介质,存储有可执行指令,用于引起处理器执行时,实现本申请实施例提供的代码覆盖率的测试处理方法。
本申请实施例提供一种计算机程序产品,包括计算机程序或指令,所述计算机程序或指令被处理器执行时,实现本申请实施例提供的代码覆盖率的测试处理方法。
本申请实施例具有以下有益效果:
首先根据文件名对多份待处理的代码覆盖率数据文件进行匹配,得到多个数据集,接着基于进程池包括的多个进程来并行处理多个数据集,得到每个数据集对应的代码覆盖率信息子文件,随后基于任务标识将多份代码覆盖率信息子文件进行合并,最后以键值对的形式存储合并得到的多份代码覆盖率信息文件,如此,针对待处理的数据集进行了并行化处理,大大提高了代码覆盖率的测试效率,并且最终得到的多份代码覆盖率信息文件是以键值对的形式进行存储,减少了后续的查找时间,进而大大提升了开发/测试人员的工作效率。
附图说明
图1是本申请实施例提供的代码覆盖率的测试处理系统100的架构示意图;
图2是本申请实施例提供的服务器200的结构示意图;
图3是本申请实施例提供的代码覆盖率的测试处理方法的流程示意图;
图4是本申请实施例提供的代码覆盖率的测试处理方法的流程示意图;
图5是本申请实施例提供的代码覆盖率的测试处理方法的流程示意图;
图6是相关技术提供的代码覆盖率的测试处理方法的流程示意图;
图7是本申请实施例提供的单个Gcov4的处理流程示意图;
图8是本申请实施例提供的Info文件的输出示意图;
图9是本申请实施例提供的多个Gcov4并发处理的流程示意图;
图10是本申请实施例提供的Redis键值设计示意图;
图11是本申请实施例提供的Redis连接池的示意图。
具体实施方式
为了使本申请的目的、技术方案和优点更加清楚,下面将结合附图对本申请作进一步地详细描述,所描述的实施例不应视为对本申请的限制,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其它实施例,都属于本申请保护的范围。
在以下的描述中,涉及到“一些实施例”,其描述了所有可能实施例的子集,但是可以理解,“一些实施例”可以是所有可能实施例的相同子集或不同子集,并且可以在不冲突的情况下相互结合。
在以下的描述中,所涉及的术语“第一\第二”仅仅是区别类似的对象,不代表针对对象的特定排序,可以理解地,“第一\第二”在允许的情况下可以互换特定的顺序或先后次序,以使这里描述的本申请实施例能够以除了在这里图示或描述的以外的顺序实施。
除非另有定义,本文所使用的所有的技术和科学术语与属于本申请的技术领域的技术人员通常理解的含义相同。本文中所使用的术语只是为了描述本申请实施例的目的,不是旨在限制本申请。
对本申请实施例进行进一步详细说明之前,对本申请实施例中涉及的名词和术语进行说明,本申请实施例中涉及的名词和术语适用于如下的解释。
1)代码覆盖率(Code coverage):软件测试中的一种度量,描述程序中源代码被测试的比例和程度,所得比例称为代码覆盖率。代码覆盖率的意义在于分析未覆盖部分的代码,从而反推在前期代码设计是否充分,还可以检测出程序中的无用代码,反推在代码设计中思维混乱之处,提醒开发人员注意代码相关逻辑关系,提升代码的质量。因此,代码覆盖率测试是帮助开发人员、测试人员提前发现问题,保证代码质量的好帮手。
2)数据文件:即Gcda文件,在运行编译过的程序的时候,会产生Gcda文件,它包含了每段代码具体的执行次数,例如包含了跳变的次数等信息。
3)符号文件:即Gcno文件,在代码编译的时候会产生Gcno文件,它包含了代码计数器和源代码之间的映射关系,例如包含了重建基本块图和相应的块的源代码的行号的信息。
4)基本块(BB,Basic Block):指程序顺序执行的语句序列,例如如果一段程序的第一句语句被执行过一次,这段程序中的每一个语句都要执行一次,也就是说,一个BB中的所有语句的执行次数一定是相同的。一般由多个顺序执行语句后边跟一个跳转语句组成。所以一般情况下BB的最后一条语句一定是一个跳转语句,跳转的目的地是另外一个BB的第一条语句,如果跳转时有条件的,就产生了分支,该BB就有两个BB作为目的地。
5)弧(ARC):从一个BB到另外一个BB的跳转称为一个ARC,因此当想获取程序中的每个语句和分支的执行次数,就必须知道每个BB和ARC的执行次数。
6)程序流图:又称程序流程图或者程序框图,是用统一规定的标准符号描述程序运行具体步骤的图形表示。例如如果把BB作为一个节点,那么这样一个函数中的所有BB就构成了一个有向图。如果想知道程序中的每个语句和分支的执行次数,就必须知道每个BB和ARC的执行次数。根据图论可以知道有向图中BB的入度和出度是相同的,因此只要知道了部分的BB或者ARC大小,就可以推断出所有的BB和ARC。
7)进程池:是资源进程和管理进程组成的技术的应用,其中,管理进程用于负责创建资源进程,把工作交给空闲的资源进程进行处理,并回收已经处理完工作的资源进程,资源进程为预先创建好的空闲进程,管理进程会把工作分发到空闲进程来处理。
8)连接池:是创建和管理一个连接的缓冲池的技术,这些连接准备好被任何需要使用它们的线程使用。数据库连接池的主要操作如下:建立数据库连接池(服务器启动);按照事先指定的参数创建初始数量的数据库连接(即空闲连接数);对于一个数据库访问请求,直接从连接池中得到一个连接,如果数据库连接池对象中没有空闲的连接,且连接数没有达到最大的活跃连接数,则可以创建一个新的数据库连接;存取数据库;关闭数据库,释放所有数据库连接(此时的关闭数据库连接,并非真正关闭,而是将其放入空闲队列中,例如当实际空闲连接数大于初始空闲连接数是,则释放连接);释放数据库连接池(即服务器停止、维护期间,释放数据库连接池,并释放所有连接)。
9)用例:又称测试用例(Test Case),是指对一项特定的软件产品进行测试任务的描述,体现测试方案、方法、技术和策略,其内容包括测试目标、测试环境、输入数据、测试步骤、预期结果、测试脚本等,最终形成文档。也就是说,测试用例是为了某个特殊目标而编制的一组测试输入、执行条件以及预期结果,用于核实是否满足某个特定软件需求。
本申请实施例提供一种代码覆盖率的测试处理方法、装置、电子设备、计算机可读存储介质以及计算机程序产品,能够有效提高代码覆盖率的测试效率。下面说明本申请实施例提供的电子设备的示例性应用,本申请实施例提供的电子设备可以实施为笔记本电脑,平板电脑,台式计算机,机顶盒,移动设备(例如,移动电话,便携式音乐播放器,个人数字助理,专用消息设备,便携式游戏设备),车载终端等各种类型的终端设备,也可以实施为服务器,或者由终端设备和服务器协调实施。
下面以由终端设备和服务器协同实施本申请实施例提供的代码覆盖率的测试处理方法为例进行说明。示例的,参见图1,图1是本申请实施例提供的代码覆盖率的测试处理系统100的架构示意图,为实现支撑一个有效提高代码覆盖率的测试效率的应用,终端设备400通过网络300连接服务器200,网络300可以是广域网或者局域网,又或者是二者的组合。
如图1所示,服务器200首先从数据库500中获取多份代码覆盖率数据文件,其中,每份代码覆盖率数据文件包括:基于用例测试代码(即待测试的代码,例如可以是某个更新后的应用程序的源代码)时产生的数据文件和对代码进行编译生成的符号文件(例如在某次测试中,测试/开发人员可以针对待测试的代码一次性编写多个用例,基于所编写的多个用例对代码进行测试,从而得到多份代码覆盖率数据文件,并将得到的多份代码覆盖率数据文件存入数据库500中);接着,服务器200根据文件名对所获取的多份代码覆盖率数据文件进行匹配,得到多个数据集,其中,每个数据集包括对应的一份数据文件和一份符号文件;随后,服务器200创建进程池,并基于进程池包括的用于运行代码的多个进程,并行处理多个数据集,得到每个数据集对应的代码覆盖率信息子文件,最后,服务器200可以基于任务标识(每个用例对应一个唯一的任务标识)将多份代码覆盖率信息子文件合并为代码覆盖率信息文件,并以键值对的形式存储合并后得到的多份代码覆盖率信息文件(即以任务标识为键、以任务标识对应的代码覆盖率信息文件为值进行存储),如此,当后续测试/开发人员需要查看某个用例对应的代码覆盖率信息文件时,可以通过终端设备400向服务器200发送请求,请求中携带用例对应的任务标识,服务器200在接收到终端设备400通过网络300发送的请求时,提取请求中携带的任务标识,并基于提取到的任务标识进行查找,得到以任务标识对应的代码覆盖率信息文件,并将得到的代码覆盖率信息文件返回给终端设备400,终端设备400在接收到服务器200返回的代码覆盖率信息文件之后,可以对服务器200返回的代码覆盖率信息文件进行格式转换处理,例如可以将服务器200返回的代码覆盖率信息文件转换成超文本标记语言(HTML,Hyper Text Markup Language)格式,并调用客户端410的人机交互界面进行展示,如此,通过可视化的方式可以让测试/开发人员直观地获取针对待测试代码的代码覆盖率信息。
在另一些实施例中,也可以由终端设备单独实施本申请实施例提供的代码覆盖率的测试处理方法,例如以图1中示出的终端设备400为例,终端设备400首先从数据库500中获取多份代码覆盖率数据文件,接着根据文件名对多份代码覆盖率数据文件进行匹配,得到多个数据集,随后终端设备400可以创建进程池,并基于进程池包括的多个用于运行代码的进程,并行处理多个数据集,得到每个数据集对应的代码覆盖率信息子文件,最后终端设备400可以基于任务标识将多份代码覆盖率信息子文件合并成代码覆盖率信息文件,并以键值对的形式存储合并得到的多份代码覆盖率信息文件,如此,通过进程池包括的多个进程并行处理多个数据集的方式,大大提升了代码覆盖率的测试效率。
在一些实施例中,本申请实施例还可以借助于云技术(Cloud Technology)实现,云技术是指在广域网或局域网内将硬件、软件、网络等系列资源统一起来,实现数据的计算、储存、处理和共享的一种托管技术。
云技术是基于云计算商业模式应用的网络技术、信息技术、整合技术、管理平台技术、以及应用技术等的总称,可以组成资源池,按需所用,灵活便利。云计算技术将变成重要支撑。技术网络系统的后台服务需要大量的计算、存储资源。
示例的,图1中示出的服务器200可以是独立的物理服务器,也可以是多个物理服务器构成的服务器集群或者分布式系统,还可以是提供云服务、云数据库、云计算、云函数、云存储、网络服务、云通信、中间件服务、域名服务、安全服务、CDN、以及大数据和人工智能平台等基础云计算服务的云服务器。终端设备400可以是智能手机、平板电脑、笔记本电脑、台式计算机、智能音箱、智能手表等,但并不局限于此。终端设备400以及服务器200可以通过有线或无线通信方式进行直接或间接地连接,本申请实施例中不做限制。
在另一些实施例中,本申请实施例提供的代码覆盖率的测试处理方法还可以结合区块链技术实现,例如图1中示出的终端设备400和服务器200可以加入区块链网络而成为其中的一个节点,区块链网络中的不同节点之间可以存在信息连接,节点之间还可以通过上述信息连接进行信息传输,例如,本申请实施例提供的代码覆盖率的测试处理方法所相关的数据(例如基于多个用例得到的多份代码覆盖率数据文件、以及基于任务标识合并后得到的多份代码覆盖率信息文件)可保存在区块链网络中,从而保证了数据的可追溯性和安全性。
在一些实施例中,终端设备或服务器还可以通过运行计算机程序来实现本申请实施例提供的代码覆盖率的测试处理方法。举例来说,计算机程序可以是操作系统中的原生程序(例如,专用的代码覆盖率测试程序)或软件模块,例如,可以嵌入到任意程序中的代码覆盖率测试模块;还可以是本地(Native)应用程序(APP,Application),即需要在操作系统中安装才能运行的程序,例如图1中示出的客户端410。总而言之,上述计算机程序可以是任意形式的应用程序、模块或插件。
下面继续对图1中示出的服务器200的结构进行说明。参见图2,图2是本申请实施例提供的服务器200的结构示意图,图2所示的服务器200包括:至少一个处理器210、存储器240、至少一个网络接口220。服务器200中的各个组件通过总线系统230耦合在一起。可理解的,总线系统230用于实现这些组件之间的连接通信。总线系统230除包括数据总线之外,还包括电源总线、控制总线和状态信号总线。但是为了清楚说明起见,在图2中将各种总线都标为总线系统230。
处理器210可以是一种集成电路芯片,具有信号的处理能力,例如通用处理器、数字信号处理器(DSP,Digital Signal Processor),或者其他可编程逻辑器件、分立门或者晶体管逻辑器件、分立硬件组件等,其中,通用处理器可以是微处理器或者任何常规的处理器等。
存储器240可以是可移除的,不可移除的或其组合。示例性的硬件设备包括固态存储器,硬盘驱动器,光盘驱动器等。存储器240可选地包括在物理位置上远离处理器210的一个或多个存储设备。
存储器240包括易失性存储器或非易失性存储器,也可包括易失性和非易失性存储器两者。非易失性存储器可以是只读存储器(ROM,Read Only Memory),易失性存储器可以是随机存取存储器(RAM,Random Access Memory)。本申请实施例描述的存储器240旨在包括任意适合类型的存储器。
在一些实施例中,存储器240能够存储数据以支持各种操作,这些数据的示例包括程序、模块和数据结构或者其子集或超集,下面示例性说明。
操作系统241,包括用于处理各种基本系统服务和执行硬件相关任务的系统程序,例如框架层、核心库层、驱动层等,用于实现各种基础业务以及处理基于硬件的任务;
网络通信模块242,用于经由一个或多个(有线或无线)网络接口220到达其他计算设备,示例性的网络接口220包括:蓝牙、无线相容性认证(WiFi)、和通用串行总线(USB,Universal Serial Bus)等;
在一些实施例中,本申请实施例提供的基于人工智能的文本处理装置可以采用软件方式实现,图2示出了存储在存储器240中的基于人工智能的文本处理装置243,其可以是程序和插件等形式的软件,包括以下软件模块:获取模块2431、匹配模块2432、处理模块2433、合并模块2434、存储模块2435、创建模块2436、确定模块2437、比较模块2438和生成模块2439,这些模块是逻辑上的,因此根据所实现的功能可以进行任意的组合或进一步拆分。需要指出的是,在图2中为了方便表达,一次性示出了上述所有模块,但是不应视为在代码覆盖率的测试处理装置243排除了可以只包括获取模块2431、匹配模块2432、处理模块2433、合并模块2434和存储模块2435的实施,将在下文中说明各个模块的功能。
在另一些实施例中,本申请实施例提供的代码覆盖率的测试处理装置可以采用硬件方式实现,作为示例,本申请实施例提供的代码覆盖率的测试处理装置可以是采用硬件译码处理器形式的处理器,其被编程以执行本申请实施例提供的代码覆盖率的测试处理方法,例如,硬件译码处理器形式的处理器可以采用一个或多个应用专用集成电路(ASIC,Application Specific Integrated Circuit)、DSP、可编程逻辑器件(PLD,ProgrammableLogic Device)、复杂可编程逻辑器件(CPLD,Complex Programmable Logic Device)、现场可编程门阵列(FPGA,Field-Programmable Gate Array)或其他电子元件。
下面将结合本申请实施例提供的服务器的示例性应用和实施,说明本申请实施例提供的代码覆盖率的测试处理方法。示例的,参见图3,图3是本申请实施例提供的代码覆盖率的测试处理方法的流程示意图,将结合图3示出的步骤进行说明。
在步骤101中,获取多份代码覆盖率数据文件。
这里,每份代码覆盖率数据文件包括:基于用例测试代码时产生的数据文件(即Gcda文件)和对代码进行编译生成的符号文件(即Gcno文件)。
在一些实施例中,当需要对某个应用程序的源代码进行代码覆盖率测试时,为了能够完整且全面地对该应用程序的源代码进行测试,测试/开发人员可以针对该应用程序一次性编写多个测试用例,并基于所编写的多个测试用例对该应用程序进行代码覆盖率测试,从而得到多份代码覆盖率数据文件,其中,每份代码覆盖率数据文件包括Gcda文件和Gcno文件。
示例的,以待测试代码为应用程序A的源代码为例,假设测试人员针对应用程序A编写了10条测试用例,则可以通过代码覆盖率测试工具(例如Gcov、Lcov等)调用测试人员所编写的10条测试用例对应用程序A的源代码进行代码覆盖率测试,从而得到10份代码覆盖率数据文件,其中,每份代码覆盖率数据文件均包括对应的Gcda文件和Gcon文件。例如,以代码覆盖率测试工具为Gcov为例,Gcno文件可以是由-ftest-coverage指令产生的,它包含了重建基本块图和相应的块的源码的行号的信息,而Gcda文件可以是加了-fprofile-arcs编译参数的编译后的文件运行所产生的,它包含了弧跳变的次数和其他的概要信息。
在步骤102中,根据文件名对多份代码覆盖率数据文件进行匹配,得到多个数据集。
这里,每个数据集包括对应的一份数据文件(即Gcda文件)和一份符号文件(即Gcno文件)。
在一些实施例中,在获取多份代码覆盖率数据文件之后,可以根据文件名对多份代码覆盖率数据文件进行匹配,得到多个数据集,即将多份代码覆盖率数据文件分别包括的数据文件和符号文件中,具有相同文件名的数据文件和符号文件合并到同一个数据集中,也就是说,同一个数据集包括的数据文件和符号文件是具有相同的文件名的,即是针对同一个用例生成的数据文件和符号文件。
在另一些实施例中,参见图4,图4是本申请实施例提供的代码覆盖率的测试处理方法的流程示意图,如图4所示,在执行完图3示出的步骤102之后,还可以执行图4示出的步骤106,将结合图4示出的步骤进行说明。
在步骤106中,将多个数据集存入待处理队列中。
这里,可以预先创建待处理队列,并将在步骤102中得到的多个数据集存入待处理队列中,并在进程池创建完成后,将待处理队列中存储的多个数据集分别分发给进程池中的多个进行,从而并发处理多个数据集。
继续参见图3,在步骤103中,基于进程池包括的用于运行代码的多个进程,并行处理多个数据集,得到每个数据集对应的代码覆盖率信息子文件。
在一些实施例中,在执行图3示出的步骤103之前,还可以执行以下处理:创建进程池;根据待处理的数据集的数量、以及用于运行进程池的性能条件,确定进程池包括的进程的数量。
示例的,为了提高代码覆盖率的测试效率,服务器可以预先创建一个进程池,以基于进程池包括的多个进程来并发处理多个数据集,其中,进程池包括的进程的数量可以是根据待处理的数据集的数量、以及服务器的性能条件综合确定的,例如,当待处理的数量集的数量较多、且服务器的性能条件较好时,可以多创建几个进程放入进程池中,以加快数据集的处理效率;而当待处理的数据集的数量较少,或者服务器的性能条件较差时,可以少创建几个进程,以避免服务器系统资源的浪费或者由于进程数量过多对服务器的运行效率产生影响。
需要说明的是,当通过终端设备来执行本申请实施例提供的代码覆盖率的测试处理方法时,可以根据待处理的数据集的数量、以及终端设备的性能条件来确定进程池包括的进程的数量,如此,既能加快代码覆盖率的测试效率,又不会对终端设备的系统资源造成浪费,从而达到最佳的并发效果。
在另一些实施例中,图3示出的步骤103还可以通过图4示出的步骤1031和步骤1032实现,将结合图4示出的步骤进行说明。
在步骤1031中,从待处理队列中获取与多个进程相同数量的多个数据集,并将多个数据集分别分发给多个进程,通过每个进程各自处理分发到的一个数据集。
在一些实施例中,在创建进程池之后,可以从在步骤106中创建的待处理队列中(待处理队列中存有在步骤102中得到的多个数据集)获取与进程池包括的多个进程相同数量的多个数据集,并将多个数据集分别分发给多个进程,以通过每个进程各自处理分发到的一个数据集。
示例的,假设创建池包括5个进程,分别为进程1至进程5,则可以首先从待处理队列中读取5个数据集,分别为数据集1至数据集5,并将这5个数据集分别分发给这5个进程,以通过每个进程各自处理分发到的一个数据集,例如将数据集1分发给进程1,以通过进程1处理数据集1;将数据集2分发给进程2,以通过进程2处理数据集2;将数据集3分发给进程3,以通过进程3处理数据集3;将数据集4分发给进程4,以通过进程4处理数据集4;将数据集5分发给进程5,以通过进程5处理数据集5,如此,通过进程池包括的多个进程进行并行处理的方式,可以大大提高数据集的处理效率,从而提高代码覆盖率的测试效率。
在一些实施例中,可以通过以下方式实现上述的通过每个进程各自处理分发到的一个数据集:通过每个进程执行以下处理:获取数据集携带的参数,其中,参数包括输入路径、输出路径、以及格式参数;根据输入路径获取数据集包括的数据文件和符号文件;基于格式参数对数据集包括的数据文件和符号文件进行处理,得到符合格式需求的代码覆盖率信息子文件;将符合格式需求的代码覆盖率信息子文件存储至数据库中与输出路径对应的位置。
示例的,可以通过以下方式实现上述的基于格式参数对数据集包括的数据文件和符号文件进行处理,得到符合格式需求的代码覆盖率信息子文件:从数据集包括的数据文件和符号文件中获取代码覆盖率信息,其中,代码覆盖率信息是基于基本块和弧进行表征的;按照格式参数,对代码覆盖率信息进行格式转换;基于格式转换后的代码覆盖率信息,生成符合格式需求的代码覆盖率信息子文件,如此,通过在参数中增加格式参数的方式,能够保证最终生成的代码覆盖率信息子文件是符合测试/开发人员预期的格式需求的。
在一些实施例中,还可以通过以下方式实现上述的从数据集包括的数据文件和符号文件中获取代码覆盖率信息:从数据集包括的符号文件中获取程序流图信息,基于程序流图信息建立代码中每个函数的程序流图;从数据集包括的数据文件中获取已知的弧的执行次数,并将已知的弧的执行次数写入程序流图中;根据程序流图、以及已知的弧的执行次数,确定其他的弧与基本块的执行次数;基于所有弧与基本块的执行次数,确定代码对应的代码覆盖率信息,其中,代码覆盖率信息包括以下至少之一:函数信息、行数信息。
在步骤1032中,当多个进程中的任一进程处理完成时,从待处理队列中获取剩余的一个数据集,通过任一进程处理所述剩余的一个数据集,直至待处理队列中存储的所有数据集均处理完成。
在一些实施例中,当进程池包括的多个进程中的任一进程针对分发到的数据集处理完成时,可以从待处理队列中继续获取剩余的一个数据集,并将所获取的剩余的一个数据集分发给已经完成处理的任一进程,以通过任一进程处理所获取的剩余的一个数据集,直至待处理队列中存储的所有数据集均处理完成。
示例的,假设待处理队列中存储有10个数据集,分别为数据集1至数据集10,进程池包括4个进程,分别为进程1至进程4,则可以首先从待处理队列中读取4个数据集,分别为数据集1至数据集4,并将这4个数据集分别分发给进程池包括的4个进程进行并行处理,当这4个进程中的任一进程针对分发到的数据集处理完成时,例如假设进程3首先完成了针对分发到的数据集3的处理,则可以继续从待处理队列中获取数据集5,并将数据集5分发给进程3进行处理,随后假设进程4完成了针对分发到的数据集4的处理,则可以继续从待处理队列中获取数据集6,并将数据集6分发给进程4进行处理,直至待处理队列中存储的10个数据集均处理完成,从而得到这10个数据集分别对应的代码覆盖率信息子文件。
在一些实施例中,参见图5,图5是本申请实施例提供的代码覆盖率的测试处理方法的流程示意图,如图5所示,在执行完图3示出的步骤103之后,还可以执行图5示出的步骤107和步骤108,将结合图5示出的步骤进行说明。
在步骤107中,针对每个用例对应的多个代码覆盖率信息子文件,执行以下处理:获取用例对应的任务标识;将任务标识作为多个代码覆盖率信息子文件的前缀。
这里,不同用例对应的任务标识不同。
在一些实施例中,在得到每个数据集对应的代码覆盖率信息子文件之后,可以针对每个用例对应的多个代码覆盖率信息子文件,执行以下处理:获取用例对应的唯一的任务标识,并将所获取的任务标识作为多个代码覆盖率信息子文件的文件名的前缀,如此,后续可以基于任务标识将同一个用例对应的多个代码覆盖率信息子文件进行合并,得到该用例对应的一个合并后的代码覆盖率信息文件。
示例的,以用例A为例,首先获取用例A对应的任务标识A,接着针对用例A对应的多个代码覆盖率信息子文件,假设为代码覆盖率信息子文件1至代码覆盖率信息子文件4,则将任务标识A作为代码覆盖率信息子文件1至代码覆盖率信息子文件4的文件名的前缀,也就是说,代码覆盖率信息子文件1至代码覆盖率信息子文件4具有相同的前缀,均为任务标识A,如此,后续可以基于任务标识A将代码覆盖率信息子文件1至代码覆盖率信息子文件4合并成一个代码覆盖率信息文件(即用例A对应的一个代码覆盖率信息文件)。
在步骤108中,针对每个代码覆盖率信息子文件,执行以下处理:为代码覆盖率信息子文件设置第一后缀和第二后缀。
这里,第一后缀用于标识代码覆盖率信息子文件对应的所有的代码行,第二后缀用于标识代码覆盖率信息子文件对应的所有的代码行中被执行的代码行。
在一些实施例中,在得到每个数据集对应的代码覆盖率信息子文件之后,还可以针对每个代码覆盖率信息子文件,执行以下处理:为代码覆盖率信息子文件的文件名设置第一后缀(例如后缀Total,用于标识该代码覆盖率信息子文件对应的所有的代码行)和第二后缀(例如后缀Cov,用于标识该代码覆盖率信息子文件对应的所有的代码行中被执行的代码行),如此,可以通过第一后缀和第二后缀即可便携地确定出每个代码覆盖率信息子文件对应的所有的代码行、以及所有的代码行中被执行的代码行。
继续参见图3,在步骤104中,基于任务标识将多份代码覆盖率信息子文件合并为代码覆盖率信息文件。
在一些实施例中,在基于步骤107为每份代码覆盖率信息子文件的文件名分别设置对应的前缀之后,可以基于所设置的前缀(即任务标识)将多份代码覆盖率信息子文件合并为代码覆盖率信息文件,即将具有相同任务标识的多份代码覆盖率信息子文件合并成一份代码覆盖率信息文件,例如假设代码覆盖率信息子文件1至代码覆盖率信息子文件4的前缀为任务标识A,代码覆盖率信息子文件5至代码覆盖率信息子文件7的前缀为任务标识B,代码覆盖率信息子文件8至代码覆盖率信息子文件10的前缀为任务标识C,则可以将代码覆盖率信息子文件1至代码覆盖率信息子文件4合并成一个代码覆盖率信息文件(即对应用例A的代码覆盖率信息文件),将代码覆盖率信息子文件5至代码覆盖率信息子文件7合并成一个代码覆盖率信息文件(即对应用例B的代码覆盖率信息文件),将代码覆盖率信息子文件8至代码覆盖率信息子文件10合并成一个代码覆盖率信息文件(即对应用例C的代码覆盖率信息文件),如此,可以基于任务标识,将同一个用例对应的多个代码覆盖率信息子文件合并成一个代码覆盖率信息文件,以方便进行后续的处理。
在步骤105中,以键值对的形式存储多份代码覆盖率信息文件。
在一些实施例中,可以通过以下方式实现上述的以键值对的形式存储多份代码覆盖率信息文件:针对每个任务标识,执行以下处理:以任务标识为键、以任务标识对应的代码覆盖率信息文件为值进行存储。
示例的,在得到多份代码覆盖率信息文件之后,可以以键值对的形式存储多份代码覆盖率信息文件,例如假设在步骤104中得到4份代码覆盖率信息文件,分别为任务标识A对应的代码覆盖率信息文件1、任务标识B对应的代码覆盖率信息文件2、任务标识C对应的代码覆盖率信息文件3和任务标识D对应的代码覆盖率信息文件4,则可以将任务标识A至任务标识D为键、以任务标识A至任务标识D分别对应的代码覆盖率信息文件为值进行存储,如此,基于键值对的方式进行存储,减少了后续查找需要消耗的时间。
在一些实施例中,为了避免多个连接的创建和销毁带来的性能消耗,还可以执行以下处理:创建连接池(又称数据库连接池),其中,连接池包括多个连接(又称数据库连接);当接收到多个代码覆盖率信息文件分别对应的多个写入请求时,基于连接池包括的多个连接并行处理多个写入请求,以将多个代码覆盖率信息文件存入数据库中。
示例的,数据库连接池在初始化时可以将创建一定数量的数据库连接放到连接池中,这些数据库连接的数量可以由最小数据库连接数来设定,无论这些数据库连接是否被使用,连接池都将一直保证至少拥有这么多的连接数量,连接池的最大数据库连接数量限定了这个连接池能占有的最大连接数,当向连接池请求的连接数超过最大连接数量时,这些请求将被加入到等待队列中。其中,数据库连接池的最小连接数和最大连接数的设置需要考虑到以下几个因素:1、最小连接数:是连接池一直保持的数据库连接,所以如果对数据库连接的使用量不是很大,将会有大量的数据库连接资源被浪费;2、最大连接数:是连接池能申请的最大连接数,如果数据库连接请求超过次数,后面的数据库连接请求将被加入到等待队列中,这会影响以后的数据库操作;3、如果最小连接数与最大连接数相差很大,那么最先连接请求将会获利,之后超过最小连接数量的连接请求等价于建立一个新的数据库连接,不过,这些大于最小连接数的数据库连接在使用完后不会马上被释放,它们将被放到连接池中等待重复使用或是在连接池空间超时后被释放,如此,通过创建连接池的方式,避免了多个连接的创建和销毁带来的系统资源的消耗,进一步提高了代码覆盖率的测试效率。
在另一些实施例中,当被测试的代码为更新后的代码时,则还可以执行以下处理:将更新后的代码对应的代码覆盖率信息文件,与更新前的代码对应的代码覆盖率信息文件进行比较,得到增量的代码覆盖率信息文件;基于增量的代码覆盖率信息文件,生成代码覆盖率报告;根据代码覆盖率报告,确定更新后的代码对应的代码覆盖率测试结果。
示例的,以待测试代码为应用程序A的源代码为例,在对应用程序A进行更新之后,可以通过本申请实施例提供的代码覆盖率的测试处理方法分别得到更新后的应用程序A的源代码对应的代码覆盖率信息文件、以及更新前的应用程序A的源代码对应的代码覆盖率信息文件,接着将更新后的应用程序A的源代码对应的代码覆盖率信息文件,与更新前的应用程序A的源代码对应的代码覆盖率信息文件进行比较,得到增量的代码覆盖率信息文件,随后可以基于增量的代码覆盖率信息文件,生成对应的代码覆盖率报告,最后根据生成的代码覆盖率报告,确定出更新后的应用程序A的源代码对应的代码覆盖率测试结果。
本申请实施例提供的代码覆盖率的测试处理方法,首先根据文件名对多份待处理的代码覆盖率数据文件进行匹配,得到多个数据集,接着基于进程池包括的多个进程来并行处理多个数据集,得到每个数据集对应的代码覆盖率信息子文件,随后基于任务标识将多份代码覆盖率信息子文件进行合并,最后以键值对的形式存储合并得到的多份代码覆盖率信息文件,如此,针对待处理的数据集进行了并行化处理,大大提高了代码覆盖率的测试效率,并且最终得到的多份代码覆盖率信息文件是以键值对的形式进行存储,减少了后续的查找时间,进而大大提升了开发/测试人员的工作效率。
下面,将说明本申请实施例在一个实际的应用场景中的示例性应用。
相关技术中,通常是直接通过代码覆盖率测试工具(例如Lcov,一种GCC测试代码覆盖率的前端图形展示工具,它通过收集多个源文件的行、函数和分支等代码覆盖率信息,即收集程序执行之后生成的Gcda文件和Gcno文件,并且基于收集后的信息生成HTML页面)处理Gcda文件和Gcno文件,生成可读的Info格式(通过Lcov的geninfo脚本将Gcda文件和Gcno文件转化为Info格式的文件,Info文件包含一个或多个源文件对应的代码覆盖率信息,一个源文件对应一条记录,其中,记录包括带全路径的源代码文件名、覆盖行、以及执行次数等)的代码覆盖率信息文件,但是这一方法计算代码覆盖率的速度过慢,无法满足测试的需求。
示例的,参见图6,图6是相关技术提供的代码覆盖率的测试处理方法的流程示意图,如图6所示,相关技术提供的技术方案是利用Lcov直接生成代码覆盖率信息文件,其中,Lcov的具体处理流程如下:首先获取当前目录下所有的Gcda文件和Gcno文件,接着使用Gcov(一个测试代码覆盖率的程序工具,正确地使用它搭配GCC可以分析、帮助用户将代码写得更加高效,同时也可以帮助用户优化程序,可以收集到一些基础的性能统计数据,例如:每一行代码执行的频度、每个代码文件中实际被执行到的行数、以及每一个代码块执行使用的时间等)针对所获取的Gcda文件和Gcno文件进行处理,生成中间Gcov文件,然后遍历所有的中间Gcov文件,生成Info格式的文件,最后按需生成HTML格式的文件,以在前端进行展示。
然而,申请人发现:相关技术提供的方案中,中间的计算过程不仅是单线程的,而且会落地很多无用的中间文件,例如在使用Gcov处理Gcda文件和Gcno文件时可以并行执行,并且生成的Gcov文件可以不落地,此外,在处理Gcov文件生成单个Info文件时也可以并行执行,并且生成的Info文件也可以不落地,另外,相关技术提供的方案中,代码覆盖率数据展示文件也并不全是必需的。
也就是说,相关技术提供的方案存在的主要问题在于计算代码覆盖率数据的速度过慢,例如对于500+的代码覆盖率数据文件而言,相关技术提供的方案通常需要五分钟左右的计算时间,这个计算速度会影响到后面代码覆盖率结果合并、展示、以及反馈等流程,不利于代码覆盖率测试的进行,对于测试人员来说使用体验也不佳。
此外,申请人还发现:相关技术在计算代码覆盖率数据时速度较慢的主要原因在于相关技术提供的方案对于文件的输入输出(IO,Input Output)操作非常频繁、以及串行的遍历所有的代码覆盖率数据文件,并且Lcov处理中间文件的速度也不尽如人意,导致整个计算过程非常缓慢。
鉴于此,本申请实施例提供一种代码覆盖率的测试处理方法,通过从Lcov工具的源代码中抽离出Gcov工具,直接对Gcov工具的源代码进行修改,抛弃掉Lcov的中间处理过程,并且针对所有的代码覆盖率数据文件进行了并行化的划分处理。同时,每一个文件会以键值对的形式存储在数据库(例如Redis,一个开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API,它通常被称为数据结构服务器,因为值(Value)可以是字符串(String)、哈希(Map)、列表(List)、集合(Sets)和有序集合(Sorted Sets)等类型)中,并且可以通过键的前缀来识别单次任务(例如测试人员在进行测试时,可以一次性编写多个测试用例,其中,每个测试用例对应一个任务),从而便于对于任务级别的代码覆盖率进行差异(Diff)操作、以及合并操作等。其中,Diff操作是指通过Gcda文件和Gcno文件生成的代码覆盖率是单个文件的全部的信息,而测试人员往往只想关注开发修改过的代码行的内容,所以这里需要一个Diff的操作,因此在Redis里面做一个差集Diff操作的时间复杂度是O(1),相较于直接在文件的维度进行操作更有优势,同理,合并操作也是如此。例如,对于千份的代码覆盖率数据文件,采用本申请实施例提供的代码覆盖率的测试处理方法,并行化后处理速度大大提升,最终可以在秒级完成代码覆盖率数据的计算,根据木桶效应,影响本次代码覆盖率计算耗时的是这些代码覆盖率数据文件里面耗时最长的一份代码覆盖率数据文件。
本申请实施例提供的代码覆盖率的测试处理方法可以用于各种利用Gcda文件和Gcno文件生成代码覆盖率信息文件的计算场景,并且通过将计算得到的代码覆盖率信息存储到Redis键值中,能够快速完成代码覆盖率的各项技术需求的提取,例如对于单份代码覆盖率信息文件的Diff操作、以及多份代码覆盖率信息文件的合并操作、以及部分文件的过滤规则配置等,例如即时通信客户端(例如企业微信)的后台代码覆盖率计算、企业微信IOS端的代码覆盖率计算、以及企业微信MAC端的代码覆盖率计算等,可以实现更高效的计算。
下面对本申请实施例提供的代码覆盖率的测试处理方法进行具体说明。
本申请实施例提供的代码覆盖率的测试处理方法,针对大量已上传的代码覆盖率数据文件,例如Gcda文件和Gcno文件进行快速计算,得到测试人员所需的代码覆盖率测试结果报告。针对相关技术中使用Lcov进行处理代码覆盖率数据文件的方法存在速度较为缓慢的问题,本申请实施例从GCC4.4+版本中抽离出Gcov工具进行修改,使其满足代码覆盖率数据计算处理、输出格式的要求,为了方便描述,本申请实施例以Gcov4来表示修改后的Gcov工具。
示例的,参见图7,图7是本申请实施例提供的单个Gcov4的处理流程示意图,如图7所示,Gcov4通过处理输入参数来记录输入路径(例如待处理的一组Gcda文件和Gcno文件所在的路径)、输出路径(例如生成的Info文件所在的路径)、以及输出的格式需求(图7中未示出),为了满足直接输出Info格式的文件的需求,这里加入了新的格式参数-i,通过该格式参数可以直接判断输出的文件是否为Info格式的文件,并且可以保持Gcov其他的功能不变,从而能够在最小成本的代价下修改Gcov的源代码,在不影响原有功能的同时添加了新的需求功能。并且,在使用Gcov4时,可以仅传入一组相应的Gcda文件和Gcno文件,方便后续以文件的维度进行并发处理。
下面对Gcda文件和Gcno文件的处理过程进行说明。
处理Gcda文件和Gcno文件的过程是从这两个文件中读取代码覆盖率信息,并储存在Gcov4的数据结构中,由于Gcda文件和Gcno文件的代码覆盖率信息是基于基本块(Block_Info)以及弧(ARC_Info)来表示的,因此Gcov4需要从基本块以及弧信息中抽取出函数覆盖、行覆盖等维度的代码覆盖率信息、并以行数信息(Line_Info)、以及函数信息(Function_Info)等进行表达。而整个读取基本块及弧的过程就是在遍历整个文件的执行链路的过程,需要对基本块、弧的前继(Pred)以及后续(Succ)进行判断。
最后在生成Info格式的文件的输出步骤中(即将生成的规范格式的代码覆盖率信息写入到Info文件),需要从上面存储着代码覆盖率信息的行数信息、以及函数信息进行链路遍历,而代码覆盖率的展示的维度只需要在行的维度,例如参见图8,图8是本申请实施例提供的Info文件的输出示意图,如图8所示,仅以行的维度展示最终得到的代码覆盖率信息,剔除了无关的信息,从而可以减少文件的读写,并且,图8中示出的DA后面的两个数字分别表示代码行号、以及当前行被执行到的次数,例如DA:23,0表示当前的代码行为第23行,当前行被执行到的次数为0,DA:25,1表示当前的代码行为第25行,当前行被执行到的次数为1,end_of_record表示一条记录结束符。
此外,还需要说明的是,Gcov4在针对传入的一组Gcda文件和Gcno文件处理完成后,可以释放之前记录的数据结构空间,以供下一组Gcda文件和Gcno文件使用,即将从下一组Gcda文件和Gcno文件中读取的代码覆盖率信息存储到Gcov4的数据结构中。
在完成Gcov4的修改之后,本申请实施例可以以代码覆盖率数据文件的维度进行并发计算,示例的,参见图9,图9是本申请实施例提供的多个Gcov4并发处理的流程示意图,如图9所示,输入的是测试过程中产生的所有的代码覆盖率数据文件,包括Gcda文件和Gcno文件,接着根据文件名将多份代码覆盖率数据文件进行匹配,得到多个数据集,其中,每个数据集包括对应的一个Gcda文件和Gcno文件,随后将这样的数据集存入待处理队列中,等待进程池分发对应的进程进行计算处理,例如可以根据计算机器的条件、以及待计算的代码覆盖率数据文件的数量来设置进程池的大小,从而达到最佳的并发处理效果。
每个数据集对应的一份Gcda文件和Gcno文件在计算完成后都会生成多份Info格式的文件(对应于上述的代码覆盖率信息子文件),如果在并发后继续使用文件进行合并,这将降低并发带来的计算优势。因此计算后的结果可以以任务的级别存储在Redis中,从而可以在Redis内部完成更精细化的覆盖率操作,例如利用Redis集合的操作能在计算过程中就完成合并的操作。
Redis对于代码覆盖率信息文件的键值设计如图10所示,前缀TaskID用于确定唯一的一份代码覆盖率信息文件(即一个TaskID对应一个测试用例产生的所有代码覆盖率的计算数据,而这份数据是由多个Info文件组成的,因此需要将同一个TaskID对应的多份Info文件合并在一起),此外,File1、File20用于标识文件的名字,后缀Total(对应于上述的第一后缀)用于标识该文件所有的代码行号,后缀Cov(对应于上述的第二后缀)用于标识该文件所有的覆盖行(即所有被执行到的代码行),对应到Info格式就是右边的转换结果,此外,针对文件中被执行到的代码行和没有被执行到的代码行可以以不同的样式进行区分,例如针对被执行到的代码行可以用斜线进行表示,举例来说,对于文件名为File1的文件,该文件所有的代码行号包括1、2、4,其中,第1行和第4行代码被执行到,即对应于右侧的DA:1,1、DA:2,0、DA:4,1;而对于文件名为File20的文件,该文件所有的代码行号同样包括1、2、4,其中,仅第4行代码被执行到,即对应于右侧的DA:1,0、DA:2,0、DA:4,1,可以看出,这种结构的好处在于不仅减少了文件的存储,同时还便于不同任务(Task)对应的代码覆盖率信息文件之间的合并、Diff等操作。
除此之外,参见图11,图11是本申请实施例提供的Redis连接池的示意图,如图11所示,对于多份Gcda文件和Gcno文件,在调用多个Gcov4处理线程进行多次计算时(例如多个Gcov4处理线程同时向Redis连接池申请读写覆盖率连接,即Redis连接池同时接收到多个申请将计算得到的代码覆盖率信息文件存入Redis的连接请求),由于计算的结果(即代码覆盖率信息文件)是存储在Redis中,因此这里不能建立起多个Redis连接,因为多个连接的创建和销毁会带来性能的消耗,因此这里在单个任务的数据处理过程中可以利用Redis连接池的机制(即事先初始化一定数量的连接,放入到连接池中,当需要操作Redis时,例如需要将计算结果存入Redis时,可以直接从Redis连接池中取出连接即可,这样可以节省创建和销毁连接带来的性能消耗),实现动态管理连接,从而减少连接的创建和销毁带来的性能消耗,进而达到高效写入的效果。此外,对于Redis代码覆盖率数据的读取,为了加快对于整份任务数据的读取,这里还可以采用二级缓存的机制,将单次任务对应的代码覆盖率信息文件以键(Key)缓存起来,即以该任务对应的任务标识为Key,以任务标识对应的代码覆盖率信息文件为Value进行存储,从而减少查找Key需要的时间。
本申请实施例提供的代码覆盖率的测试处理方法通过修改Gcov的源代码,再对其进行文件维度的并行化处理,以及将计算得到的代码覆盖率信息文件(包含有对应的代码覆盖率数据)按照键值对的形式存储在Redis集合中,便于后续对于版本的差异(Diff)、版本的合并操作,减少了文件落地的繁琐操作,从而降低耗时。
下面继续结合实验数据对本申请实施例提供的代码覆盖率的测试处理方法的有益效果进行说明。
示例的,参见表1,表1是本申请实施例提供的处理速度对比表,如表1所示,对于200+的代码覆盖率数据文件(包括Gcda文件和Gcno文件),并发使用本申请实施例提供的修改后的Gcov(即Gcov4)进行代码覆盖率数据的计算能够在秒级完成,例如对于240份文件,采用本申请实施例提供的并发Gcov4能够在2.09秒完成,而使用相关技术提供的Lcov则完成127秒才能完成,也就是说,相较于相关技术提供的Lcov,本申请实施例提供的技术方案达到了约60倍的加速效果。
表1处理速度对比表
并且,在日常的代码覆盖率的测试使用中,代码覆盖率数据以Redis键值对的形式进行存储,从前端的展示到后台对数据进行二次处理,减少了70%不必要文件的落地,减少了对磁盘的压力。另外,Redis的读取比文件读取更加快速,从而使得前端的展示速度也更快,整个代码覆盖率的测试流程也有了3-4倍的速度提升。
下面继续说明本申请实施例提供的代码覆盖率的测试处理装置243的实施为软件模块的示例性结构,在一些实施例中,如图2所示,存储在存储器240的代码覆盖率的测试处理装置243中的软件模块可以包括:获取模块2431、匹配模块2432、处理模块2433、合并模块2434和存储模块2435。
获取模块2431,用于获取多份代码覆盖率数据文件,其中,每份代码覆盖率数据文件包括:基于用例测试代码时产生的数据文件和对代码进行编译生成的符号文件;匹配模型2432,用于根据文件名对多份代码覆盖率数据文件进行匹配,得到多个数据集,其中,每个数据集包括对应的一份数据文件和一份符号文件;处理模块2433,用于基于进程池包括的用于运行代码的多个进程,并行处理多个数据集,得到每个数据集对应的代码覆盖率信息子文件;合并模块2434,用于基于任务标识将多份代码覆盖率信息子文件合并为代码覆盖率信息文件;存储模块2435,用于以键值对的形式存储多份代码覆盖率信息文件。
在一些实施例中,存储模块2435,还用于将多个数据集存入待处理队列中;处理模块2433,还用于从待处理队列中获取与多个进程相同数量的多个数据集,并将多个数据集分别分发给多个进程,通过每个进程各自处理分发到的一个数据集;当多个进程中的任一进程处理完成时,从待处理队列中获取剩余的一个数据集,通过任一进程处理剩余的一个数据集,直至待处理队列中存储的所有数据集均处理完成。
在一些实施例中,处理模块2433,还用于通过每个进程执行以下处理:获取数据集携带的参数,其中,参数包括输入路径、输出路径、以及格式参数;根据输入路径获取数据集包括的数据文件和符号文件;基于格式参数对数据集包括的数据文件和符号文件进行处理,得到符合格式需求的代码覆盖率信息子文件;将符合格式需求的代码覆盖率信息子文件存储至数据库中与输出路径对应的位置。
在一些实施例中,处理模块2433,还用于从数据集包括的数据文件和符号文件中获取代码覆盖率信息,其中,代码覆盖率信息是基于基本块和弧进行表征的;按照格式参数,对代码覆盖率信息进行格式转换;基于格式转换后的代码覆盖率信息,生成符合格式需求的代码覆盖率信息子文件。
在一些实施例中,处理模块2433,还用于从数据集包括的符号文件中获取程序流图信息,基于程序流图信息建立代码中每个函数的程序流图;从数据集包括的数据文件中获取已知的弧的执行次数,并将已知的弧的执行次数写入程序流图中;根据程序流图、以及已知的弧的执行次数,确定其他的弧与基本块的执行次数;基于所有弧与基本块的执行次数,确定代码对应的代码覆盖率信息,其中,代码覆盖率信息包括以下至少之一:函数信息、行数信息。
在一些实施例中,处理模块2433,还用于针对每个用例对应的多个代码覆盖率信息子文件,执行以下处理:获取用例对应的任务标识;将任务标识作为多个代码覆盖率信息子文件的前缀;其中,不同用例对应的任务标识不同。
在一些实施例中,处理模块2433,还用于针对每个代码覆盖率信息子文件,执行以下处理:为代码覆盖率信息子文件设置第一后缀和第二后缀,其中,第一后缀用于标识代码覆盖率信息子文件对应的所有的代码行,第二后缀用于标识代码覆盖率信息子文件对应的所有的代码行中被执行的代码行。
在一些实施例中,代码覆盖率的测试处理装置243还包括创建模块2436,用于创建进程池;代码覆盖率的测试处理装置243还包括确定模块2437,用于根据待处理的数据集的数量、以及用于运行进程池的性能条件,确定进程池包括的进程的数量。
在一些实施例中,创建模块2436,还用于创建连接池,其中,连接池包括多个连接;处理模块2433,还用于当接收到多个代码覆盖率信息文件分别对应的多个写入请求时,基于连接池包括的多个连接并行处理多个写入请求,以将多个代码覆盖率信息文件存入数据库中。
在一些实施例中,存储模块2435,还用于针对每个任务标识,执行以下处理:以任务标识为键、以任务标识对应的代码覆盖率信息文件为值进行存储。
在一些实施例中,被测试的代码为更新后的代码;代码覆盖率的测试处理装置243还包括比较模块2438,用于将更新后的代码对应的代码覆盖率信息文件,与更新前的代码对应的代码覆盖率信息文件进行比较,得到增量的代码覆盖率信息文件;代码覆盖率的测试处理装置243还包括生成模块2439,用于基于增量的代码覆盖率信息文件,生成代码覆盖率报告;确定模块2437,还用于根据代码覆盖率报告,确定更新后的代码对应的代码覆盖率测试结果。
需要说明的是,本申请实施例中关于装置的描述,与上文中代码覆盖率的测试处理方法的实现是类似的,并具有相似的有益效果,因此不做赘述。对于本申请实施例提供的代码覆盖率的测试处理装置中未尽的技术细节,可以根据图3-5任一附图的说明而理解。
本申请实施例提供了一种计算机程序产品或计算机程序,该计算机程序产品或计算机程序包括计算机指令,该计算机指令存储在计算机可读存储介质中。计算机设备的处理器从计算机可读存储介质读取该计算机指令,处理器执行该计算机指令,使得该计算机设备执行本申请实施例上述的代码覆盖率的测试处理方法。
本申请实施例提供一种存储有可执行指令的计算机可读存储介质,其中存储有可执行指令,当可执行指令被处理器执行时,将引起处理器执行本申请实施例提供的代码覆盖率的测试处理方法,例如,如图3-5任一附图示出的代码覆盖率的测试处理方法。
在一些实施例中,计算机可读存储介质可以是FRAM、ROM、PROM、EPROM、EEPROM、闪存、磁表面存储器、光盘、或CD-ROM等存储器;也可以是包括上述存储器之一或任意组合的各种设备。
在一些实施例中,可执行指令可以采用程序、软件、软件模块、脚本或代码的形式,按任意形式的编程语言(包括编译或解释语言,或者声明性或过程性语言)来编写,并且其可按任意形式部署,包括被部署为独立的程序或者被部署为模块、组件、子例程或者适合在计算环境中使用的其它单元。
作为示例,可执行指令可以但不一定对应于文件系统中的文件,可以可被存储在保存其它程序或数据的文件的一部分,例如,存储在超文本标记语言(HTML,Hyper TextMarkup Language)文档中的一个或多个脚本中,存储在专用于所讨论的程序的单个文件中,或者,存储在多个协同文件(例如,存储一个或多个模块、子程序或代码部分的文件)中。
作为示例,可执行指令可被部署为在一个计算设备上执行,或者在位于一个地点的多个计算设备上执行,又或者,在分布在多个地点且通过通信网络互连的多个计算设备上执行。
综上所述,本申请实施例首先根据文件名对多份待处理的代码覆盖率数据文件进行匹配,得到多个数据集,接着基于进程池包括的多个进程来并行处理多个数据集,得到每个数据集对应的代码覆盖率信息子文件,随后基于任务标识将多份代码覆盖率信息子文件进行合并,最后以键值对的形式存储合并得到的多份代码覆盖率信息文件,如此,针对待处理的数据集进行了并行化处理,大大提高了代码覆盖率的测试效率,并且最终得到的多份代码覆盖率信息文件是以键值对的形式进行存储,减少了后续的查找时间,进而大大提升了开发/测试人员的工作效率。
以上所述,仅为本申请的实施例而已,并非用于限定本申请的保护范围。凡在本申请的精神和范围之内所作的任何修改、等同替换和改进等,均包含在本申请的保护范围之内。
Claims (15)
1.一种代码覆盖率的测试处理方法,其特征在于,所述方法包括:
获取多份代码覆盖率数据文件,其中,每份所述代码覆盖率数据文件包括:基于用例测试代码时产生的数据文件和对所述代码进行编译生成的符号文件;
根据文件名对所述多份代码覆盖率数据文件进行匹配,得到多个数据集,其中,每个所述数据集包括对应的一份所述数据文件和一份所述符号文件;
基于进程池包括的用于运行所述代码的多个进程,并行处理所述多个数据集,得到每个所述数据集对应的代码覆盖率信息子文件;
基于任务标识将多份所述代码覆盖率信息子文件合并为代码覆盖率信息文件,并以键值对的形式存储多份所述代码覆盖率信息文件。
2.根据权利要求1所述的方法,其特征在于,在得到多个数据集之后,所述方法还包括:
将所述多个数据集存入待处理队列中;
所述基于进程池包括的用于运行所述代码的多个进程,并行处理所述多个数据集,包括:
从所述待处理队列中获取与所述多个进程相同数量的多个数据集,并将所述多个数据集分别分发给所述多个进程,通过每个所述进程各自处理分发到的一个数据集;
当所述多个进程中的任一进程处理完成时,从所述待处理队列中获取剩余的一个数据集,通过所述任一进程处理所述剩余的一个数据集,直至所述待处理队列中存储的所有数据集均处理完成。
3.根据权利要求2所述的方法,其特征在于,所述通过每个所述进程各自处理分发到的一个数据集,包括:
通过每个所述进程执行以下处理:
获取所述数据集携带的参数,其中,所述参数包括输入路径、输出路径、以及格式参数;
根据所述输入路径获取所述数据集包括的数据文件和符号文件;
基于所述格式参数对所述数据集包括的数据文件和符号文件进行处理,得到符合格式需求的代码覆盖率信息子文件;
将所述符合格式需求的代码覆盖率信息子文件存储至数据库中与所述输出路径对应的位置。
4.根据权利要求3所述的方法,其特征在于,所述基于所述格式参数对所述数据集包括的数据文件和符号文件进行处理,得到符合格式需求的代码覆盖率信息子文件,包括:
从所述数据集包括的数据文件和符号文件中获取代码覆盖率信息,其中,所述代码覆盖率信息是基于基本块和弧进行表征的;
按照所述格式参数,对所述代码覆盖率信息进行格式转换;
基于格式转换后的所述代码覆盖率信息,生成符合格式需求的代码覆盖率信息子文件。
5.根据权利要求4所述的方法,其特征在于,所述从所述数据集包括的数据文件和符号文件中获取代码覆盖率信息,包括:
从所述数据集包括的符号文件中获取程序流图信息,基于所述程序流图信息建立所述代码中每个函数的程序流图;
从所述数据集包括的数据文件中获取已知的弧的执行次数,并将所述已知的弧的执行次数写入所述程序流图中;
根据所述程序流图、以及所述已知的弧的执行次数,确定其他的弧与基本块的执行次数;
基于所有弧与基本块的执行次数,确定所述代码对应的代码覆盖率信息,其中,所述代码覆盖率信息包括以下至少之一:函数信息、行数信息。
6.根据权利要求1所述的方法,其特征在于,在得到每个所述数据集对应的代码覆盖率信息子文件之后,所述方法还包括:
针对每个所述用例对应的多个代码覆盖率信息子文件,执行以下处理:
获取所述用例对应的任务标识;
将所述任务标识作为所述多个代码覆盖率信息子文件的前缀;
其中,不同用例对应的任务标识不同。
7.根据权利要求6所述的方法,其特征在于,所述方法还包括:
针对每个所述代码覆盖率信息子文件,执行以下处理:
为所述代码覆盖率信息子文件设置第一后缀和第二后缀,其中,所述第一后缀用于标识所述代码覆盖率信息子文件对应的所有的代码行,所述第二后缀用于标识所述代码覆盖率信息子文件对应的所有的代码行中被执行的代码行。
8.根据权利要求1所述的方法,其特征在于,在基于进程池包括的用于运行所述代码的多个进程,并行处理所述多个数据集之前,所述方法还包括:
创建所述进程池;
根据待处理的数据集的数量、以及用于运行所述进程池的性能条件,确定所述进程池包括的进程的数量。
9.根据权利要求1所述的方法,其特征在于,所述方法还包括:
创建连接池,其中,所述连接池包括多个连接;
当接收到多个所述代码覆盖率信息文件分别对应的多个写入请求时,基于所述连接池包括的所述多个连接并行处理所述多个写入请求,以将多个所述代码覆盖率信息文件存入数据库中。
10.根据权利要求1所述的方法,其特征在于,所述以键值对的形式存储多份所述代码覆盖率信息文件,包括:
针对每个所述任务标识,执行以下处理:
以所述任务标识为键、以所述任务标识对应的代码覆盖率信息文件为值进行存储。
11.根据权利要求1所述的方法,其特征在于,所述代码为更新后的代码;所述方法还包括:
将所述更新后的代码对应的代码覆盖率信息文件,与更新前的代码对应的代码覆盖率信息文件进行比较,得到增量的代码覆盖率信息文件;
基于所述增量的代码覆盖率信息文件,生成代码覆盖率报告;
根据所述代码覆盖率报告,确定所述更新后的代码对应的代码覆盖率测试结果。
12.一种代码覆盖率的测试处理装置,其特征在于,所述装置包括:
获取模块,用于获取多份代码覆盖率数据文件,其中,每份所述代码覆盖率数据文件包括:基于用例测试代码时产生的数据文件和对所述代码进行编译生成的符号文件;
匹配模型,用于根据文件名对所述多份代码覆盖率数据文件进行匹配,得到多个数据集,其中,每个所述数据集包括对应的一份所述数据文件和一份所述符号文件;
处理模块,用于基于进程池包括的用于运行所述代码的多个进程,并行处理所述多个数据集,得到每个所述数据集对应的代码覆盖率信息子文件;
合并模块,用于基于任务标识将多份所述代码覆盖率信息子文件合并为代码覆盖率信息文件;
存储模块,用于以键值对的形式存储多份所述代码覆盖率信息文件。
13.一种电子设备,其特征在于,所述电子设备包括:
存储器,用于存储可执行指令;
处理器,用于执行所述存储器中存储的可执行指令时,实现权利要求1至11任一项所述的代码覆盖率的测试处理方法。
14.一种计算机可读存储介质,存储有可执行指令,其特征在于,所述可执行指令被处理器执行时实现权利要求1至11任一项所述的代码覆盖率的测试处理方法。
15.一种计算机程序产品,包括计算机程序或指令,其特征在于,所述计算机程序或指令被处理器执行时实现权利要求1至11任一项所述的代码覆盖率的测试处理方法。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202111222862.5A CN115994085A (zh) | 2021-10-20 | 2021-10-20 | 代码覆盖率的测试处理方法、装置、设备及存储介质 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202111222862.5A CN115994085A (zh) | 2021-10-20 | 2021-10-20 | 代码覆盖率的测试处理方法、装置、设备及存储介质 |
Publications (1)
Publication Number | Publication Date |
---|---|
CN115994085A true CN115994085A (zh) | 2023-04-21 |
Family
ID=85989255
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN202111222862.5A Pending CN115994085A (zh) | 2021-10-20 | 2021-10-20 | 代码覆盖率的测试处理方法、装置、设备及存储介质 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN115994085A (zh) |
Cited By (2)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN116610577A (zh) * | 2023-05-25 | 2023-08-18 | 成都融见软件科技有限公司 | 一种覆盖率获取方法 |
CN116627974A (zh) * | 2023-05-25 | 2023-08-22 | 成都融见软件科技有限公司 | 一种覆盖率存储系统 |
-
2021
- 2021-10-20 CN CN202111222862.5A patent/CN115994085A/zh active Pending
Cited By (4)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN116610577A (zh) * | 2023-05-25 | 2023-08-18 | 成都融见软件科技有限公司 | 一种覆盖率获取方法 |
CN116627974A (zh) * | 2023-05-25 | 2023-08-22 | 成都融见软件科技有限公司 | 一种覆盖率存储系统 |
CN116610577B (zh) * | 2023-05-25 | 2024-01-26 | 成都融见软件科技有限公司 | 一种覆盖率获取方法 |
CN116627974B (zh) * | 2023-05-25 | 2024-02-09 | 成都融见软件科技有限公司 | 一种覆盖率存储系统 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN109542791B (zh) | 一种基于容器技术的程序大规模并发评测方法 | |
CN109951547B (zh) | 事务请求并行处理方法、装置、设备和介质 | |
CN108280023B (zh) | 任务执行方法、装置和服务器 | |
US20130263090A1 (en) | System and method for automated testing | |
CN112104709B (zh) | 智能合约的处理方法、装置、介质及电子设备 | |
US20160337469A1 (en) | Automated service interface optimization | |
CN107025167B (zh) | 在处理器追踪日志中使用编译器类型信息进行数据流分析的方法和设备 | |
CN112394942B (zh) | 基于云计算的分布式软件开发编译方法及软件开发平台 | |
CN110944048B (zh) | 业务逻辑配置方法及装置 | |
US20170220613A1 (en) | Systems and methods for database orientation transformation | |
CN115994085A (zh) | 代码覆盖率的测试处理方法、装置、设备及存储介质 | |
CN107451062B (zh) | 一种用户界面遍历测试方法、装置、服务器、存储介质 | |
CN109614325B (zh) | 一种确定控件属性的方法及装置、电子设备和存储介质 | |
CN107391528B (zh) | 前端组件依赖信息搜索方法及设备 | |
US9116714B2 (en) | Methods and systems for file processing | |
CN114356964A (zh) | 数据血缘构建方法、装置、存储介质及电子设备 | |
CN112860264B (zh) | 一种抽象语法树重构方法及装置 | |
CN112559525B (zh) | 数据检查系统、方法、装置和服务器 | |
CN107526639B (zh) | 资源编排的方法、介质、装置和计算设备 | |
CN113238739A (zh) | 一种插件开发和数据获取方法、装置、电子设备及介质 | |
CN105573763A (zh) | 一种支持rtos的嵌入式系统建模方法 | |
CN111309297B (zh) | 脚本开发系统及方法 | |
US20190317877A1 (en) | Application state monitoring | |
CN115167822A (zh) | 分支代码合并方法、装置、设备和存储介质 | |
EP3907602A1 (en) | Trustworthy application integration |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
REG | Reference to a national code |
Ref country code: HK Ref legal event code: DE Ref document number: 40086402 Country of ref document: HK |