一种基于深度学习的JS转译器缺陷检测方法

文档序号:29795813发布日期:2022-04-23 18:48阅读:98来源:国知局
一种基于深度学习的JS转译器缺陷检测方法
一种基于深度学习的js转译器缺陷检测方法
技术领域
1.本发明属于软件测试技术领域,尤其涉及一种用于检查javascript转译器缺陷的技术,具体为一种基于深度学习的js(javascript)转译器缺陷检测方法。


背景技术:

2.近些年来javascript(简称js)已经成为最流行的编程语言,javascript语法遵守ecma(欧洲计算机制造商协会)国际通过ecma-262标准化的脚本程序设计语言规范ecmascript(简称es)。从2015年开始,ecma下的组织tc39(ecma的第39号技术专家委员会)更是每年更新一个ecmascript标准。ecmascript标准更新频繁,然而浏览器由于兼容性,安全性等问题考虑无法快速跟进ecmascript标准,同时主流的浏览器厂家也会按照自己对ecmascript标准的理解来实现js引擎(浏览器中运行javascript脚本的执行器),如google的v8,mozilla的spidermonkey等。每个js引擎都有着不同的性能特征,每个都实现着ecmascript功能的不同子集。在这种情况下,想要让javascript代码使用新的语言特性就需要面对不同浏览器的兼容性问题了。
3.为了解决这一问题,javascript社区出现了一类javascript转译器工具,这类工具又称源到源编译器或者翻译器,是读取一种编程语言编写的源代码并生成以另一种语言编写的等效代码的工具。常见的js转译器,如babel,能将不同标准下的js代码转换为指定版本的es规范代码(如es5),从而解决浏览器的兼容性问题。js转译器已经成为浏览器应用开发工具链中的重要一环。js转译器能否正确地完成转译,极大的影响着浏览器应用开发的准确性、可靠性。
4.虽然现有的一些发明专利可以用于生成或变异一定量的测试用例,但是仍有不足,如一种基于路径反馈的javascript引擎模糊测试方法及装置(cn201811309430.6),该方法对测试样本集中的各个待突变测试样本进行突变,突变后的种子测试用例种类多样,但是这些测试用例是语法盲的,种子测试用例的语法正确性很低、javascript引擎安全测试方法及测试系统(cn202110006727.0),该方法在语法分析的基础上,利用rnn模型生成新的测试用例,能够生成种类丰富的不定长度的javascript测试用例;但是该方法没有对测试用例的语法特性进行区分,在前期语法分析阶段仅仅验证了语法正确性,无法生成指定语法特性的测试用例、javascript程序的符号执行和自动测试用例生成(us20130318503a1),该方法通过符号执行解析验证现有的javascript程序并生成新的测试用例,该方法能够一定程度上保证语法正确性,但是生成程序高度依赖于原有测试用例,生成的测试用例结构单一。
5.综上所述:现有的几个方法主要将测试目标聚焦于javascript引擎方面,对于测试用例的获取一般采用对现有测试用例变异的方式,或直接训练随机种子语料库,这样的方法虽然能够获得种类多样的测试用例,但是生成的测试用例大多是语法盲的,而且测试用例的正确率较低,无法满足转译器对于某一特定语法输入的要求,应用测试不够全面,测试覆盖率低。


技术实现要素:

