CN114168454B - 一种基于动态插桩-销桩技术的异步测试方法 - Google Patents
一种基于动态插桩-销桩技术的异步测试方法 Download PDFInfo
- Publication number
- CN114168454B CN114168454B CN202111391660.3A CN202111391660A CN114168454B CN 114168454 B CN114168454 B CN 114168454B CN 202111391660 A CN202111391660 A CN 202111391660A CN 114168454 B CN114168454 B CN 114168454B
- Authority
- CN
- China
- Prior art keywords
- pile
- test
- point
- code
- processing
- 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.)
- Active
Links
Images
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F11/00—Error detection; Error correction; Monitoring
- G06F11/36—Preventing errors by testing or debugging software
- G06F11/362—Software debugging
- G06F11/3636—Software debugging by tracing the execution of the program
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F11/00—Error detection; Error correction; Monitoring
- G06F11/36—Preventing errors by testing or debugging software
- G06F11/362—Software debugging
- G06F11/3644—Software debugging by instrumenting at runtime
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F11/00—Error detection; Error correction; Monitoring
- G06F11/36—Preventing errors by testing or debugging software
- G06F11/362—Software debugging
- G06F11/366—Software debugging using diagnostics
Landscapes
- Engineering & Computer Science (AREA)
- Theoretical Computer Science (AREA)
- Computer Hardware Design (AREA)
- Quality & Reliability (AREA)
- Physics & Mathematics (AREA)
- General Engineering & Computer Science (AREA)
- General Physics & Mathematics (AREA)
- Debugging And Monitoring (AREA)
Abstract
本发明公开了一种基于动态插桩‑销桩技术的异步测试方法,采用动态测试用例和动态测试预期技术,在执行过程中,根据程序运行结果同预期进行比较来判断一致性,并动态生成脚本形成新的测试用例;生成的用例识别被测程序动态生成控件特征和数据特性,并针对性的生成输入参数和预期值;这些参数和预期难以在程序前进行准确预估,并通过动态测试用例开展后续测试。本发明减少了被测软件的性能损失和异常情况,避免了测试过程延迟,提升了测试的灵活性。
Description
技术领域
本发明属于软件测试技术领域,尤其涉及一种基于动态插桩-销桩技术的异步测试方法。
背景技术
现有测试技术中,为获取软件中间状态,通常会采用插桩技术。即在程序执行代码的内部嵌入测试模块,或着嵌入程序跳转代码以便转到指定测试程序。
插桩方式分两类:
a)静态插桩
利用编译过程将桩代码插入程序。实现方法有两种:在源代码中插入桩源代码然后编译成二进制代码,称为源代码插桩方式;在编译过程中编译器嵌入二进制代码,称为二进制插桩方式。
b)动态插桩
利用程序运行期间加载桩代码到程序进程空间,并在测试点处执行测试程序。实现方法有两种:通过设置断点并在断点处跳转到测试桩程序,称为断点方式;另一种通过加载时修改测试点处代码,插入桩代码,称为注入方式。
静态插桩在传统软件测试中使用较多,典型的例子就是通过插入print语句输出变量,也可采用更复杂的处理。静态插桩增大软件程序映像,加载后,运行所有可达桩代码,对软件运行性能影响较大。
动态插桩不会导致软件程序映像发生改变,并且非常灵活,对软件运行性能影响则有插桩策略决定。
断点方式多次调用INT3系统中断,也会造成程序运行速度变慢。由于系统中断不能嵌套调用,否则导致测试过程发生异常。
注入方式的动态插桩具有灵活快速,而且可以嵌套插桩,适应复杂的插桩要求。但是注入方式的接口代码处理比较复杂,需要使用者对被测软件的二进制代码特性有很深的了解,加大了操作和推广难度。
静态插桩会导致软件程序映像发生改变,造成编译后的被测软件代码冗余大,运行速度变慢,造成严重性能问题。插桩点选择缺乏灵活性,容易反复在同一个插桩点调用相同的测试模块,对相关代码的运行输出带来混乱,如果代码是不可重入的,则插桩可导致软件运行异常。甚至由于测试代码自身可能存在缺陷,导致该测试版本的软件引入缺陷。
动态插桩不会导致软件程序映像发生改变,并且非常灵活,对软件运行性能影响较小。但是传统上采用的断点方式是调用INT3系统中断,由于系统中断不能嵌套调用,否则会导致测试过程发生异常,因此缺乏灵活性,无法完成复杂测试处理。
自动化测试通过程序代替人工与被测软件进行交互,实现对被测软件的功能和性能等指标进行验证。从实施的角度包含三个方面:
a)自动数据产生(模拟器)
通过软件根据需求和接口定义产生符合被测软件输入条件的数据,从而使得被测软件输出结果,然后通过人工或程序手段并与期望值进行比较,获得测试结果。这种方式使用时间较长,但存在测试粒度问题。
b)特定接口协议的自动化测试
测试工具利用测试脚本模拟网络通信协议和设备通信协议的交互过程,实现对被测试软件和硬件系统的测试。根据已知的协议交互规则,判断协议实现过程中的报文数据的完整性和正确性。由于协议固化较好,容错处理相对容易,但范围比较受限制。
c)UI自动化测试
通过软件和脚本对用户交互进行模拟执行,然后在测试程序中自动对被测软件输出和预期进行比较,判断测试结果。实际使用中,由于UI界面的输入为人工操作设计且基于事件响应,而事件响应的处理具有很强的灵活性和不可预知性,因此预先编写的测试程序对响应无法正确的判断和处理,测试程序运行过程经常因为UI元素变化和响应阻塞导致异常而失败。
传统测试采用作业式脚本模式实现自动化测试,测试程序采用顺序执行,返回结果后判断预期与返回结果的一致性,然后决定下一步执行。后续测试用例的执行根据上一步测试用例结果进行。缺乏对被测软件事件响应的处理能力,也不具备对中间状态的预期设定能力,只能机械地按顺序执行,遇到错误在进行回退和处理。即使如此,依然导致了测试脚本在多次执行中重现性差,复用性差,修改多,容错成本高,测试耗时增加,使得自动化测试的综合效果还不如人工效果好。典型的情况如UI的自动化测试和复杂网络交互的自动化测试,在发生无法预知的状态变化之后,测试程序可能导致异常从而必须回退。
现有的大数据测试测试方法的缺点:
a)采用重复开发开发流程的方式,目前仍然以手工测试为主。
无论手工测试还是有限的自动测试工具,都需要重复编写测试代码,而且用例场景与开发阶段部分场景重合,造成很大浪费。
b)验证方式落后
一致性比较(预期比较)缺乏有效手段,测试效率低。特别是对实时场景缺乏有效的比较手段。
c)问题复现困难。
现有的机器学习软件的测试方法的缺点:
a)采用黑盒方式,状态跟踪能力有限
机器学习软件特别是深度学习软件通常在模型训练过程中进行输出反向传播和模型参数调整,如果仅仅根据最外层的输入和输出是很难发现模型本身的缺陷。因此必须跟踪模型内部的输出变化。
b)数据提取,特征分析等仍然人工操作,缺乏评估手段。
机器学习软件的数据提取和清洗,数据集分拆都是由复杂算法结合历史数据完成,因此整个测试的判断标准最好有测试程序自动处理。但目前的情况是这些测试依然由人工根据经验指定预期并和人工进行判断。自动化处理仅限于传统的数据处理部分。而且无法通过大量的历史数据结合做中间状态的评估,而仅仅依赖最后结果的评估,无法全面评估软件。
测试过程中的重复劳动
在工程实践中,单元测试和模块测试是高耗费低产出的测试活动,很多情况下开发人员是跳过该阶段以节省成本。当然这会导致部分关键代码覆盖不全,可能会出现测试不充分的情况。造成的原因是由于在软件开发早期,软件的硬件环境、相关模块环境和数据环境都不够齐备,导致不得不花很多力气进行模拟和编写桩代码和驱动代码,从而造成巨大的人力和时间成本。
传统测试方式的测试用例是通过作业方式(批处理方式)连续传递给被测软件接口。
如果被测软件利用复杂的事件机制进行返回,如类似Promise机制,那么这种方式就无法获取返回结果。需要对事件的回调函数进行插桩处理才能获取返回结果。但是目前的简单插桩技术不能保障操作的安全性,也不能执行复杂的比较操作。因此很多测试只有通过单独插桩打印结果,用人工检验结果的正确性,效率依然很低。
发明内容
这对上述技术问题,本发明提供一种基于动态插桩-销桩技术的异步测试方法。
本发明的一种基于动态插桩-销桩技术的异步测试方法,包括以下步骤:
步骤1:通过测试管理器调用桩处理例程,在程序加载和运行阶段,根据配置文件中的插桩点配置信息,在编译后的二进制机器代码上指定地址上修改代码,并保存原有代码;更改该地址内容使其指向桩处理例程在内存中注入的桩代码,通过桩代码关联配置信息指定的测试程序;桩代码在被测软件所在的进程中运行。
步骤2:被测软件执行到插桩点地址上后转到插桩点插入的代码中执行,该段代码处理被测软件上下文,获取软件的运行状态,全局变量和函数参数,并传递给触发的测试程序;测试程序在被测软件的进程中运行,或在被测软件的进程外运行。
步骤3:当检测点被触发时,相关联的测试程序执行测试用例,将测试用例参数和相关全局变量值传递给被测软件,当观察点被触发时,测试程序收集测试输出,并将测试输出通过进程间通信协议发送到验证处理进程中进行处理;然后测试程序选择执行销桩或增加插桩操作。
步骤4:验证处理进程运行系统的验证处理模块;当该进程接到新的测试输出,便启动一个测试验证任务并加入到任务队列中;验证执行线程从队列中将每一个测试验证任务取出执行,返回的测试验证结果如果为通过,则发送给测试管理器;当结果验证出现不通过或异常情况,利用异常处理机制返回测试管理器进行处理;当测试输出持续到达就持续进行新增测试验证任务并加入到任务队列,直到不再有测试输出到达;此后将队列中的测试验证任务依次取出处理,直到队列为空。
步骤5:验证进程分析测试输出并与预期结果进行比较,决定测试是否通过;如果测试不通过则发送消息给测试管理器,停止测试的执行;如果测试通过则暂存测试结果,确定是否请求销除插桩点的操作或增加插桩点的操作,确定执行销桩或增加插桩操作;确定是否产生动态测试用例和动态预期,如果确定则执行动态测试用例处理。
步骤6:测试管理器检查被测软件没有结束运行,则继续执行被测软件,如果被测软件结束运行,则保存和输出测试结果。
上述销桩或增加插桩操作具体为:
A1:测试程序通过桩处理例程增加插桩点,根据在编译后的二进制机器代码上指定地址上修改代码,并保存原有代码,更改该地址内容使其指向桩处理例程在内存中注入的桩代码,通过桩代码关联配置信息指定的测试程序;测试程序连续调用桩处理例程进行插桩,形成相互关联的多个插桩点;当被测软件触发插桩点并调用测试程序后,当前执行的测试脚本设置新的插桩点,形成嵌套插桩;插桩遵循桩处理策略进行。
A2:测试程序通过桩处理例程删除插桩点;在函数或待测代码片段结束时,将修改的代码为被测软件恢复原来的代码,继续执行被测软件未插桩前的代码,同时清除无用的桩代码;这称为销桩;在测试程序中连续调用销桩操作,并解除嵌套插桩;销桩遵循桩处理策略进行。
A3:当此段测试程序执行完后,流程将回到被测软件执行,直到下一个插桩点被触发。
上述桩处理策略包括桩计数机制和生存周期。
桩计数机制用于插桩和销桩的过程中,具体为:桩处理模块维持一个桩计数列表,为每个创建的插桩点保存计数值和生存周期值,并按插桩顺序排序;当某个插桩点被创建时,在桩计数列表中新建节点,初始计数值为1,生存周期值为0;当某个插桩点再次被调用时,对应的桩计数增加1,而某个插桩点不再使用时,桩计数减1;如果某个插桩点的桩计数为0,则删除该插桩点的插桩代码,恢复插桩点原来的代码,并且把该插桩点在桩计数列表中的节点信息删除。
每个插桩点都有生存周期,用64位无符号整数表示;大于0的数值代表指定的生存周期;每个插桩点的桩计数等于生存周期值时将在桩代码和关联测试程序执行完毕对该插桩点进行销桩;数值0为初始值,代表不限时的生存周期。
测试程序根据需要设置生存周期条件:
如果某个插桩点需要多次观察而测试程序运行结束后不销桩的话,设定其生存周期值来决定插桩点接下来使用多久;如果生存周期值为某个正整数,当桩计数到达该整数后,对该插桩点测试程序运行结束后进行销桩;如果设置生存周期值为0,则该插桩点在测试过程中不会被删除;如果插桩点代码出现异常,按后面的插桩点造成异常导致的异常处理流程处理;
如果某个插桩点不需要多次观察,则视为不满足生存周期条件。
如果某个插桩点的桩计数等于1的话,则插桩点位于一般代码中;如果某个插桩点的桩计数大于1的话,认为该插桩点处于循环代码,重入代码或共用代码中。
以下根据生存周期条件来决定如何处理桩:
(1)如果该插桩点满足生存周期条件,则测试程序运行结束后不销桩,按照生存周期继续运行桩代码。
重入代码:每次插桩点执行时记录当前线程id,对当前线程id和历史线程id进行比较,如果线程id不是全部一致,可判断该插桩点处于重入代码中,此时测试脚本要动态创建线程访问保护代码。
共用代码:每次插桩点执行时比较代码的模块句柄是否和进程主模块句柄一致,如果不一致的话可判断该插桩点处于共用代码中,此时测试脚本可将测试输出做日志处理。
循环代码:如果满足线程id不属于(1)的情形,并且模块句柄不属于(2)的情形,判断为该插桩点处于循环代码中,不做额外处理。
一般代码:不做额外处理。
(2)如果该插桩点不满足生存周期条件,则在该插桩点测试程序执行完毕后立即销桩;
插桩点造成异常:当被测软件在该插桩点出现异常时,将转入异常处理模块,此时异常处理模块如在决定退出被测软件和测试过程,则根据调用堆栈识别和定位该插桩点;如果该插桩点计数大于1,通知桩处理例程将该插桩点在新的测试过程中将该插桩点的生存周期设为1,即使用1次后,桩处理例程将对该插桩点进行销桩;如果该插桩点计数等于1,则通知桩处理例程将该插桩点在新的测试过程中不在被使用。
插桩点无异常:不做额外处理。
动态测试用例处理具体为:
B1、通过对已有测试输出进行分析,经过特定处理后获得测试参数,然后通过加载的脚本模板进行填充和替换,利用动态测试用例生成策略生成测试用例脚本。
B2、动态测试用例绑定预配置的测试预期,选择绑定动态测试预期利用动态测试用例生成策略生成测试用例脚本。
B3、测试程序通过桩处理例程增加插桩点,根据在编译后的二进制机器代码上指定地址上修改代码,并保存原有代码,更改该地址内容使其指向桩处理例程在内存中注入的桩代码,通过桩代码关联配置信息指定的测试程序;测试程序连续调用桩处理例程进行插桩,形成相互关联的多个插桩点;当被测软件触发插桩点并调用测试程序后,当前执行的测试脚本设置新的插桩点,形成嵌套插桩;增加插桩点并将生成的测试用例脚本关联到该插桩点。
B4、当此段测试程序执行完后,流程将回到被测软件执行,直到下一个插桩点被触发。
动态测试用例生成策略采用程序自动处理方式,或采用人工干预的方式。
人工干预方式:
采用异步结果验证,测试过程执行到测试脚本生成器时转入交互状态,通过人工交互输入测试参数和测试预期值,或以字符串形式输入少量代码;人工干预处理结束后,脚本生成器将人工输入内容与模板进行合并,产生新的测试用例。
程序自动处理方式:
测试脚本生成器可以根据前面测试运行的检测点测试输入和观察点的测试输出,判断测试输入是否覆盖到完整的参数区间,如果发现没有被覆盖的参数区间,就会根据该区间范围内生成新的测试用例参数,结合模板处理后产生新的测试用例;判断测试输出是否覆盖到完整的预期值范围,如果发现没有被预期值范围覆盖的输出结果区间,就根据该区间范围内生成新的测试预期值。
插桩点触发采用动态测试用例触发策略,动态测试用例的触发有两种方式,分常规触发和循环触发。
常规触发:
新的测试脚本关联检测点和观察点的桩程序后,测试管理器重新加载被测软件,并在被测软件执行过程中触发新的测试脚本关联检测点和观察点,然后按照设计的测试流程继续完成测试任务;常规触发执行对机器学习中的反向传播等随机反馈数据及处理活动的测试。
循环触发:
新的测试脚本关联检测点和观察点的桩程序后,测试过程返回到测试管理器中,由测试管理器直接触发检测点和观察点的桩程序并执行,然后按系统设计流程继续完成测试任务;循环触发在软件集成后的任何阶段完成类似单元测试的功能。
本发明的有益技术效果为:
1、本发明的动态插桩的方法可以在没有源代码下对二进制机器码进行插桩,只需要调试符号的支持。对于一般编译型开发语言和运行于JIT(即时编译)技术的开发语言所生成的软件都可运用。由于采用测试脚本不受本地语言限制,桩代码与被测软件运行环境一致,因此只要被测软件环境满足操作系统和硬件架构,本发明方案都可以使用。在Windows,MacOS, Linux,Android,iOS等标准操作系统上都可以实现
2、本发明插桩技术不仅仅适用单个或少量的插桩需求,而且同中断技术相比,本专利技术可以嵌套插桩,形成一个复杂的桩链。这个桩链可以延伸至被测软件的任意位置,由于异步验证技术,使得插桩点被触发时,被测软件不会造成明显的阻塞。销桩的方法可以避免插桩点过多,嵌入的测试脚本大量耗时,给被测软件带来比较大的性能损失,也可以避免反复执行某些插桩点导致测试代码重入造成而带来的异常和混乱。本发明在插桩基础上增加销桩的操作,可以使嵌入被测软件的测试代码具有智能使用和禁止的能力,从而能够满足更复杂和灵活的测试需求,而不是局限在覆盖率记录和变量打印这些简单操作上。检测点-观察点的配对使用可以使用响应式的方式执行测试程序,解决了在异步处理,事件驱动和多线程程序中安全获取测试输出和软件状态的问题。由于嵌入的测试脚本可以获得被测软件的内部信息,同时可以灵活的操作被测软件,使得测试能力大大增强,可以实现某些传统测试方法无法实现的功能。
3、本发明异步结果验证避免了复杂的结果验证过程阻塞被测软件,被测软件在每一步测试触发之后,无需等待测试验证过程完成和返回验证结果,而是继续运行。在这种情况下,如果测试验证处理比较复杂或耗时较长,将不会影响被测软件的运行效率,也不会导致被测软件阻塞。同时如果测试验证过程出现异常,也不会造成被测软件的异常退出。本发明采用异步式结果验证技术,可以在不阻塞被测软件的情况下,执行复杂度较高的验证算法,因此对大数据集、矩阵及向量操作具有较好的处理能力。在测试执行过程中多点验证,进而可利用中间状态和历史数据,获得软件在数据处理中的详细信息,从而更加准确揭示模型和算法的运行趋势和特征,对模型和训练过程进行更全面有效的解释和评估。异步处理测试输出可以利用复杂运算处理矩阵和向量等复杂数据结构,验证过程中可以选择使用外部服务提供更为复杂的验证处理,比如产生动态测试用例,测试验证处理进程同外部服务交互方式采用异步方式。这样极大提升了验证过程的计算能力因此也适合于针对算法的对比测试中进行对照验证。
4、本发明动态测试用例是在测试过程中自动产生的用例,动态测试预期则是自动产生的希望的测试结果。动态测试用例可以使用预配置的测试预期,但是很多情况下使用动态测试预期。在工程实践中,单元测试和模块测试由于测试环境具备度低,依赖较多的模拟工作,测出有效缺陷反而很少。属于高耗费低产出的测试活动,很多开发活动采取跳过该阶段。引入动态测试用例和动态测试预期后,可以通过本专利设计的方案在程序运行期间局部范围内进行测试工作,类似于针对于代码片段的测试处理,相当于进行了单元测试和模块测试。如果在软件联试完成后对软件进行测试的话,软件运行的硬件环境、相关模块环境和数据环境都是具备的,无需花时间去设计桩代码和驱动代码,可能也不需要再去模拟数据。这样不影响软件测试开展的效果,却可以做到在配置项测试和系统测试阶段完成单元测试和模块测试的工作,此时测试环境具备度高,测试过程耗费时间较少,而且缺陷产出好,而且节省了开发成本。动态测试用例可以测试事件响应和回调处理,可以通过插桩方式处理被测软件的随机反馈,例如在事件响应中动态产生的GUI控件,本专利提供的方法可以从软件内部准确获取控件状态,并提供正确的操作,从而对UI自动化测试提供比较好的支持。测试活动如果不是仅仅限于最终结果验证,而是对中间结果进行验证,那么就需要动态生成测试用例和测试预期。如果我们对某个事件响应函数内的某个逻辑实现进行测试,而且要达到满足一定的路径覆盖,我们可能需要产生一个新的测试用例,产生一个新的预期。这组用例输入参数和预期值都不是在最初开始测试时能够完全确定的,需要并根据前面的中间结果决定输入参数和预期值。例如可以对神经网络反向行为和训练调整行为进行测试,在这种场景下,测试者对被测软件无法通过操作入口处理测试用例并观察测试软件的状态,必须依赖内部的自动测试用例实现。目前已有的专利尚未有比较好的解决方案。动态测试用例技术提供了比较实用的解决方法。
附图说明
图1为本发明插桩和销桩流程示意图。
图2为本发明异步验证过程时序图。
具体实施方式
下面结合附图和具体实施方法对本发明做进一步详细说明。
本发明的一种基于动态插桩-销桩技术的异步测试方法,包括以下步骤:
步骤1:通过测试管理器调用桩处理例程,在程序加载和运行阶段,根据配置文件中的插桩点配置信息,在编译后的二进制机器代码上指定地址上修改代码,并保存原有代码;更改该地址内容使其指向桩处理例程在内存中注入的桩代码,通过桩代码关联配置信息指定的测试程序;桩代码在被测软件所在的进程中运行。
步骤2:被测软件执行到插桩点地址上后转到插桩点插入的代码中执行,该段代码处理被测软件上下文,获取软件的运行状态,全局变量和函数参数,并传递给触发的测试程序;测试程序在被测软件的进程中运行,或在被测软件的进程外运行。
步骤3:当检测点被触发时,相关联的测试程序执行测试用例,将测试用例参数和相关全局变量值传递给被测软件,当观察点被触发时,测试程序收集测试输出,并将测试输出通过进程间通信协议发送到验证处理进程中进行处理;然后测试程序选择执行销桩或增加插桩操作。
步骤4:验证处理进程运行系统的验证处理模块;当该进程接到新的测试输出,便启动一个测试验证任务并加入到任务队列中;验证执行线程从队列中将每一个测试验证任务取出执行,返回的测试验证结果如果为通过,则发送给测试管理器;当结果验证出现不通过或异常情况,利用异常处理机制返回测试管理器进行处理;当测试输出持续到达就持续进行新增测试验证任务并加入到任务队列,直到不再有测试输出到达;此后将队列中的测试验证任务依次取出处理,直到队列为空。
步骤5:验证进程分析测试输出并与预期结果进行比较,决定测试是否通过;如果测试不通过则发送消息给测试管理器,停止测试的执行;如果测试通过则暂存测试结果,确定是否请求销除插桩点的操作或增加插桩点的操作,确定执行销桩或增加插桩操作;确定是否产生动态测试用例和动态预期,如果确定则执行动态测试用例处理。
步骤6:测试管理器检查被测软件没有结束运行,则继续执行被测软件,如果被测软件结束运行,则保存和输出测试结果。
上述销桩或增加插桩操作流程如图1所示,具体步骤为:
A1:测试程序通过桩处理例程增加插桩点,根据在编译后的二进制机器代码上指定地址上修改代码,并保存原有代码,更改该地址内容使其指向桩处理例程在内存中注入的桩代码,通过桩代码关联配置信息指定的测试程序;测试程序连续调用桩处理例程进行插桩,形成相互关联的多个插桩点;当被测软件触发插桩点并调用测试程序后,当前执行的测试脚本设置新的插桩点,形成嵌套插桩;插桩遵循桩处理策略进行。
A2:测试程序通过桩处理例程删除插桩点;在函数或待测代码片段结束时,将修改的代码为被测软件恢复原来的代码,继续执行被测软件未插桩前的代码,同时清除无用的桩代码;这称为销桩;在测试程序中连续调用销桩操作,并解除嵌套插桩;销桩遵循桩处理策略进行。
A3:当此段测试程序执行完后,流程将回到被测软件执行,直到下一个插桩点被触发。
上述桩处理策略包括桩计数机制和生存周期。
桩计数机制用于插桩和销桩的过程中,具体为:桩处理模块维持一个桩计数列表,为每个创建的插桩点保存计数值和生存周期值,并按插桩顺序排序;当某个插桩点被创建时,在桩计数列表中新建节点,初始计数值为1,生存周期值为0;当某个插桩点再次被调用时,对应的桩计数增加1,而某个插桩点不再使用时,桩计数减1;如果某个插桩点的桩计数为0,则删除该插桩点的插桩代码,恢复插桩点原来的代码,并且把该插桩点在桩计数列表中的节点信息删除。
每个插桩点都有生存周期,用64位无符号整数表示;大于0的数值代表指定的生存周期;每个插桩点的桩计数等于生存周期值时将在桩代码和关联测试程序执行完毕对该插桩点进行销桩;数值0为初始值,代表不限时的生存周期。
测试程序根据需要设置生存周期条件:
如果某个插桩点需要多次观察而测试程序运行结束后不销桩的话,设定其生存周期值来决定插桩点接下来使用多久;如果生存周期值为某个正整数,当桩计数到达该整数后,对该插桩点测试程序运行结束后进行销桩;如果设置生存周期值为0,则该插桩点在测试过程中不会被删除;如果插桩点代码出现异常,按后面的插桩点造成异常导致的异常处理流程处理;
如果某个插桩点不需要多次观察,则视为不满足生存周期条件。
如果某个插桩点的桩计数等于1的话,则插桩点位于一般代码中;如果某个插桩点的桩计数大于1的话,认为该插桩点处于循环代码,重入代码或共用代码中。
以下根据生存周期条件来决定如何处理桩:
(1)如果该插桩点满足生存周期条件,则测试程序运行结束后不销桩,按照生存周期继续运行桩代码。
重入代码:每次插桩点执行时记录当前线程id,对当前线程id和历史线程id进行比较,如果线程id不是全部一致,可判断该插桩点处于重入代码中,此时测试脚本要动态创建线程访问保护代码。
共用代码:每次插桩点执行时比较代码的模块句柄是否和进程主模块句柄一致,如果不一致的话可判断该插桩点处于共用代码中,此时测试脚本可将测试输出做日志处理。
循环代码:如果满足线程id不属于(1)的情形,并且模块句柄不属于(2)的情形,判断为该插桩点处于循环代码中,不做额外处理。
一般代码:不做额外处理。
(2)如果该插桩点不满足生存周期条件,则在该插桩点测试程序执行完毕后立即销桩;
插桩点造成异常:当被测软件在该插桩点出现异常时,将转入异常处理模块,此时异常处理模块如在决定退出被测软件和测试过程,则根据调用堆栈识别和定位该插桩点;如果该插桩点计数大于1,通知桩处理例程将该插桩点在新的测试过程中将该插桩点的生存周期设为1,即使用1次后,桩处理例程将对该插桩点进行销桩;如果该插桩点计数等于1,则通知桩处理例程将该插桩点在新的测试过程中不在被使用。
插桩点无异常:不做额外处理。
动态测试用例处理具体为:
B1、通过对已有测试输出进行分析,经过特定处理后获得测试参数,然后通过加载的脚本模板进行填充和替换,利用动态测试用例生成策略生成测试用例脚本。
B2、动态测试用例绑定预配置的测试预期,选择绑定动态测试预期利用动态测试用例生成策略生成测试用例脚本。
B3、测试程序通过桩处理例程增加插桩点,根据在编译后的二进制机器代码上指定地址上修改代码,并保存原有代码,更改该地址内容使其指向桩处理例程在内存中注入的桩代码,通过桩代码关联配置信息指定的测试程序;测试程序连续调用桩处理例程进行插桩,形成相互关联的多个插桩点;当被测软件触发插桩点并调用测试程序后,当前执行的测试脚本设置新的插桩点,形成嵌套插桩;增加插桩点并将生成的测试用例脚本关联到该插桩点。
B4、当此段测试程序执行完后,流程将回到被测软件执行,直到下一个插桩点被触发。
动态测试用例生成策略采用程序自动处理方式,或采用人工干预的方式。
人工干预方式:
采用异步结果验证,测试过程执行到测试脚本生成器时转入交互状态,通过人工交互输入测试参数和测试预期值,或以字符串形式输入少量代码;人工干预处理结束后,脚本生成器将人工输入内容与模板进行合并,产生新的测试用例。
程序自动处理方式:
测试脚本生成器可以根据前面测试运行的检测点测试输入和观察点的测试输出,判断测试输入是否覆盖到完整的参数区间,如果发现没有被覆盖的参数区间,就会根据该区间范围内生成新的测试用例参数,结合模板处理后产生新的测试用例;判断测试输出是否覆盖到完整的预期值范围,如果发现没有被预期值范围覆盖的输出结果区间,就根据该区间范围内生成新的测试预期值。
插桩点触发采用动态测试用例触发策略,动态测试用例的触发有两种方式,分常规触发和循环触发。
常规触发:
新的测试脚本关联检测点和观察点的桩程序后,测试管理器重新加载被测软件,并在被测软件执行过程中触发新的测试脚本关联检测点和观察点,然后按照设计的测试流程继续完成测试任务;常规触发执行对机器学习中的反向传播等随机反馈数据及处理活动的测试。
循环触发:
新的测试脚本关联检测点和观察点的桩程序后,测试过程返回到测试管理器中,由测试管理器直接触发检测点和观察点的桩程序并执行,然后按系统设计流程继续完成测试任务;循环触发在软件集成后的任何阶段完成类似单元测试的功能。
本发明采用检测点和观察点对执行测试输入和输出。检测点和观察点都是属于插桩点,一般结对出现,也可使用其中一个。当被测软件运行到检测点时触发测试程序,执行测试数据的输入,而运行到观察点时,测试程序收集测试输出,并将测试输出通过IPC通信协议发送到验证处理进程中进行处理。
以函数为例但不限于函数,为了执行测试用例的输入,在被测试的函数入口设置第一个插桩点,称为检测点。在被测试的函数出口设置第二个插桩点,称为观察点。检测点测试程序产生测试输入,用测试程序准备的数据替换被测函数的入口参数值和相关全局变量值,继续执行被测软件。观察点测试程序读取函数的返回值和相关全局变量的值,产生测试输出。检测点和观察点不需要在同一个函数中。检测点和观察点有时也可以用其中一个。而且同一个插桩点可以即是检测点也是观察点,但观察点身份对应的是其他检测-观察点对的检测点,检测点身份对应的是其他检测-观察点对的观察点。
观察点在获取测试输出后,会通过管道将该输出传递到验证进程(验证模块)中。验证进程分析测试输出并与预期结果进行比较,决定测试是否通过。如果测试不通过则可以发送消息给测试管理器,停止测试的执行。如果测试通过则继续处理后续测试输出。
验证处理进程运行系统的验证处理模块。当该进程接到新的测试输出,便启动一个测试验证任务并加入到任务队列中。验证执行线程从队列中将每一个测试验证任务取出执行,返回的测试验证结果如果为通过,则发送给测试管理器。当结果验证出现不通过或异常情况,利用异常处理机制返回测试管理器进行处理,不会直接中断被测软件。当测试输出持续到达就持续进行新增测试验证任务并加入到任务队列,直到不再有测试输出到达。此后将队列中的测试验证任务依次取出处理,直到队列为空。
测试验证时采用的预期结果有两种来源方式:
1)测试配置文件的预先设置。
对每个检测点和观察点对的信息中预设相关的测试参数和测试预期。
2)动态测试预期
对动态产生的插桩点,采用动态测试用例和动态测试预期。
被测软件在每一步测试触发之后,无需等待测试验证过程完成和返回验证结果,而是继续运行。在这种情况下,如果测试验证处理比较复杂或耗时较长,将不会影响被测软件的运行效率,也不会导致被测软件阻塞。同时如果测试验证过程出现异常,也不会造成被测软件的异常退出。具体时序图见图2。
Claims (6)
1.一种基于动态插桩-销桩技术的异步测试方法,其特征在于,包括以下步骤:
步骤1:通过测试管理器调用桩处理例程,在程序加载和运行阶段,根据配置文件中的插桩点配置信息,在编译后的二进制机器代码上指定地址上修改代码,并保存原有代码;更改地址内容使其指向桩处理例程在内存中注入的桩代码,通过桩代码关联配置信息指定的测试程序;桩代码在被测软件所在的进程中运行;
步骤2:被测软件执行到插桩点地址上后转到插桩点插入的代码中执行,通过执行插桩点插入的代码处理被测软件上下文,获取软件的运行状态,全局变量和函数参数,并传递给触发的测试程序;测试程序在被测软件的进程中运行,或在被测软件的进程外运行;
步骤3:当检测点被触发时,相关联的测试程序执行测试用例,将测试用例参数和相关全局变量值传递给被测软件,当观察点被触发时,测试程序收集测试输出,并将测试输出通过进程间通信协议发送到验证处理进程中进行处理;然后测试程序选择执行销桩或增加插桩操作;
步骤4:验证处理进程运行系统的验证处理模块;当该进程接到新的测试输出,便启动一个测试验证任务并加入到任务队列中;验证执行线程从队列中将每一个测试验证任务取出执行,返回的测试验证结果如果为通过,则发送给测试管理器;当结果验证出现不通过或异常情况,利用异常处理机制返回测试管理器进行处理;当测试输出持续到达就持续进行新增测试验证任务并加入到任务队列,直到不再有测试输出到达;此后将队列中的测试验证任务依次取出处理,直到队列为空;
步骤5:验证进程分析测试输出并与预期结果进行比较,决定测试是否通过;如果测试不通过则发送消息给测试管理器,停止测试的执行;如果测试通过则暂存测试结果,确定是否请求销除插桩点的操作或增加插桩点的操作,确定执行销桩或增加插桩操作;确定是否产生动态测试用例和动态预期,如果确定则执行动态测试用例处理;
步骤6:测试管理器检查被测软件没有结束运行,则继续执行被测软件,如果被测软件结束运行,则保存和输出测试结果。
2.根据权利要求1所述的一种基于动态插桩-销桩技术的异步测试方法,其特征在于,所述销桩或增加插桩操作具体为:
A1:测试程序通过桩处理例程增加插桩点,根据在编译后的二进制机器代码上指定地址上修改代码,并保存原有代码,更改地址内容使其指向桩处理例程在内存中注入的桩代码,通过桩代码关联配置信息指定的测试程序;测试程序连续调用桩处理例程进行插桩,形成相互关联的多个插桩点;当被测软件触发插桩点并调用测试程序后,当前执行的测试脚本设置新的插桩点,形成嵌套插桩;插桩遵循桩处理策略进行;
A2:测试程序通过桩处理例程删除插桩点;在函数或待测代码片段结束时,将修改的代码为被测软件恢复原来的代码,继续执行被测软件未插桩前的代码,同时清除无用的桩代码;这称为销桩;在测试程序中连续调用销桩操作,并解除嵌套插桩;销桩遵循桩处理策略进行;
A3:当此段测试程序执行完后,流程将回到被测软件执行,直到下一个插桩点被触发。
3.根据权利要求2所述的一种基于动态插桩-销桩技术的异步测试方法,其特征在于,所述桩处理策略包括桩计数机制和生存周期;
桩计数机制用于插桩和销桩的过程中,具体为:桩处理模块维持一个桩计数列表,为每个创建的插桩点保存计数值和生存周期值,并按插桩顺序排序;当某个插桩点被创建时,在桩计数列表中新建节点,初始计数值为1,生存周期值为0;当某个插桩点再次被调用时,对应的桩计数增加1,而某个插桩点不再使用时,桩计数减1;如果某个插桩点的桩计数为0,则删除该插桩点的插桩代码,恢复插桩点原来的代码,并且把该插桩点在桩计数列表中的节点信息删除;
每个插桩点都有生存周期,用64位无符号整数表示;大于0的数值代表指定的生存周期;每个插桩点的桩计数等于生存周期值时将在桩代码和关联测试程序执行完毕对该插桩点进行销桩;数值0为初始值,代表不限时的生存周期;
测试程序根据需要设置生存周期条件:
如果某个插桩点需要多次观察而测试程序运行结束后不销桩的话,设定其生存周期值来决定插桩点接下来使用多久;如果生存周期值为某个正整数,当桩计数到达该整数后,对该插桩点测试程序运行结束后进行销桩;如果设置生存周期值为0,则该插桩点在测试过程中不会被删除;如果插桩点代码出现异常,按后面的插桩点造成异常导致的异常处理流程处理;
如果某个插桩点不需要多次观察,则视为不满足生存周期条件;
如果某个插桩点的桩计数等于1的话,则插桩点位于一般代码中;如果某个插桩点的桩计数大于1的话,认为该插桩点处于循环代码,重入代码或共用代码中;
以下根据生存周期条件来决定如何处理桩:
(1)如果该插桩点满足生存周期条件,则测试程序运行结束后不销桩,按照生存周期继续运行桩代码;
(2)如果该插桩点不满足生存周期条件,则在该插桩点测试程序执行完毕后立即销桩;
对于情形(1),分以下情况:
重入代码:每次插桩点执行时记录当前线程id,对当前线程id和历史线程id进行比较,如果线程id不是全部一致,可判断该插桩点处于重入代码中,此时测试脚本要动态创建线程访问保护代码;
共用代码:每次插桩点执行时比较代码的模块句柄是否和进程主模块句柄一致,如果不一致的话可判断该插桩点处于共用代码中,此时测试脚本可将测试输出做日志处理;
循环代码:如果满足线程id不属于重入代码的情形,并且模块句柄不属于共用代码的情形,判断为该插桩点处于循环代码中,不做额外处理;
一般代码:不做额外处理;
对于情形(2),分以下情况:
插桩点造成异常:当被测软件在该插桩点出现异常时,将转入异常处理模块,此时异常处理模块如在决定退出被测软件和测试过程,则根据调用堆栈识别和定位该插桩点;如果该插桩点计数大于1,通知桩处理例程将该插桩点在新的测试过程中将该插桩点的生存周期设为1,即使用1次后,桩处理例程将对该插桩点进行销桩;如果该插桩点计数等于1,则通知桩处理例程将该插桩点在新的测试过程中不在被使用;
插桩点无异常:不做额外处理。
4.根据权利要求1所述的一种基于动态插桩-销桩技术的异步测试方法,其特征在于,所述动态测试用例处理具体为:
B1、通过对已有测试输出进行分析,经过特定处理后获得测试参数,然后通过加载的脚本模板进行填充和替换,利用动态测试用例生成策略生成测试用例脚本;
B2、动态测试用例绑定预配置的测试预期,选择绑定动态测试预期利用动态测试用例生成策略生成测试用例脚本;
B3、测试程序通过桩处理例程增加插桩点,根据在编译后的二进制机器代码上指定地址上修改代码,并保存原有代码,更改地址内容使其指向桩处理例程在内存中注入的桩代码,通过桩代码关联配置信息指定的测试程序;测试程序连续调用桩处理例程进行插桩,形成相互关联的多个插桩点;当被测软件触发插桩点并调用测试程序后,当前执行的测试脚本设置新的插桩点,形成嵌套插桩;增加插桩点并将生成的测试用例脚本关联到该插桩点;
B4、当此段测试程序执行完后,流程将回到被测软件执行,直到下一个插桩点被触发。
5.根据权利要求4所述的一种基于动态插桩-销桩技术的异步测试方法,其特征在于,所述动态测试用例生成策略采用程序自动处理方式,或采用人工干预的方式;
人工干预方式:
采用异步结果验证,测试过程执行到测试脚本生成器时转入交互状态,通过人工交互输入测试参数和测试预期值,或以字符串形式输入少量代码;人工干预处理结束后,脚本生成器将人工输入内容与模板进行合并,产生新的测试用例;
程序自动处理方式:
测试脚本生成器根据前面测试运行的检测点测试输入和观察点的测试输出,判断测试输入是否覆盖到完整的参数区间,如果发现没有被覆盖的参数区间,就会根据该区间范围内生成新的测试用例参数,结合模板处理后产生新的测试用例;判断测试输出是否覆盖到完整的预期值范围,如果发现没有被预期值范围覆盖的输出结果区间,就根据该区间范围内生成新的测试预期值。
6.根据权利要求4所述的一种基于动态插桩-销桩技术的异步测试方法,其特征在于,所述插桩点触发采用动态测试用例触发策略,动态测试用例的触发有两种方式,分常规触发和循环触发;
常规触发:
新的测试脚本关联检测点和观察点的桩程序后,测试管理器重新加载被测软件,并在被测软件执行过程中触发新的测试脚本关联检测点和观察点,然后按系统设计流程继续完成测试任务;常规触发执行对机器学习中的反向传播随机反馈数据及处理活动的测试;
循环触发:
新的测试脚本关联检测点和观察点的桩程序后,测试过程返回到测试管理器中,由测试管理器直接触发检测点和观察点的桩程序并执行,然后按照设计的测试流程继续完成测试任务;循环触发在软件集成后的任何阶段完成相同单元测试的功能。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202111391660.3A CN114168454B (zh) | 2021-11-23 | 2021-11-23 | 一种基于动态插桩-销桩技术的异步测试方法 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202111391660.3A CN114168454B (zh) | 2021-11-23 | 2021-11-23 | 一种基于动态插桩-销桩技术的异步测试方法 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN114168454A CN114168454A (zh) | 2022-03-11 |
CN114168454B true CN114168454B (zh) | 2023-03-10 |
Family
ID=80480402
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN202111391660.3A Active CN114168454B (zh) | 2021-11-23 | 2021-11-23 | 一种基于动态插桩-销桩技术的异步测试方法 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN114168454B (zh) |
Families Citing this family (2)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN114996152A (zh) * | 2022-06-17 | 2022-09-02 | 抖音视界(北京)有限公司 | 一种单元测试方法、装置、设备及介质 |
CN115576840B (zh) * | 2022-11-01 | 2023-04-18 | 中国科学院软件研究所 | 基于机器学习的静态程序插桩检测方法及装置 |
Citations (5)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN104834590A (zh) * | 2014-02-11 | 2015-08-12 | 腾讯科技(深圳)有限公司 | 软件测试方法和系统 |
CN105095092A (zh) * | 2015-09-25 | 2015-11-25 | 南京大学 | 基于静态分析和动态运行的Web应用JavaScript代码原子性违反检测 |
CN111222142A (zh) * | 2020-01-09 | 2020-06-02 | 大连理工大学 | 一种车载obu的数据竞争检测方法 |
CN112559322A (zh) * | 2020-11-20 | 2021-03-26 | 国家电网有限公司 | 一种基于动态插桩的软件分析方法及系统 |
CN112579437A (zh) * | 2020-12-01 | 2021-03-30 | 中国科学院电子学研究所苏州研究院 | 一种程序运行过程符合性验证方法 |
Family Cites Families (2)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN110162472B (zh) * | 2019-05-08 | 2022-08-12 | 安徽工业大学 | 一种基于fuzzing测试的测试用例生成方法 |
WO2021229295A1 (en) * | 2020-05-12 | 2021-11-18 | Lightrun Platform LTD | Systems and methods for debugging and application development |
-
2021
- 2021-11-23 CN CN202111391660.3A patent/CN114168454B/zh active Active
Patent Citations (5)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN104834590A (zh) * | 2014-02-11 | 2015-08-12 | 腾讯科技(深圳)有限公司 | 软件测试方法和系统 |
CN105095092A (zh) * | 2015-09-25 | 2015-11-25 | 南京大学 | 基于静态分析和动态运行的Web应用JavaScript代码原子性违反检测 |
CN111222142A (zh) * | 2020-01-09 | 2020-06-02 | 大连理工大学 | 一种车载obu的数据竞争检测方法 |
CN112559322A (zh) * | 2020-11-20 | 2021-03-26 | 国家电网有限公司 | 一种基于动态插桩的软件分析方法及系统 |
CN112579437A (zh) * | 2020-12-01 | 2021-03-30 | 中国科学院电子学研究所苏州研究院 | 一种程序运行过程符合性验证方法 |
Non-Patent Citations (1)
Title |
---|
系统控制类软件系统的共用仿真测试技术;王煜成;《电子信息对抗技术》;20150331;第30卷(第2期);第79-82页 * |
Also Published As
Publication number | Publication date |
---|---|
CN114168454A (zh) | 2022-03-11 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN114168454B (zh) | 一种基于动态插桩-销桩技术的异步测试方法 | |
Memon | An event‐flow model of GUI‐based applications for testing | |
Yuan et al. | GUI interaction testing: Incorporating event context | |
CN100547562C (zh) | 自动生成可再现运行时问题的单元测试用例的方法和系统 | |
CN110688313B (zh) | 一种VxWorks操作系统下软件测试的故障注入方法 | |
US20050223362A1 (en) | Methods and systems for performing unit testing across multiple virtual machines | |
CN110704314B (zh) | 一种嵌入式软件测试的故障注入方法 | |
US7546585B2 (en) | Method, system and computer program product for testing computer programs | |
Sanches et al. | J-swfit: A java software fault injection tool | |
Koeman et al. | Automating failure detection in cognitive agent programs | |
CN110704315B (zh) | 一种嵌入式软件测试的故障注入装置 | |
Barbosa et al. | Verification and validation of (real time) COTS products using fault injection techniques | |
Kranzlmüller et al. | NOPE: A nondeterministic program evaluator | |
Vinter et al. | Fiscade-a fault injection tool for scade models | |
Singh et al. | Learning component interfaces with may and must abstractions | |
Naslavsky et al. | Using traceability to support model-based regression testing | |
CN110955605A (zh) | 一种cpu验证单步动态执行的方法 | |
CN115168131A (zh) | 一种故障注入的cpu异常功能验证方法 | |
Sharma et al. | Model-based testing: the new revolution in software testing | |
Jin et al. | Fault injection scheme for embedded systems at machine code level and verification | |
Pfeiffer et al. | Applying model checking to workflow verification | |
Garg | A study of aspect oriented testing techniques | |
Karam et al. | Challenges and opportunities for improving code-based testing of graphical user interfaces | |
CN112527680B (zh) | 一种基于Fitnesse框架的项目API级全链路自动化测试方法及系统 | |
CN113688032A (zh) | 基于进程间通信机制的故障注入验证方法、系统及终端 |
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 | ||
GR01 | Patent grant | ||
GR01 | Patent grant |