6.本发明的目的在于提供一种基于深度学习的javascript转译器缺陷检测方法。本发明通过在github上收集指定语法的测试用例,通过语法检测工具过滤,得到一系列包含正确语法单元的测试用例片段的语料库,然后训练出深度学习模型,根据模型生成新的测试用例。该方案按指定语法收集筛选测试用例,解决了测试用例生成的语法盲问题,以包含语法特性的代码块作为训练单元,增加了生成包含目标语法要求代码正确率,同时通过深度学习生成新的测试用例,提高了测试用例的多样性,扩大了测试空间,进而实现了对javascript转译器的高效检测。
7.本发明的技术方案:
8.一种基于深度学习的js转译器缺陷检测方法,具体步骤如下:
9.步骤1:按照关键词搜索法收集github上指定语法的代码库。
10.具体为:通过关键字搜索法,使用github提供的api按照star数量从多到少收集语料库。然后使用js引擎将js文件中引入的外部模块导入到当前文件中以避免引用错误,最后使用代码静态检查工具进行语法检查,筛选出语法正确的代码保存到语料库中。语法检查分为两遍,第一遍找到符合指定语法标准的代码文件,第二遍从第一遍检查后的文件中找到语法正确的代码文件。
11.步骤2:对语料库进行预处理。为减轻深度学习模型的训练压力,要首先对语料库进行预处理,预处理内容包括删除注释,统一标记名和字符串信息。
12.具体为:首先将js测试用例转换为ast(抽象语法树),再统一修改标记名。这里的标记名包括函数名、类名、变量名和属性名,修改变量名和属性名的时候略过javascript的保留字和内置函数,然后将字符串变量统一修改为“string”。对于js中能将字符串内容作为一般js脚本执行eval函数进行特殊处理,将eval函数的字符串参数,提取成单独的代码段插入原有的程序中。其次将ast上的注释内容删除,最后将ast再转换为js程序。
13.步骤3:训练模型。
14.使用lstm(长短期记忆模型)进行训练,lstm是一种时间循环神经网络(rnn),通过门控状态来控制传输状态,记住需要长时间记忆的,忘记不重要的信息;从而能够解决长序列训练过程中的梯度消失和梯度爆炸问题,在处理长序列数据是有良好的表现,比较适合应用于代码生成。
15.lstm模型需要将每个训练文本(即js程序)转换为一个整数序列作为神经网络的输入。为此,首先需要构建一个词汇表,通过在词汇表中查找标记,将每个指令、常量和变量映射为整数。本发明使用字节对编码(bpe)标记化方法构建词汇表,具体为:首先计算训练数据中每个单词的频率,然后根据单词频率将每个单词分成块(或子单词)。例如,常见的语言关键字(如var、for和if)将标记为整个单词,而较少见的单词(如变量名)将拆分为较小的块(如几个字符),并可用于创建其余单词。最终将每个子词或标记映射到要存储在词汇表中的整数。该方案允许通过重用有限子单词列表中的标记来处理现实生活中js程序中可能出现的无限多个单词。在构建成功词汇表后,将js程序一一映射为整数序列来更新lstm网络,得到训练后的模型。
16.步骤4:检测是否达到测试时间限制。如果没有达到,则转到步骤5,使用深度学习模型指导测试用例生成;若已达到,则停止测试。
17.其中,测试时间限制可由测试人员根据需求进行设置,不包含步骤1,2,3中构建语料库和训练模型的时间。
18.步骤5:生成测试用例。通过加载训练后的模型可以生成新的代码片段。本发明方法从现有语料库选定一定数量的,包含不同语法特性的短小代码片段作为样本头输入到模型中,然后要求深度学习网络根据这些字符串生成下一个令牌。本方法采用top-k采样方案,从top-k令牌中随机选择一个令牌。然后将生成字符追加到现有字符并作为下一轮网络更新的输入。当花括号“{”和“}”匹配,或语言模型生成专用终止符号“eof”,或合成程序的字数超过初始设置的最长字符阈值时,该生成过程终止。对于生成的测试用例进行静态语法检查,去除完全不包含指定语法的测试用例和包含错误语法的测试用例。但是本方法还随机保留了一定量的错误语法测试用例,来触发未能检测到语法错误的转译器bug。
19.步骤6:使用转译器转译测试用例。在转译过程中,如果转译器报错,收集报错信息,错误信息的首行记录了bug类型和bug内容,以此作为索引值,触发bug的测试用例作为索引内容,记录在bug字典中。
20.步骤7:语法检测。对于成功转换的测试用例,使用静态语法检查工具来检查代码,如果检查结果中包括了语法规范错误的报错信息,证明了转译器未能正确地将测试用例转换为指定语法的代码,将此类报错信息作为索引值,测试用例作为索引内容载入bug字典中。
21.步骤8:语义检测。对于转换后的代码,转译器可能在转换过程中改变代码的语义,需要使用js引擎等运行转换前后代码,比较转译语义。如果在转译前后代码的语义不同,则可能转译器中包含bug。并以语义转换错误作为索引值,测试用例作为索引内容载入bug字典中。
22.步骤9:约简测试用例。包含更多代码的测试用例一般包含更多的代码路径,暴露转译工具bug的可能性更大,但是体积过于庞大的测试用例难以帮助开发者进行bug定位,需要对测试用例进行缩减,本发明在抽象语法树的层次上对测试用例进行缩减。具体来说,借助抽象语法树转换工具将测试用例转换为抽象语法树,以非终结符为界定单元将代码分割为一个个代码块,如果删除某个代码块不影响bug触发则证明该代码块可以被缩减,最后得到一个能够触发bug的最小代码块。
23.步骤8中,转译前后的语义检测涉及了转译器的转译边界问题,具体来说,转译器的转译方式并没有一个具体的标准,同时,ecmascript发展过程中,新的语法并非是能够完全转换成旧的语法。这时关于语义转换结果正确性的界定就很模糊了。对此本发明方法采取差分测试来进行判断转译器是否在转换过程中改变代码的语义,流程如下:
24.定义一个标准集合e,标准e1,e2...en,转译器集合t,其中转译器t1,t2...tn,转译器t1,t2…
tn,将e1标准的源代码o1分别转换为符合e2语法规范的代码d1,d2…dn
,再运行o1和d1,d2…dn
,通过对比执行结果来判断转译器是否改变了语义,包括以下两种情况。
25.情况a:
26.d1,d2…dn-1
的执行结果和o1的执行结果一致,dn执行结果和o1的执行结果不同,这里认为tn的转译过程是包含bug的,则将tn转译后语义不一致bug及其测试用例载入bug字典中
27.情况b:
28.d1,d2…dn
执行结果一致,和o1执行结果不同,认为这是转译工具普遍认为的转译方式,是不同语法的固有差异导致转译前后的语义无法完全一致,不载入bug字典。
29.注意在运行转译结果时要首先排除包含有运行时代码(包括打印时间,随机数,打印运行时信息,如函数和对象的信息)的测试用例。
30.本发明的有益效果:本发明方法可以对javascript转译器进行缺陷检测,通过深度学习模型学习测试用例的语法特性并生成新的测试用例,避免了以往检测过程中需要开发人员手动编写测试用例或传统方法生成大量无用的语法盲的测试用例,大大的节省了时间的同时提高了测试效率。
附图说明
31.图1是本发明的一种基于深度学习指导的js转译器缺陷检测方法工作流程示意图。
32.具体实施示例
33.以下结合附图、技术方案以及实例对本发明方法进行详细说明。
34.在本实施示例中,本发明方法部署在一台linux服务器上,服务器具体配置如表1所示。根据实验需求安装javascript引擎v8,深度学习依赖库keras,js语法静态检查工具jshint,ast转换工具astexplorer以及待测试的js转译器babel,swc和traceur,并对babel,swc和traceur进行了测试。
35.表1 linux服务器配置信息表
[0036][0037]
如图1所示,本发明的一种基于深度学习的javascript转译器缺陷检测方法按如下流程进行。首先收集github上指定语法的js测试用例,然后进行语法检测找到满足语法要求的代码。接下来在抽象语法树层次上对测试用例进行预处理得到语料库,并使用深度学习框架训练语料库得到模型,然后根据模型指导代码生成。继而,使用不同的js转译器对输入进行转译,收集测试用例触发的转译器bug,对转译后的代码进行语法检测和语义检测,收集相应的bug。在代码缩减后向开发者提交bug报告。
[0038]
本实施具体步骤如下:
[0039]
步骤1:在github上收集符合指定语法标准的库,并提取js代码至语料库中。
[0040]
具体为:通过关键字搜索法,使用github提供的api按照star数量从多到少收集测试用例。以检测转译器对于es6标准代码到es5标准代码的转换为例,可以按照es6关键词搜索,按star排名前2000的存储库。对于下载到本地github库,使用google的js引擎v8通过
‑‑
module命令将测试用例中引入的外部文件扩展到当前文件中,防止在代码检查时出现引用未定义变量问题,然后使用代码静态检查工具jshint,筛选出语法正确且包括es6语法规范的代码片段至语料库中。
[0041]
以es6到es5的转换测试为例,其中语料库的筛选分为两次筛选,第一次筛选设置
语法要求为es5,找到检测信息包含”use esversion:6”的程序,第二次筛选设置语法要求为es6,在第一次筛选的基础上,找到正确通过语法检测工具的代码。通过这两次筛选可以整理出包含es6语法且无语法错误的测试用例。
[0042]
步骤2:对语料库进行预处理,包括删除注释,统一标记名和字符串信息。
[0043]
具体来说,将js测试用例用ast转换工具astexplorer转换为抽象语法树,统一修改标记名,这里的标记包括函数名,类名,变量名和属性名,注意略过关键词和内置函数等;然后将字符串变量统一修改为“string”,注意js特有的语法eval函数能将字符串内容作为一般js脚本执行,故需要略过eval函数中的字符串参数。然后将ast在转换为js程序,转换时不保留注释。
[0044]
步骤3:使用lstm训练生成模型。
[0045]
具体来说,首先通过字节对编码(bpe)标记化方法构建词汇表。第一步计算训练数据中每个单词的频率。然后根据单词频率将每个单词分成块。例如,常见的语言关键字(如var、for和if)将标记为整个单词,而较少见的单词(如变量名)将拆分为较小的块(如几个字符),并可用于创建其余单词。最终实现用最少的标记表示训练数据集,并将每个子词或标记映射到要存储在词汇表中的整数。
[0046]
然后使用包含映射js数据集的整数序列作为输入来更新每层512个节点的两层lstm网络,优化器选择adam优化器,epochs设置为100,最后,训练好的模型保存在checkpoint中供生成器生成使用。
[0047]
步骤4:检测是否达到测试时间限制;若未达到,利用训练好的深度学习模型生成测试用例种子代码;若已达到,则停止测试。
[0048]
具体为:在完成深度学习模型后记录一个时间点time1,获取当前时间点time2,设置执行时间为exec_time,如果time2

time1》=exec_time则停止测试,否则继续进行下一步。
[0049]
步骤5:生成测试用例。本发明方法从现有语料库选定2000个包含不同语法特性的短小代码片段作为样本头输入到模型中,然后要求深度学习网络根据这些字符串生成下一个令牌,本方法采用top-k抽样方案,其中k设置为10,从前10个概率最高的令牌中随机选择一个令牌。然后将生成字符追加到现有字符并作为下一轮网络更新的输入。当花括号“{”和“}”匹配,或语言模型生成专用终止符号“eof”,或合成程序的字数超过2000时,该生成过程终止。对于生成的测试用例进行静态语法检查,去除完全不包含指定语法的测试用例和包含错误语法的测试用例。但是本方法还随机保留了10%的错误语法测试用例,因为这些测试用例也有可能被转译器忽略语法错误并进行转换,从而触发bug。
[0050]
步骤6:使用转译器转译测试用例。在转译过程中,如果出现错误,收集报错信息,错误信息的首行记录了bug类型和bug内容,以此作为索引值,触发bug的测试用例作为索引内容记录在bug字典中。
[0051]
步骤7:语法检测。对于成功转换的测试用例,使用jshint检查代码,如果检查结果中包括了“use esversion:6”此类报错信息,证明了转译器未能正确地将测试用例转换为指定语法的代码,将“use esversion:6”作为索引值,测试用例作为索引内容载入bug字典中。
[0052]
步骤8:语义检测。对于转换后的代码,分别使用v8运行,如果某一转译后代码运行
结果和转译前代码运行结果不同,将语义错误作为索引值,测试用例作为索引内容载入到bug字典中。若所有转译后代码运行结果和转译前代码运行结果都不同,则跳过该测试用例继续运行。
[0053]
具体为,设转换前源代码为o1,babel,swc和traceur的转译结果分别为d1,d2,d3,判断转译前后语义是否一致可以分为以下两种情况。
[0054]
情况a:若d1,d2的执行结果和o1的执行结果一致,d3执行结果和o1的执行结果不同,这里认为traceur转译过程是包含bug的。将traceur转译前后语义不一致bug及其测试用例载入bug字典中。同理可扩展到其他转译器转译后语义不一致情况。
[0055]
情况b:d1,d2,d3执行结果一致,和o1执行结果不同,本方法认为这是转译工具普遍认为的转译方式,是不同语法的固有差异导致转译前后的语义无法完全一致,不载入bug字典。
[0056]
步骤9:约简测试用例。包含更多代码的测试用例一般包含更多的代码路径,暴露转译工具bug的可能性更大。但是体积过于庞大的测试用例难以帮助开发者进行bug定位,需要对测试用例进行缩减。本发明在抽象语法树的层次上对测试用例进行缩减。具体来说,借助astexplorer工具将测试用例转换为抽象语法树,以非终结符为界定单元将代码分割为一个个代码块。如果删除某个代码块不影响bug触发则证明该代码块可以被缩减,最后得到一个能够触发bug的最小代码块。
[0057]
本发明方法自动化运行上述过程,完成了对于javascript转译器的缺陷检测工作。基于深度学习的以包含指定语法的代码片段作为训练数据的测试用例生成算法,能够生成大量包含符合转译器转译要求的指定语法代码,大大增加了测试用例的种类和数量,提高了javascript转译器缺陷检测的效率。
当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1