CN109614329A - 一种基于接口控制文件的软件测试用例辅助设计方法 - Google Patents
一种基于接口控制文件的软件测试用例辅助设计方法 Download PDFInfo
- Publication number
- CN109614329A CN109614329A CN201811487116.7A CN201811487116A CN109614329A CN 109614329 A CN109614329 A CN 109614329A CN 201811487116 A CN201811487116 A CN 201811487116A CN 109614329 A CN109614329 A CN 109614329A
- Authority
- CN
- China
- Prior art keywords
- node
- character string
- name
- character
- structural body
- 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.)
- Granted
Links
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/3668—Software testing
- G06F11/3672—Test management
- G06F11/3684—Test management for test design, e.g. generating new test cases
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)
- Machine Translation (AREA)
- Devices For Executing Special Programs (AREA)
Abstract
本发明提供了一种基于接口控制文件的软件测试用例辅助设计方法,针对C语言结构体语法,在程序中自定义用于存放结构体信息的词典数据结构和名字树数据结构;解析得到的ICD数据信息,以树形列表的方式呈现,从ICD列表中选择待编辑的数据块,放到树形列表上,形成测试用例;在编辑测试用例后,将数据按其格式拼接组合为字节流发送给被测软件,完成动态测试。本发明可以快速完成对ICD文件的解析,在解析ICD文件后,ICD结构信息以词典文件形式供编辑、查看,其它可配置集成测试环境也可以按照接口调用此词典文件,使用灵活;在ICD结构信息的自动显示的基础上,实现编辑、发送测试用例,能够显著提高某些软件的测试效率。
Description
技术领域
本发明涉及软件测试技术领域,提供一种基于C语言接口控制文件的软件测试用例辅助设计方法。
背景技术
接口控制文件(以下简称ICD)规定了嵌入式设备软件之间的具体接口关系,大量的嵌入式软件采用C语言编写,在测试时需要提供ICD接口数据激励。
软件测试用例设计是软件测试的核心技术工作。测试用例设计存在突出瓶颈,体现在:测试用例的输入、输出元素来自于ICD,ICD结构复杂多样,可配置的动态测试环境需要ICD信息,主要依靠人工录入,工作量大、容易出错。
发明内容
为了克服现有技术的不足,本发明提供一种使用计算机程序解析ICD数据信息、并基于ICD数据信息,快速辅助生成大量非冗余的测试用例,以方便软件测试的方法。
本发明解决其技术问题所采用的技术方案的步骤如下:
步骤1:针对C语言结构体语法,在程序中自定义用于存放结构体信息的词典数据结构和名字树数据结构;
读取字符流并按C语言语法规则分割为关键字和变量、常量词;
读入字符串流,依次放入一个待处理字符串队列中,并生成名字树:因为父结构体名经常出现在结构体的最后(右花括号之后),按字符流读入嵌套结构体时,会先读入子结构体信息,而在处理子结构体时需要知道父结构体名,所以对整个结构体进行预先处理,形成名字树,树的节点结构对应于结构体的嵌套结构,每个树节点上存放对应结构体的名字;随后处理字符串队列时,遍历该树即可得到子结构体的全名;
将待处理字符串队列的元素依次弹出,放入一个字符串栈中,在碰到一个右花括号“}”时,即将字符串栈中对应于此“}”的内容弹出,处理对应的结构体;若结构体中存在嵌套子结构体,则其会比父结构体先进行处理),处理的内容包括记录非结构体数据类型元素、数组和位域元素;依据读入的花括号对数判断结构体是否结束。
如果结构体中的嵌套子结构体的元素已全部处理,则将其按规定的数据格式放入词典中,同时将子结构体按结构体变量形式压入原栈中,以供处理父结构体时保持其完整的信息;待父结构体解析完毕,将父结构体信息也按规定格式存入词典,子结构体信息存入词典时,其类型名为父结构体类型名+子结构体类型名,以便在使用数据词典时,根据父结构体进行逐级查找展开;
步骤2:解析得到的ICD数据信息,以树形列表的方式呈现,以供查看;对不同词典元素进行编辑后进行保存,以供下次使用或其他可配置动态测试环境调用;
步骤3:从ICD列表中选择待编辑的数据块,放到树形列表上,形成测试用例;在编辑测试用例后,将数据按其格式拼接组合为字节流发送给被测软件,完成动态测试。
所述步骤1的详细步骤如下:
步骤1:解析ICD头文件
在解析ICD头文件前,确保待解析的C语言头文件符合ANSIC语法,且经过任一C语言编译器编译通过,没有语法错误;解析ICD头文件分为解析结构体定义文件和结构体变量声明文件;
所述ICD结构体定义文件仅包含所有符合C语言语法的结构体定义,均具有成对花括号,结构体定义中同时包含简单数据类型元素和嵌套的结构体定义;
所述ICD结构体声明文件仅包含根据定义文件中出现的定义,声明的ICD结构体变量;先解析结构体定义文件,然后解析结构体变量声明文件和ICD变量展示同时进行。
所述解析ICD结构体定义文件的步骤如下:
步骤1.1
在解析程序中定义词典数据结构,定义规则如下:
a)词典是<结构体名字,结构体信息类StructNode>的键值对集合;
b)结构体名字类型是字符串;
c)结构体信息类StructNode是自定义类型,其中应包含以下字段:结构体类型(struct或union)、结构体类型名、结构体类型全名、该结构体定义的注释、该结构体子变量的列表容器(容器中每个元素类型都为ChildNode),其中,对于结构体类型全名,如果此结构体是嵌套定义结构体的子元素,则按嵌套层级顺序连接所有包含它的结构体的名字;
d)子元素类ChildNode为自定义类型,其中包含以下字段:在父结构体中此变量的类型名(对应填充StructNode里的结构体类型全名)、在父结构体中此变量的名字、在父结构体中此变量的个数(单个或者数组)、数组第二维维度(如果该变量是二维数组)、位域变量位数(如果是位域变量)、该变量的注释、变量值域、变量量纲。
定义结构体名字树数据结构,定义规则如下:
每个名字树节点持有指向其父节点、下一节点、子节点的三个指针,并持有表示本节点名字的字符串,以及用于深度优先遍历名字树的布尔值;
步骤1.2
逐字符读入待解析C语言头文件的内容,分割成字符串,提供给解析程序,所述分割步骤如下:
步骤1.2.1
置一个已读字符标志为假、一个已读字符串标志为假、一个已读字符变量为空、一个已读字符串为空;
步骤1.2.2
若已读字符串标志为假,执行步骤1.2.3;若已读字符串标志为真,则将已读字符串标志置假,并使用已读字符串,返回给解析程序;
步骤1.2.3
若已读字符标志为假,读入一个字符;若已读字符标志为真,则使用上次已读入字符,并将已读字符标志置假;
步骤1.2.4
若步骤1.2.3的字符是英文字母、下划线'_'或阿拉伯数字,则循环读入新字符,直到读入的新字符不是英文字母、下划线'_'或阿拉伯数字,并向解析程序提供该字符串;置已读字符标志为真,并记录刚读入的不是英文字母、下划线'_'或阿拉伯数字的字符,返回步骤1.2.2;
若步骤1.2.3的字符是冒号“:”、左方括号“[”或赋值号“=”,读入接下来的字符串,并置已读字符串标志为真,已读字符标志为真,并向解析程序返回步骤1.2.3读入的冒号“:”、左方括号“[”或赋值号“=”(作为字符串);返回步骤1.2.2;
若步骤1.2.3的字符是“#”,则从字符流读入一整行,随后返回步骤1.2.2;
若步骤1.2.3的字符是“/”,则再读入一个字符,若也是“/”,则读入一整行字符串;若再读入的字符是“/”,则持续读入并记录字符,直到读到字符串“*/”,将读到的“/*”和“*/”之间的字符串返回;向解析程序返回两个字符串:字符串“comment”,以及刚读入的字符串;返回步骤1.2.2;
若步骤1.2.3的字符是左花括号“{”、右花括号“}”、分号“;”、右方括号“]”,则将其作为字符串返回给解析程序;返回步骤1.2.2;
若步骤1.2.3的字符是缩进符“\t”或空格符“”,则返回步骤1.2.2;
若步骤1.2.3的字符是“\r”,则再读入一个字符,并向解析程序返回读入的新字符(按字符串返回);返回步骤1.2.2;
若步骤1.2.3的字符是“\n”,则再读一个字符,若新字符是“\r”,则返回步骤1.2.2;否则向解析程序返回读入的新字符(按字符串返回)。
步骤1.3
对ICD结构体定义文件的解析程序过程如下:
首先按步骤1.1的定义设置一个词典Dict,并设置一个待处理字符串队列容器,并对步骤1.2中分割得到的字符串流,按以下规则进行解析:
步骤1.3.1
如果读入的是空字符串,则结束解析过程;
如果读入的是结构体关键字“struct”或“union”,放入队列中;
如果读入的是关键字“typedef”,向后再分割一个单词,将后一个单词放入队列;
设置一个有字符串标志、一个名字树当前节点,并开始执行以下步骤;
步骤1.3.2
若有字符串标志为有,则将其置为无,并执行下一步,否则读入一个字符串;
步骤1.3.3
如果刚执行完步骤1.3.1,读入结构体关键字后,随后读入的字符串不是左花括号,则将此字符串记录下来,并返回步骤1.3.2;
步骤1.3.4
如果当前读入左花括号{,且是第一次读入,则创建此结构体名字树的根节点,并将其作为当前名字树节点;
若读入左花括号且非第一次读入,且当前名字树节点的子节点为空,则创建当前名字树节点的子节点,并将新建子节点作为当前节点;
若读入左花括号且非第一次读入,且当前名字树节点的子节点为非空,则创建一个当前节点的最后一个子节点的兄弟节点,并将新建节点作为当前节点;
以上三种情况都不成立,则执行步骤1.3.5;
完成判断上述三种情况并创建对应的名字树节点后,若步骤1.3.3中读入了非空字符串,则认为其是当前结构体的名字,将此字符串赋给当前名字树节点的名字字符串;
将左花括号放入队列,并跳到步骤1.3.2;
步骤1.3.5
若步骤1.3.2读入的是右花括号},将其放入队列,并读入下一个字符串;
若下一个字符串不是分号“;”,则将此字符串赋给当前名字树节点的名字字符串,并再读一个字符串,若其是左方括号[,再读入两个字符串,将这三个字符串按顺序放入队列;
若当前名字树节点的父节点非空,则将父节点置为当前节点,跳到步骤1.3.2;
步骤1.3.6
若步骤1.3.2读入的是关键字“struct”或“union”,将其放入队列,再读下一个字符串;
若下一个字符串是左花括号,则置有字符串标志为有,跳到步骤1.3.2;否则记录此字符串,并再读一个字符串,若读到的是左花括号,则置有字符串标志为有,跳到步骤1.3.2,否则将记录字符串和此字符串都放入队列,跳到步骤1.3.2;
步骤1.3.7
将步骤1.3.3-步骤1.3.6没有处理的字符串放入队列;
若左花括号个数不等于右花括号个数,跳到步骤1.3.2;否则设置一个全名字符串、一个存放被处理结构体里从第一层到当前层的元素的栈wordStack、一个存放当前被处理结构体里的元素的栈childStack、一个存放结构体类型“struct”或“union”的字符串栈structTypes,并执行以下步骤:
步骤1.3.8
弹出字符串队列的一个元素;
步骤1.3.9
若步骤1.3.8弹出的是左花括号,则深度优先遍历当前名字树,找到当前节点的第一个没有被遍历过的子节点,将此子节点设为当前节点;
若当前名字树节点不是名字树根节点,则在全名字符串的最后加一个字符“.”;
在全名字符串的最后加上当前名字树节点的名字;
步骤1.3.10
若步骤1.3.8弹出的是右花括号,执行本步骤-步骤1.3.16的操作,否则跳到步骤1.3.17;
若当前名字树节点不是名字树根节点,置一个子结构体带花括号的标记;
查看队列的下一个元素,若是左方括号“[”,则将此元素弹出,将队列下一个元素也弹出,将其记为结构体数组的元素个数(待用),再将队列下一个元素也弹出(这是类似struct{…}A[3]的形式);
新建一个步骤1.1所述的StructNode元素,命名为structNode;
将structNode的结构体类型全名structFullTypeName置为步骤1.3.9中得到的全名字符串,将structNode的结构体类型名structTypeName置为全名字符串中最后一个“.”字符之后的子字符串;
将childStack清空,并从wordStack中弹出元素,依次放入childStack中,直到弹出的元素是左花括号为止;
从structTypes弹出一个元素,赋给structNode的结构体类型;
执行步骤1.3.11;
步骤1.3.11
从childStack弹出一个字符串,如果是“\n”,则再弹出一个字符串,直到不是“\n”;
步骤1.3.12
新建一个步骤1.1所述的ChildNode元素childNode;顺序执行以下各段:
如果步骤1.3.11弹出的字符串是“comment”,则再弹出childStack中的一个元素,将其作为注释内容,并重复弹出元素,直到不再弹出“comment”,将得到的注释字符串连接起来,作为childNode的注释记录下来;
若当前弹出的字符串word是“struct”或“union”,再从childStack弹出一个字符串(形如struct A a;变量),将word值置为childNode的在父结构体中此变量的类型名varType;
如果当前字符串是“unsigned”,则看一下childStack的首元素是否是“int”、“long”、“short”、“char”,如果是,则弹出childStack的首元素,并将其连接在childNode.varType之后;
如果当前childNode.varType包含“short”字符串,且childStack的首元素是“int”,则弹出childStack的首元素,并将其连接在childNode.varType之后;
如果childNode.varType包含“long”字符串,且childStack的首元素是“int”,则弹出childStack的首元素,并将其连接在childNode.varType之后;否则若childStack的首元素是“long”,则弹出childStack的首元素,并将其连接在childNode.varType之后,并再次查看childStack的首元素,若childStack的首元素是“int”,则弹出childStack的首元素,并将其连接在childNode.varType之后;
步骤1.3.13
再从childStack弹出一个字符串,若当前字符串是“:”,则将childNode的在父结构体中此变量的名字varName置为空字符串“”,并从childStack新弹出一个元素,将childNode的位域变量位数bitNum置为新字符串对应的数值,将childNode的在父结构体中此变量的个数varNum置为1,再从childStack新弹出一个元素,验证其为字符串“;”(形如short:4;);
若上段开始弹出的字符串不是“:”,则将childNode.varName置为当前字符串,从childStack新弹出一个元素x,若x是“:”,则从childStack新弹出一个元素,将childNode.bitNum置为新字符串对应的数值,将childNode.varNum置为1,再从childStack新弹出一个元素,验证其为字符串“;”;若x是字符串“[”,从childStack新弹出一个元素,将childNode.varNum置为新字符串对应的数值,再弹出一个元素,验证其为“]”,再弹出一个元素,若其为“[”,则从childStack新弹出一个元素,将childNode的数组第二维维度varNum2置为新字符串对应的数值;
然后查看childStack的首个元素,若其为“comment”,则将“comment”随后的元素弹出,连接在childNode的注释之后;重复此过程直到childStack的首个元素不再为“comment”;
将childNode的注释值置为注释字符串;
在structNode的子变量列表容器中添加childNode;
若此时childStack不为空,返回步骤1.3.11,否则执行步骤1.3.14;
步骤1.3.14
若步骤1.3.10中所置的子结构体带花括号标记为真,将structNode.structFullTypeName、structNode.structTypeName依次压入wordStack栈中,且若步骤9)中有方括号,则将字符串“[”、结构体数组的元素个数对应的字符串、“]”依次压入栈中,最后将“;”压入栈中;
步骤1.3.15
判断步骤1.3.1前定义的词典Dict中是否存在以structNode.structFullTypeName为键名的键值对,如果没有,则将键值对<structNode.structFullTypeName,structNode>添加到Dict中;
步骤1.3.16
将步骤1.3.9中的当前名字树节点的已遍历属性置为真,并将当前名字树节点置为其父节点,若步骤1.3.9最后得到的全名字符串中包含“.”,则将其最后一个“.”以后的内容从全名字符串中删去;
步骤1.3.17
若步骤1.3.8弹出的是“struct”或“union”,则判断字符串队列的接下来几个元素是否能组成形如“struct A a;”或“union A a;”的形式,若不能,则在步骤1.3.7定义的structTypes栈中压入当前结构体类型(“struct”或“union”);
若步骤1.3.8弹出的是“typedef”,执行步骤1.3.18;
若步骤1.3.8弹出的是其它非空字符串,将其压入wordStack,执行步骤1.3.18;
步骤1.3.18
若字符串队列剩余元素为0,则跳到步骤1.3.1;否则跳到步骤1.3.8。
所述步骤2的详细步骤如下:
解析过每一个ICD结构体定义文件后,得到一个词典,使用此词典可以解析ICD变量声明文件,解析成功一个变量声明后,即可将其显示在软件界面的树形列表控件上;
解析ICD结构体声明并展示的具体过程如下:
首先定义一个字符串列表SimpleTypes,定义待处理的简单数据类型,里面包含表1定义的字符串;设操作界面上有一个树形控件IcdTreeList,能够任意添加层级节点;
表1简单数据类型对应的字符串
步骤2.1
打开一个ICD变量声明文件,使用步骤1.2的字符串分割方法分割字符串,并读入一个字符串;
步骤2.2
若步骤2.1中读入的字符串是“comment”,再读入一个字符串,将其记为注释字符串,重复此过程,直到不再读入“comment”;
连接所有的注释字符串成一个,执行步骤2.3;
步骤2.3
读入一个字符串,若其为空,则结束解析过程,否则将此字符串记为变量类型名,再读入一个字符串word,记为变量名,再读入一个字符串,判断其若为左方括号“[”,则再读入两个字符串,将最近三个字符串顺序连接到变量名之后,再读入一个字符串,确认其为“;”;若word为“;”,不进行处理;
步骤2.4
读入一个字符串,若其为“comment”,再读入一个字符串,将其连接在步骤2.2的注释字符串之后,重复此过程,直到不再读入“comment”,或读入的注释中包含字符“\n”;
步骤2.5
在树形控件IcdTreeList上新建一个根节点,根节点的名字即为步骤2.3的变量名;
步骤2.6
根据步骤2.3中的变量类型名,在词典中查找对应的StructNode类型数据structNode,对structNode中的子变量列表的每个ChildNode类型子变量childListNode,若childListNode的变量类型名存在于SimpleTypes中,则执行步骤2.7,否则执行步骤2.11;
步骤2.7
若步骤2.6的childListNode的变量个数varNum为1并且childListNode的变量名varName不包含左方括号“[”,则在当前树形控件根节点上增加一个子节点,名字就是childListNode的varName;
若步骤2.6的childListNode.varNum不为1或者childListNode.varName包含左方括号“[”,则若childListNode的varNum2大于0,执行步骤2.8,否则执行步骤2.9;
步骤2.8
在当前树形控件根节点上添加一个子节点,名字是childListNode.varName,以此子节点为根节点,添加两层子节点,第一层子节点个数为childListNode.varNum,第二层子节点个数为childListNode.varNum2;
步骤2.9
在当前树形控件根节点上添加一个子节点,名字是childListNode.varName,以此子节点为根节点,添加一层子节点,其个数为childListNode.varNum;若childListNode.varNum为1,且childListNode.varName不包含左方括号“[”,执行步骤2.10,否则执行步骤2.11;
步骤2.10
以childListNode.varName为名字,在当前树形控件根节点上添加一个子节点,并以此子节点为当前树形控件根节点,递归执行步骤2.6-步骤2.10;
步骤2.11
则以childListNode.varName为名字,在当前树形控件根节点上添加一个子节点,并以此子节点为根节点,添加一层子节点,其个数为childListNode.varNum,并以每个子节点为当前树形控件根节点,递归执行步骤2.6-步骤2.11;
步骤2.12
跳回步骤2.1执行,直到变量声明文件全部解析完毕。
以上步骤均执行完毕,便在软件界面上根据结构体变量列表得到一个完整的树形结构,随意点击ICD变量树上的节点,可通过界面显示节点上的对应变量信息,显示方法如步骤2.13-步骤2.14:
步骤2.13
判断若选中的节点对应的数据类型,若为词典中存在的结构体类型,则使用词典的信息对变量信息显示框赋值,否则执行下一步骤;
步骤2.14
若选中的节点对应的数据类型为简单数据类型,则获得其父节点NodeA的类型名A,在词典里查询,若仍未查到,将NodeA的父节点NodeB(其名字记为b)对应的类型名B,加上NodeA的名字a进行查找,即在词典中查找“B.a”,若仍未查到,将NodeB的父节点对应的类型名C,加上其它子节点的名字进行查找,即在词典中查找“C.b.a”,如此逐层上溯,直到在词典中查到选中节点的父节点的完整类型名,得到选中节点的父节点对应的类型structNode;在structNode的子变量列表中找到选中节点的名字后,对变量信息显示框赋值。
所述步骤3的详细步骤如下:
步骤3:基于ICD数据结构编辑和发送测试用例
设界面上有一个树形列表控件TestCaseList,可从步骤2的IcdTreeList中选择根数据块。则测试用例编辑界面可设计为,选择并拷贝根数据块到TestCaseList后,待编辑的数据块每行都显示有初始值、变化步长;树形列表控件的数据显示格式示例见表2,其中变量名字列具有树形层级嵌套的结构,每个变量名字节点对应一组初始值、步长、最小值、最大值;只有变量名字叶节点的值才能编辑,非叶节点的值编辑后无效。
表2树形列表的数据显示格式示例
一个树形列表的数据对应一个测试用例,用户在编辑其上的数据后选择发送测试用例,软件即可将当前编辑界面的数据块组织为字节流,通过TCP socket接口发送给经过插桩修改了数据接收方式、同样运行在PC机上的被测软件,向使用VC++编译运行的被测软件发送数据时,组织字节流的规则如下:
步骤3.1
对树形列表控件的各个数据块,分别执行以下步骤;
步骤3.2
对数据块的根节点,若其有子节点,则对每个子节点,递归执行步骤3.3-步骤3.8;若其没有子节点,说明其数据类型为简单数据类型,直接执行步骤3.8;
步骤3.3
使用步骤2.13-步骤2.14的处理方式,获取当前叶子节点的类型信息,若当前叶子节点是结构体位域元素,则执行步骤3.4-步骤3.7,否则执行步骤3.8;
步骤3.4
判断该叶子节点是否有上一个同父叶子节点,且上一个同父叶子节点也是按位域元素处理的,且这两个叶子节点的数据类型相同,且当前已拼接的位数加上当前叶子节点的位域位数小于这两个叶子节点的数据类型对应的字节数*8,(若条件不成立则转到步骤3.7)则将计算当前叶子节点的值加上步长*已过去的程序运行周期,将得到的值按已经拼接的位数左移,再加上已拼接的值;将已拼接的位数加上此叶子节点的位域位数;
步骤3.5
查看步骤3.4的叶子节点是否有下一个同父叶子节点,若有且下一个叶子节点不是位域元素,或下一个叶子节点的数据类型和当前节点不一致,则执行步骤3.6;
步骤3.6
若当前拼接的位数恰好等于当前节点的数据类型对应的字节数*8,或当前叶子节点没有下一个叶子节点,或步骤3.5的情况成立,则将当前拼接的值转化为字节流,输出到待发送字节流中,结束本次递归;
步骤3.7
若步骤3.4的条件不成立,则若当前叶子节点有下一个同父叶子节点,且下一个叶子节点也是位域元素、数据类型和当前叶子节点相同、数据类型对应的字节数*8大于这两者的位域位数之和,则将此节点按位域元素处理,预备和下一个叶子节点拼接,否则执行步骤3.8;
步骤3.8
若步骤3.4和步骤3.7的条件不成立,直接将当前叶子节点按照其数据类型的字节数转换为字节流,输出到待发送字节流中。
本发明的有益效果在于可以快速完成对ICD文件的解析,在解析ICD文件后,ICD结构信息以词典文件形式供编辑、查看,其它可配置集成测试环境也可以按照接口调用此词典文件,使用灵活;在ICD结构信息的自动显示的基础上,实现编辑、发送测试用例,能够显著提高某些软件的测试效率。
附图说明
图1为本发明的工作流程图。
具体实施方式
下面结合附图和实施例对本发明进一步说明。
本发明所述方法应用计算机编译技术的词法分析和语法分析原理,结合已有的软件树形列表控件,提供解析、展示、编辑和拼接发送ICD数据的方法。
步骤1:针对C语言结构体语法,在程序中自定义用于存放结构体信息的词典数据结构和名字树数据结构(详细定义见具体实施方式的步骤1.1);
读取字符流并按C语言语法规则分割为关键字和变量、常量词;
读入字符串流,依次放入一个待处理字符串队列中,并生成名字树:因为父结构体名经常出现在结构体的最后(右花括号之后),按字符流读入嵌套结构体时,会先读入子结构体信息,而在处理子结构体时需要知道父结构体名,所以对整个结构体进行预先处理,形成名字树,树的节点结构对应于结构体的嵌套结构,每个树节点上存放对应结构体的名字;随后处理字符串队列时,遍历该树即可得到子结构体的全名;
将待处理字符串队列的元素依次弹出,放入一个字符串栈中,在碰到一个右花括号“}”时,即将字符串栈中对应于此“}”的内容弹出,处理对应的结构体;若结构体中存在嵌套子结构体,则其会比父结构体先进行处理),处理的内容包括记录非结构体数据类型元素、数组和位域元素;依据读入的花括号对数判断结构体是否结束。
如果结构体中的嵌套子结构体的元素已全部处理,则将其按规定的数据格式放入词典中,同时将子结构体按结构体变量形式压入原栈中,以供处理父结构体时保持其完整的信息;待父结构体解析完毕,将父结构体信息也按规定格式存入词典。子结构体信息存入词典时,其类型名为父结构体类型名+子结构体类型名,以便在使用数据词典时,根据父结构体进行逐级查找展开;这种存储方法消除了结构体中存在的嵌套形式。
步骤2:解析得到的ICD数据信息,以树形列表的方式呈现,以供查看;对不同词典元素进行编辑后进行保存,以供下次使用或其他可配置动态测试环境调用;
步骤3:从ICD列表中选择待编辑的数据块,放到树形列表上,形成测试用例;在编辑测试用例后,将数据按其格式拼接组合为字节流发送给被测软件,完成动态测试。
如上3个步骤的详细步骤如下:
步骤1:解析ICD头文件
在解析ICD头文件前,确保待解析的C语言头文件符合ANSIC语法,且经过任一C语言编译器编译通过,没有语法错误;解析ICD头文件分为解析结构体定义文件(以下均用“结构体”代指C语言的结构体struct和联合体union)和结构体变量声明文件;
所述ICD结构体定义文件仅包含所有符合C语言语法的结构体定义,均具有成对花括号,结构体定义中同时包含简单数据类型元素(见表1定义)和嵌套的结构体定义;所述ICD结构体声明文件仅包含根据定义文件中出现的定义,声明的ICD结构体变量;先解析结构体定义文件,然后解析结构体变量声明文件和ICD变量展示同时进行。
以下叙述算法均可使用C#实现,但对其它面向对象语言如Java也适用。
所述解析ICD结构体定义文件的步骤如下:
步骤1.1
在解析程序中定义词典数据结构,定义规则如下:
a)词典是<结构体名字,结构体信息类StructNode>的键值对集合;
b)结构体名字类型是字符串;
c)结构体信息类StructNode是自定义类型,其中应包含以下字段:结构体类型(struct或union)、结构体类型名、结构体类型全名、该结构体定义的注释、该结构体子变量的列表容器(容器中每个元素类型都为ChildNode),其中,对于结构体类型全名,如果此结构体是嵌套定义结构体的子元素,则按嵌套层级顺序连接所有包含它的结构体的名字;
d)子元素类ChildNode为自定义类型,其中包含以下字段:在父结构体中此变量的类型名(对应填充StructNode里的结构体类型全名)、在父结构体中此变量的名字、在父结构体中此变量的个数(单个或者数组)、数组第二维维度(如果该变量是二维数组)、位域变量位数(如果是位域变量)、该变量的注释、变量值域、变量量纲。
定义结构体名字树数据结构,定义规则如下:
每个名字树节点持有指向其父节点、下一节点、子节点的三个指针,并持有表示本节点名字的字符串,以及用于深度优先遍历名字树的布尔值;
步骤1.2
逐字符读入待解析C语言头文件的内容,分割成字符串,提供给解析程序,所述分割步骤如下:
步骤1.2.1
置一个已读字符标志为假、一个已读字符串标志为假、一个已读字符变量为空、一个已读字符串为空;
步骤1.2.2
若已读字符串标志为假,执行步骤1.2.3;若已读字符串标志为真,则将已读字符串标志置假,并使用已读字符串,返回给解析程序;
步骤1.2.3
若已读字符标志为假,读入一个字符;若已读字符标志为真,则使用上次已读入字符,并将已读字符标志置假;
步骤1.2.4
若步骤1.2.3的字符是英文字母、下划线'_'或阿拉伯数字,则循环读入新字符,直到读入的新字符不是英文字母、下划线'_'或阿拉伯数字,并向解析程序提供该字符串;置已读字符标志为真,并记录刚读入的不是英文字母、下划线'_'或阿拉伯数字的字符,返回步骤1.2.2;
若步骤1.2.3的字符是冒号“:”、左方括号“[”或赋值号“=”,读入接下来的字符串,并置已读字符串标志为真,已读字符标志为真,并向解析程序返回步骤1.2.3读入的冒号“:”、左方括号“[”或赋值号“=”(作为字符串);返回步骤1.2.2;
若步骤1.2.3的字符是“#”,则从字符流读入一整行,随后返回步骤1.2.2;
若步骤1.2.3的字符是“/”,则再读入一个字符,若也是“/”,则读入一整行字符串;若再读入的字符是“/”,则持续读入并记录字符,直到读到字符串“*/”,将读到的“/*”和“*/”之间的字符串返回;向解析程序返回两个字符串:字符串“comment”,以及刚读入的字符串;返回步骤1.2.2;
若步骤1.2.3的字符是左花括号“{”、右花括号“}”、分号“;”、右方括号“]”,则将其作为字符串返回给解析程序;返回步骤1.2.2;
若步骤1.2.3的字符是缩进符“\t”或空格符“”,则返回步骤1.2.2;
若步骤1.2.3的字符是“\r”,则再读入一个字符,并向解析程序返回读入的新字符(按字符串返回);返回步骤1.2.2;
若步骤1.2.3的字符是“\n”,则再读一个字符,若新字符是“\r”,则返回步骤1.2.2;否则向解析程序返回读入的新字符(按字符串返回)。
步骤1.3
对ICD结构体定义文件的解析程序过程如下:
首先按步骤1.1的定义设置一个词典Dict,并设置一个待处理字符串队列容器,并对步骤1.2中分割得到的字符串流,按以下规则进行解析:
步骤1.3.1
如果读入的是空字符串,则结束解析过程;
如果读入的是结构体关键字“struct”或“union”,放入队列中;
如果读入的是关键字“typedef”,向后再分割一个单词,将后一个单词放入队列;
设置一个有字符串标志、一个名字树当前节点,并开始执行以下步骤;
步骤1.3.2
若有字符串标志为有,则将其置为无,并执行下一步,否则读入一个字符串;
步骤1.3.3
如果刚执行完步骤1.3.1,读入结构体关键字后,随后读入的字符串不是左花括号,则将此字符串记录下来,并返回步骤1.3.2;
步骤1.3.4
如果当前读入左花括号{,且是第一次读入,则创建此结构体名字树的根节点,并将其作为当前名字树节点;
若读入左花括号且非第一次读入,且当前名字树节点的子节点为空,则创建当前名字树节点的子节点,并将新建子节点作为当前节点;
若读入左花括号且非第一次读入,且当前名字树节点的子节点为非空,则创建一个当前节点的最后一个子节点的兄弟节点,并将新建节点作为当前节点;
以上三种情况都不成立,则执行步骤1.3.5;
完成判断上述三种情况并创建对应的名字树节点后,若步骤1.3.3中读入了非空字符串,则认为其是当前结构体的名字,将此字符串赋给当前名字树节点的名字字符串;
将左花括号放入队列,并跳到步骤1.3.2;
步骤1.3.5
若步骤1.3.2读入的是右花括号},将其放入队列,并读入下一个字符串;
若下一个字符串不是分号“;”,则将此字符串赋给当前名字树节点的名字字符串,并再读一个字符串,若其是左方括号[,再读入两个字符串,将这三个字符串按顺序放入队列;
若当前名字树节点的父节点非空,则将父节点置为当前节点,跳到步骤1.3.2;
步骤1.3.6
若步骤1.3.2读入的是关键字“struct”或“union”,将其放入队列,再读下一个字符串;
若下一个字符串是左花括号,则置有字符串标志为有,跳到步骤1.3.2;否则记录此字符串,并再读一个字符串,若读到的是左花括号,则置有字符串标志为有,跳到步骤1.3.2,否则将记录字符串和此字符串都放入队列,跳到步骤1.3.2;
步骤1.3.7
将步骤1.3.3-步骤1.3.6没有处理的字符串放入队列;
若左花括号个数不等于右花括号个数,跳到步骤1.3.2;否则设置一个全名字符串、一个存放被处理结构体里从第一层到当前层的元素的栈wordStack、一个存放当前被处理结构体里的元素的栈childStack、一个存放结构体类型“struct”或“union”的字符串栈structTypes,并执行以下步骤:
步骤1.3.8
弹出字符串队列的一个元素;
步骤1.3.9
若步骤1.3.8弹出的是左花括号,则深度优先遍历当前名字树,找到当前节点的第一个没有被遍历过的子节点,将此子节点设为当前节点;
若当前名字树节点不是名字树根节点,则在全名字符串的最后加一个字符“.”;
在全名字符串的最后加上当前名字树节点的名字;
步骤1.3.10
若步骤1.3.8弹出的是右花括号,执行本步骤-步骤1.3.16的操作,否则跳到步骤1.3.17;
若当前名字树节点不是名字树根节点,置一个子结构体带花括号的标记;
查看队列的下一个元素,若是左方括号“[”,则将此元素弹出,将队列下一个元素也弹出,将其记为结构体数组的元素个数(待用),再将队列下一个元素也弹出(这是类似struct{…}A[3]的形式);
新建一个步骤1.1所述的StructNode元素,命名为structNode;
将structNode的结构体类型全名structFullTypeName置为步骤1.3.9中得到的全名字符串,将structNode的结构体类型名structTypeName置为全名字符串中最后一个“.”字符之后的子字符串;
将childStack清空,并从wordStack中弹出元素,依次放入childStack中,直到弹出的元素是左花括号为止;
从structTypes弹出一个元素,赋给structNode的结构体类型;
执行步骤1.3.11;
步骤1.3.11
从childStack弹出一个字符串,如果是“\n”,则再弹出一个字符串,直到不是“\n”;
步骤1.3.12
新建一个步骤1.1所述的ChildNode元素childNode;顺序执行以下各段:
如果步骤1.3.11弹出的字符串是“comment”,则再弹出childStack中的一个元素,将其作为注释内容,并重复弹出元素,直到不再弹出“comment”,将得到的注释字符串连接起来,作为childNode的注释记录下来;
若当前弹出的字符串word是“struct”或“union”,再从childStack弹出一个字符串(形如struct A a;变量),将word值置为childNode的在父结构体中此变量的类型名varType;
如果当前字符串是“unsigned”,则看一下childStack的首元素是否是“int”、“long”、“short”、“char”,如果是,则弹出childStack的首元素,并将其连接在childNode.varType之后;
如果当前childNode.varType包含“short”字符串,且childStack的首元素是“int”,则弹出childStack的首元素,并将其连接在childNode.varType之后;
如果childNode.varType包含“long”字符串,且childStack的首元素是“int”,则弹出childStack的首元素,并将其连接在childNode.varType之后;否则若childStack的首元素是“long”,则弹出childStack的首元素,并将其连接在childNode.varType之后,并再次查看childStack的首元素,若childStack的首元素是“int”,则弹出childStack的首元素,并将其连接在childNode.varType之后;
步骤1.3.13
再从childStack弹出一个字符串,若当前字符串是“:”,则将childNode的在父结构体中此变量的名字varName置为空字符串“”,并从childStack新弹出一个元素,将childNode的位域变量位数bitNum置为新字符串对应的数值,将childNode的在父结构体中此变量的个数varNum置为1,再从childStack新弹出一个元素,验证其为字符串“;”(形如short:4;);
若上段开始弹出的字符串不是“:”,则将childNode.varName置为当前字符串,从childStack新弹出一个元素x,若x是“:”,则从childStack新弹出一个元素,将childNode.bitNum置为新字符串对应的数值,将childNode.varNum置为1,再从childStack新弹出一个元素,验证其为字符串“;”;若x是字符串“[”,从childStack新弹出一个元素,将childNode.varNum置为新字符串对应的数值,再弹出一个元素,验证其为“]”,再弹出一个元素,若其为“[”,则从childStack新弹出一个元素,将childNode的数组第二维维度varNum2置为新字符串对应的数值;
然后查看childStack的首个元素,若其为“comment”,则将“comment”随后的元素弹出,连接在childNode的注释之后;重复此过程直到childStack的首个元素不再为“comment”;
将childNode的注释值置为注释字符串;
在structNode的子变量列表容器中添加childNode;
若此时childStack不为空,返回步骤1.3.11,否则执行步骤1.3.14;
步骤1.3.14
若步骤1.3.10中所置的子结构体带花括号标记为真,将structNode.structFullTypeName、structNode.structTypeName依次压入wordStack栈中,且若步骤9)中有方括号,则将字符串“[”、结构体数组的元素个数对应的字符串、“]”依次压入栈中,最后将“;”压入栈中;
步骤1.3.15
判断步骤1.3.1前定义的词典Dict中是否存在以structNode.structFullTypeName为键名的键值对,如果没有,则将键值对<structNode.structFullTypeName,structNode>添加到Dict中;
步骤1.3.16
将步骤1.3.9中的当前名字树节点的已遍历属性置为真,并将当前名字树节点置为其父节点,若步骤1.3.9最后得到的全名字符串中包含“.”,则将其最后一个“.”以后的内容从全名字符串中删去;
步骤1.3.17
若步骤1.3.8弹出的是“struct”或“union”,则判断字符串队列的接下来几个元素是否能组成形如“struct A a;”或“union A a;”的形式,若不能,则在步骤1.3.7定义的structTypes栈中压入当前结构体类型(“struct”或“union”);
若步骤1.3.8弹出的是“typedef”,执行步骤1.3.18;
若步骤1.3.8弹出的是其它非空字符串,将其压入wordStack,执行步骤1.3.18;
步骤1.3.18
若字符串队列剩余元素为0,则跳到步骤1.3.1;否则跳到步骤1.3.8。
步骤2:展示ICD变量
解析过每一个ICD结构体定义文件后,得到一个词典,使用此词典可以解析ICD变量声明文件,解析成功一个变量声明后,即可将其显示在软件界面的树形列表控件上;
解析ICD结构体声明并展示的具体过程如下:
首先定义一个字符串列表SimpleTypes,定义待处理的简单数据类型,里面包含表2定义的字符串;设操作界面上有一个树形控件IcdTreeList,能够任意添加层级节点;
表2简单数据类型对应的字符串
随后执行以下步骤:
步骤2.1
打开一个ICD变量声明文件,使用步骤1.2的字符串分割方法分割字符串,并读入一个字符串;
步骤2.2
若步骤2.1中读入的字符串是“comment”,再读入一个字符串,将其记为注释字符串,重复此过程,直到不再读入“comment”;
连接所有的注释字符串成一个,执行步骤2.3;
步骤2.3
读入一个字符串,若其为空,则结束解析过程,否则将此字符串记为变量类型名,再读入一个字符串word,记为变量名,再读入一个字符串,判断其若为左方括号“[”,则再读入两个字符串,将最近三个字符串顺序连接到变量名之后,再读入一个字符串,确认其为“;”;若word为“;”,不进行处理;
步骤2.4
读入一个字符串,若其为“comment”,再读入一个字符串,将其连接在步骤2.2的注释字符串之后,重复此过程,直到不再读入“comment”,或读入的注释中包含字符“\n”;
步骤2.5
在树形控件IcdTreeList上新建一个根节点,根节点的名字即为步骤2.3的变量名;
步骤2.6
根据步骤2.3中的变量类型名,在词典中查找对应的StructNode类型数据structNode,对structNode中的子变量列表的每个ChildNode类型子变量childListNode,若childListNode的变量类型名存在于SimpleTypes中,则执行步骤2.7,否则执行步骤2.11;
步骤2.7
若步骤2.6的childListNode的变量个数varNum为1并且childListNode的变量名varName不包含左方括号“[”,则在当前树形控件根节点上增加一个子节点,名字就是childListNode的varName;
若步骤2.6的childListNode.varNum不为1或者childListNode.varName包含左方括号“[”,则若childListNode的varNum2大于0,执行步骤2.8,否则执行步骤2.9;
步骤2.8
在当前树形控件根节点上添加一个子节点,名字是childListNode.varName,以此子节点为根节点,添加两层子节点,第一层子节点个数为childListNode.varNum,第二层子节点个数为childListNode.varNum2;
步骤2.9
在当前树形控件根节点上添加一个子节点,名字是childListNode.varName,以此子节点为根节点,添加一层子节点,其个数为childListNode.varNum;若childListNode.varNum为1,且childListNode.varName不包含左方括号“[”,执行步骤2.10,否则执行步骤2.11;
步骤2.10
以childListNode.varName为名字,在当前树形控件根节点上添加一个子节点,并以此子节点为当前树形控件根节点,递归执行步骤2.6-步骤2.10;
步骤2.11
则以childListNode.varName为名字,在当前树形控件根节点上添加一个子节点,并以此子节点为根节点,添加一层子节点,其个数为childListNode.varNum,并以每个子节点为当前树形控件根节点,递归执行步骤2.6-步骤2.11;
步骤2.12
跳回步骤2.1执行,直到变量声明文件全部解析完毕。
以上步骤均执行完毕,便在软件界面上根据结构体变量列表得到一个完整的树形结构,随意点击ICD变量树上的节点,可通过界面显示节点上的对应变量信息,显示方法如步骤2.13-步骤2.14:
步骤2.13
判断若选中的节点对应的数据类型,若为词典中存在的结构体类型,则使用词典的信息对变量信息显示框赋值,否则执行下一步骤;
步骤2.14
若选中的节点对应的数据类型为简单数据类型,则获得其父节点NodeA的类型名A,在词典里查询,若仍未查到,将NodeA的父节点NodeB(其名字记为b)对应的类型名B,加上NodeA的名字a进行查找,即在词典中查找“B.a”,若仍未查到,将NodeB的父节点对应的类型名C,加上其它子节点的名字进行查找,即在词典中查找“C.b.a”,如此逐层上溯,直到在词典中查到选中节点的父节点的完整类型名,得到选中节点的父节点对应的类型structNode;在structNode的子变量列表中找到选中节点的名字后,对变量信息显示框赋值。
ICD变量的信息中,变量值域、MSB、LSB、变量量纲需要用户手动编辑并保存到当前节点对应的词典元素中,然后序列化保存(使用C#自带的序列化接口函数即可)当前词典对象,下次使用时可以再次读入。
步骤3:基于ICD数据结构编辑和发送测试用例
设界面上有一个树形列表控件TestCaseList,可从步骤2的IcdTreeList中选择根数据块。则测试用例编辑界面可设计为,选择并拷贝根数据块到TestCaseList后,待编辑的数据块每行都显示有初始值、变化步长(还有最小值和最大值可选);树形列表控件的数据显示格式示例见2,其中变量名字列具有树形层级嵌套的结构,每个变量名字节点对应一组初始值、步长、最小值、最大值;只有变量名字叶节点的值才能编辑,非叶节点的值编辑后无效。
表2树形列表的数据显示格式示例
一个树形列表的数据对应一个测试用例,用户在编辑其上的数据后选择发送测试用例,软件即可将当前编辑界面的数据块组织为字节流,通过TCP socket接口发送给经过插桩修改了数据接收方式、同样运行在PC机上的被测软件,向使用VC++编译运行的被测软件发送数据时,组织字节流的规则如下:
步骤3.1
对树形列表控件的各个数据块,分别执行以下步骤;
步骤3.2
对数据块的根节点,若其有子节点,则对每个子节点,递归执行步骤3.3-步骤3.8;若其没有子节点,说明其数据类型为简单数据类型,直接执行步骤3.8;
步骤3.3
使用步骤2.13-步骤2.14的处理方式,获取当前叶子节点的类型信息,若当前叶子节点是结构体位域元素,则执行步骤3.4-步骤3.7,否则执行步骤3.8;
步骤3.4
判断该叶子节点是否有上一个同父叶子节点,且上一个同父叶子节点也是按位域元素处理的,且这两个叶子节点的数据类型相同,且当前已拼接的位数加上当前叶子节点的位域位数小于这两个叶子节点的数据类型对应的字节数*8,(若条件不成立则转到步骤3.7)则将计算当前叶子节点的值加上步长*已过去的程序运行周期,将得到的值按已经拼接的位数左移,再加上已拼接的值;将已拼接的位数加上此叶子节点的位域位数;
步骤3.5
查看步骤3.4的叶子节点是否有下一个同父叶子节点,若有且下一个叶子节点不是位域元素,或下一个叶子节点的数据类型和当前节点不一致,则执行步骤3.6;
步骤3.6
若当前拼接的位数恰好等于当前节点的数据类型对应的字节数*8,或当前叶子节点没有下一个叶子节点,或步骤3.5的情况成立,则将当前拼接的值转化为字节流,输出到待发送字节流中,结束本次递归;
步骤3.7
若步骤3.4的条件不成立,则若当前叶子节点有下一个同父叶子节点,且下一个叶子节点也是位域元素、数据类型和当前叶子节点相同、数据类型对应的字节数*8大于这两者的位域位数之和,则将此节点按位域元素处理,预备和下一个叶子节点拼接,否则执行步骤3.8;
步骤3.8
若步骤3.4和步骤3.7的条件不成立,直接将当前叶子节点按照其数据类型的字节数转换为字节流,输出到待发送字节流中。
Claims (4)
1.一种基于接口控制文件的软件测试用例辅助设计方法,其特征在于包括下述步骤:
步骤1:针对C语言结构体语法,在程序中自定义用于存放结构体信息的词典数据结构和名字树数据结构;
读取字符流并按C语言语法规则分割为关键字和变量、常量词;
读入字符串流,依次放入一个待处理字符串队列中,并生成名字树:因为父结构体名经常出现在结构体的最后(右花括号之后),按字符流读入嵌套结构体时,会先读入子结构体信息,而在处理子结构体时需要知道父结构体名,所以对整个结构体进行预先处理,形成名字树,树的节点结构对应于结构体的嵌套结构,每个树节点上存放对应结构体的名字;随后处理字符串队列时,遍历该树即可得到子结构体的全名;
将待处理字符串队列的元素依次弹出,放入一个字符串栈中,在碰到一个右花括号“}”时,即将字符串栈中对应于此“}”的内容弹出,处理对应的结构体;若结构体中存在嵌套子结构体,则其会比父结构体先进行处理),处理的内容包括记录非结构体数据类型元素、数组和位域元素;依据读入的花括号对数判断结构体是否结束;
如果结构体中的嵌套子结构体的元素已全部处理,则将其按规定的数据格式放入词典中,同时将子结构体按结构体变量形式压入原栈中,以供处理父结构体时保持其完整的信息;待父结构体解析完毕,将父结构体信息也按规定格式存入词典,子结构体信息存入词典时,其类型名为父结构体类型名+子结构体类型名,以便在使用数据词典时,根据父结构体进行逐级查找展开;
步骤2:解析得到的ICD数据信息,以树形列表的方式呈现,以供查看;对不同词典元素进行编辑后进行保存,以供下次使用或其他可配置动态测试环境调用;
步骤3:从ICD列表中选择待编辑的数据块,放到树形列表上,形成测试用例;在编辑测试用例后,将数据按其格式拼接组合为字节流发送给被测软件,完成动态测试。
2.根据权利要求1所述的一种基于接口控制文件的软件测试用例辅助设计方法,其特征在于:
所述步骤1的详细步骤如下:
步骤1:解析ICD头文件
在解析ICD头文件前,确保待解析的C语言头文件符合ANSIC语法,且经过任一C语言编译器编译通过,没有语法错误;解析ICD头文件分为解析结构体定义文件和结构体变量声明文件;
所述ICD结构体定义文件仅包含所有符合C语言语法的结构体定义,均具有成对花括号,结构体定义中同时包含简单数据类型元素和嵌套的结构体定义;
所述ICD结构体声明文件仅包含根据定义文件中出现的定义,声明的ICD结构体变量;先解析结构体定义文件,然后解析结构体变量声明文件和ICD变量展示同时进行;
所述解析ICD结构体定义文件的步骤如下:
步骤1.1
在解析程序中定义词典数据结构,定义规则如下:
a)词典是<结构体名字,结构体信息类StructNode>的键值对集合;
b)结构体名字类型是字符串;
c)结构体信息类StructNode是自定义类型,其中应包含以下字段:结构体类型(struct或union)、结构体类型名、结构体类型全名、该结构体定义的注释、该结构体子变量的列表容器(容器中每个元素类型都为ChildNode),其中,对于结构体类型全名,如果此结构体是嵌套定义结构体的子元素,则按嵌套层级顺序连接所有包含它的结构体的名字;
d)子元素类ChildNode为自定义类型,其中包含以下字段:在父结构体中此变量的类型名(对应填充StructNode里的结构体类型全名)、在父结构体中此变量的名字、在父结构体中此变量的个数(单个或者数组)、数组第二维维度(如果该变量是二维数组)、位域变量位数(如果是位域变量)、该变量的注释、变量值域、变量量纲;
定义结构体名字树数据结构,定义规则如下:
每个名字树节点持有指向其父节点、下一节点、子节点的三个指针,并持有表示本节点名字的字符串,以及用于深度优先遍历名字树的布尔值;
步骤1.2
逐字符读入待解析C语言头文件的内容,分割成字符串,提供给解析程序,所述分割步骤如下:
步骤1.2.1
置一个已读字符标志为假、一个已读字符串标志为假、一个已读字符变量为空、一个已读字符串为空;
步骤1.2.2
若已读字符串标志为假,执行步骤1.2.3;若已读字符串标志为真,则将已读字符串标志置假,并使用已读字符串,返回给解析程序;
步骤1.2.3
若已读字符标志为假,读入一个字符;若已读字符标志为真,则使用上次已读入字符,并将已读字符标志置假;
步骤1.2.4
若步骤1.2.3的字符是英文字母、下划线'_'或阿拉伯数字,则循环读入新字符,直到读入的新字符不是英文字母、下划线'_'或阿拉伯数字,并向解析程序提供该字符串;置已读字符标志为真,并记录刚读入的不是英文字母、下划线'_'或阿拉伯数字的字符,返回步骤1.2.2;
若步骤1.2.3的字符是冒号“:”、左方括号“[”或赋值号“=”,读入接下来的字符串,并置已读字符串标志为真,已读字符标志为真,并向解析程序返回步骤1.2.3读入的冒号“:”、左方括号“[”或赋值号“=”(作为字符串);返回步骤1.2.2;
若步骤1.2.3的字符是“#”,则从字符流读入一整行,随后返回步骤1.2.2;
若步骤1.2.3的字符是“/”,则再读入一个字符,若也是“/”,则读入一整行字符串;若再读入的字符是“/”,则持续读入并记录字符,直到读到字符串“*/”,将读到的“/*”和“*/”之间的字符串返回;向解析程序返回两个字符串:字符串“comment”,以及刚读入的字符串;返回步骤1.2.2;
若步骤1.2.3的字符是左花括号“{”、右花括号“}”、分号“;”、右方括号“]”,则将其作为字符串返回给解析程序;返回步骤1.2.2;
若步骤1.2.3的字符是缩进符“\t”或空格符“”,则返回步骤1.2.2;
若步骤1.2.3的字符是“\r”,则再读入一个字符,并向解析程序返回读入的新字符(按字符串返回);返回步骤1.2.2;
若步骤1.2.3的字符是“\n”,则再读一个字符,若新字符是“\r”,则返回步骤1.2.2;否则向解析程序返回读入的新字符(按字符串返回);
步骤1.3
对ICD结构体定义文件的解析程序过程如下:
首先按步骤1.1的定义设置一个词典Dict,并设置一个待处理字符串队列容器,并对步骤1.2中分割得到的字符串流,按以下规则进行解析:
步骤1.3.1
如果读入的是空字符串,则结束解析过程;
如果读入的是结构体关键字“struct”或“union”,放入队列中;
如果读入的是关键字“typedef”,向后再分割一个单词,将后一个单词放入队列;
设置一个有字符串标志、一个名字树当前节点,并开始执行以下步骤;
步骤1.3.2
若有字符串标志为有,则将其置为无,并执行下一步,否则读入一个字符串;
步骤1.3.3
如果刚执行完步骤1.3.1,读入结构体关键字后,随后读入的字符串不是左花括号,则将此字符串记录下来,并返回步骤1.3.2;
步骤1.3.4
如果当前读入左花括号{,且是第一次读入,则创建此结构体名字树的根节点,并将其作为当前名字树节点;
若读入左花括号且非第一次读入,且当前名字树节点的子节点为空,则创建当前名字树节点的子节点,并将新建子节点作为当前节点;
若读入左花括号且非第一次读入,且当前名字树节点的子节点为非空,则创建一个当前节点的最后一个子节点的兄弟节点,并将新建节点作为当前节点;
以上三种情况都不成立,则执行步骤1.3.5;
完成判断上述三种情况并创建对应的名字树节点后,若步骤1.3.3中读入了非空字符串,则认为其是当前结构体的名字,将此字符串赋给当前名字树节点的名字字符串;
将左花括号放入队列,并跳到步骤1.3.2;
步骤1.3.5
若步骤1.3.2读入的是右花括号},将其放入队列,并读入下一个字符串;
若下一个字符串不是分号“;”,则将此字符串赋给当前名字树节点的名字字符串,并再读一个字符串,若其是左方括号[,再读入两个字符串,将这三个字符串按顺序放入队列;
若当前名字树节点的父节点非空,则将父节点置为当前节点,跳到步骤1.3.2;
步骤1.3.6
若步骤1.3.2读入的是关键字“struct”或“union”,将其放入队列,再读下一个字符串;
若下一个字符串是左花括号,则置有字符串标志为有,跳到步骤1.3.2;否则记录此字符串,并再读一个字符串,若读到的是左花括号,则置有字符串标志为有,跳到步骤1.3.2,否则将记录字符串和此字符串都放入队列,跳到步骤1.3.2;
步骤1.3.7
将步骤1.3.3-步骤1.3.6没有处理的字符串放入队列;
若左花括号个数不等于右花括号个数,跳到步骤1.3.2;否则设置一个全名字符串、一个存放被处理结构体里从第一层到当前层的元素的栈wordStack、一个存放当前被处理结构体里的元素的栈childStack、一个存放结构体类型“struct”或“union”的字符串栈structTypes,并执行以下步骤:
步骤1.3.8
弹出字符串队列的一个元素;
步骤1.3.9
若步骤1.3.8弹出的是左花括号,则深度优先遍历当前名字树,找到当前节点的第一个没有被遍历过的子节点,将此子节点设为当前节点;
若当前名字树节点不是名字树根节点,则在全名字符串的最后加一个字符“.”;
在全名字符串的最后加上当前名字树节点的名字;
步骤1.3.10
若步骤1.3.8弹出的是右花括号,执行本步骤-步骤1.3.16的操作,否则跳到步骤1.3.17;
若当前名字树节点不是名字树根节点,置一个子结构体带花括号的标记;
查看队列的下一个元素,若是左方括号“[”,则将此元素弹出,将队列下一个元素也弹出,将其记为结构体数组的元素个数(待用),再将队列下一个元素也弹出(这是类似struct{…}A[3]的形式);
新建一个步骤1.1所述的StructNode元素,命名为structNode;
将structNode的结构体类型全名structFullTypeName置为步骤1.3.9中得到的全名字符串,将structNode的结构体类型名structTypeName置为全名字符串中最后一个“.”字符之后的子字符串;
将childStack清空,并从wordStack中弹出元素,依次放入childStack中,直到弹出的元素是左花括号为止;
从structTypes弹出一个元素,赋给structNode的结构体类型;
执行步骤1.3.11;
步骤1.3.11
从childStack弹出一个字符串,如果是“\n”,则再弹出一个字符串,直到不是“\n”;
步骤1.3.12
新建一个步骤1.1所述的ChildNode元素childNode;顺序执行以下各段:
如果步骤1.3.11弹出的字符串是“comment”,则再弹出childStack中的一个元素,将其作为注释内容,并重复弹出元素,直到不再弹出“comment”,将得到的注释字符串连接起来,作为childNode的注释记录下来;
若当前弹出的字符串word是“struct”或“union”,再从childStack弹出一个字符串(形如struct A a;变量),将word值置为childNode的在父结构体中此变量的类型名varType;
如果当前字符串是“unsigned”,则看一下childStack的首元素是否是“int”、“long”、“short”、“char”,如果是,则弹出childStack的首元素,并将其连接在childNode.varType之后;
如果当前childNode.varType包含“short”字符串,且childStack的首元素是“int”,则弹出childStack的首元素,并将其连接在childNode.varType之后;
如果childNode.varType包含“long”字符串,且childStack的首元素是“int”,则弹出childStack的首元素,并将其连接在childNode.varType之后;否则若childStack的首元素是“long”,则弹出childStack的首元素,并将其连接在childNode.varType之后,并再次查看childStack的首元素,若childStack的首元素是“int”,则弹出childStack的首元素,并将其连接在childNode.varType之后;
步骤1.3.13
再从childStack弹出一个字符串,若当前字符串是“:”,则将childNode的在父结构体中此变量的名字varName置为空字符串“”,并从childStack新弹出一个元素,将childNode的位域变量位数bitNum置为新字符串对应的数值,将childNode的在父结构体中此变量的个数varNum置为1,再从childStack新弹出一个元素,验证其为字符串“;”(形如short:4;);
若上段开始弹出的字符串不是“:”,则将childNode.varName置为当前字符串,从childStack新弹出一个元素x,若x是“:”,则从childStack新弹出一个元素,将childNode.bitNum置为新字符串对应的数值,将childNode.varNum置为1,再从childStack新弹出一个元素,验证其为字符串“;”;若x是字符串“[”,从childStack新弹出一个元素,将childNode.varNum置为新字符串对应的数值,再弹出一个元素,验证其为“]”,再弹出一个元素,若其为“[”,则从childStack新弹出一个元素,将childNode的数组第二维维度varNum2置为新字符串对应的数值;
然后查看childStack的首个元素,若其为“comment”,则将“comment”随后的元素弹出,连接在childNode的注释之后;重复此过程直到childStack的首个元素不再为“comment”;
将childNode的注释值置为注释字符串;
在structNode的子变量列表容器中添加childNode;
若此时childStack不为空,返回步骤1.3.11,否则执行步骤1.3.14;
步骤1.3.14
若步骤1.3.10中所置的子结构体带花括号标记为真,将structNode.structFullTypeName、structNode.structTypeName依次压入wordStack栈中,且若步骤9)中有方括号,则将字符串“[”、结构体数组的元素个数对应的字符串、“]”依次压入栈中,最后将“;”压入栈中;
步骤1.3.15
判断步骤1.3.1前定义的词典Dict中是否存在以structNode.structFullTypeName为键名的键值对,如果没有,则将键值对<structNode.structFullTypeName,structNode>添加到Dict中;
步骤1.3.16
将步骤1.3.9中的当前名字树节点的已遍历属性置为真,并将当前名字树节点置为其父节点,若步骤1.3.9最后得到的全名字符串中包含“.”,则将其最后一个“.”以后的内容从全名字符串中删去;
步骤1.3.17
若步骤1.3.8弹出的是“struct”或“union”,则判断字符串队列的接下来几个元素是否能组成形如“struct Aa;”或“union Aa;”的形式,若不能,则在步骤1.3.7定义的structTypes栈中压入当前结构体类型(“struct”或“union”);
若步骤1.3.8弹出的是“typedef”,执行步骤1.3.18;
若步骤1.3.8弹出的是其它非空字符串,将其压入wordStack,执行步骤1.3.18;
步骤1.3.18
若字符串队列剩余元素为0,则跳到步骤1.3.1;否则跳到步骤1.3.8。
3.根据权利要求1所述的一种基于接口控制文件的软件测试用例辅助设计方法,其特征在于:
所述步骤2的详细步骤如下:
解析过每一个ICD结构体定义文件后,得到一个词典,使用此词典可以解析ICD变量声明文件,解析成功一个变量声明后,即可将其显示在软件界面的树形列表控件上;
解析ICD结构体声明并展示的具体过程如下:
首先定义一个字符串列表SimpleTypes,定义待处理的简单数据类型,里面包含表1定义的字符串;设操作界面上有一个树形控件IcdTreeList,能够任意添加层级节点;
表1 简单数据类型对应的字符串
步骤2.1
打开一个ICD变量声明文件,使用步骤1.2的字符串分割方法分割字符串,并读入一个字符串;
步骤2.2
若步骤2.1中读入的字符串是“comment”,再读入一个字符串,将其记为注释字符串,重复此过程,直到不再读入“comment”;
连接所有的注释字符串成一个,执行步骤2.3;
步骤2.3
读入一个字符串,若其为空,则结束解析过程,否则将此字符串记为变量类型名,再读入一个字符串word,记为变量名,再读入一个字符串,判断其若为左方括号“[”,则再读入两个字符串,将最近三个字符串顺序连接到变量名之后,再读入一个字符串,确认其为“;”;若word为“;”,不进行处理;
步骤2.4
读入一个字符串,若其为“comment”,再读入一个字符串,将其连接在步骤2.2的注释字符串之后,重复此过程,直到不再读入“comment”,或读入的注释中包含字符“\n”;
步骤2.5
在树形控件IcdTreeList上新建一个根节点,根节点的名字即为步骤2.3的变量名;
步骤2.6
根据步骤2.3中的变量类型名,在词典中查找对应的StructNode类型数据structNode,对structNode中的子变量列表的每个ChildNode类型子变量childListNode,若childListNode的变量类型名存在于SimpleTypes中,则执行步骤2.7,否则执行步骤2.11;
步骤2.7
若步骤2.6的childListNode的变量个数varNum为1并且childListNode的变量名varName不包含左方括号“[”,则在当前树形控件根节点上增加一个子节点,名字就是childListNode的varName;
若步骤2.6的childListNode.varNum不为1或者childListNode.varName包含左方括号“[”,则若childListNode的varNum2大于0,执行步骤2.8,否则执行步骤2.9;
步骤2.8
在当前树形控件根节点上添加一个子节点,名字是childListNode.varName,以此子节点为根节点,添加两层子节点,第一层子节点个数为childListNode.varNum,第二层子节点个数为childListNode.varNum2;
步骤2.9
在当前树形控件根节点上添加一个子节点,名字是childListNode.varName,以此子节点为根节点,添加一层子节点,其个数为childListNode.varNum;若childListNode.varNum为1,且childListNode.varName不包含左方括号“[”,执行步骤2.10,否则执行步骤2.11;
步骤2.10
以childListNode.varName为名字,在当前树形控件根节点上添加一个子节点,并以此子节点为当前树形控件根节点,递归执行步骤2.6-步骤2.10;
步骤2.11
则以childListNode.varName为名字,在当前树形控件根节点上添加一个子节点,并以此子节点为根节点,添加一层子节点,其个数为childListNode.varNum,并以每个子节点为当前树形控件根节点,递归执行步骤2.6-步骤2.11;
步骤2.12
跳回步骤2.1执行,直到变量声明文件全部解析完毕;
以上步骤均执行完毕,便在软件界面上根据结构体变量列表得到一个完整的树形结构,随意点击ICD变量树上的节点,可通过界面显示节点上的对应变量信息,显示方法如步骤2.13-步骤2.14:
步骤2.13
判断若选中的节点对应的数据类型,若为词典中存在的结构体类型,则使用词典的信息对变量信息显示框赋值,否则执行下一步骤;
步骤2.14
若选中的节点对应的数据类型为简单数据类型,则获得其父节点NodeA的类型名A,在词典里查询,若仍未查到,将NodeA的父节点NodeB(其名字记为b)对应的类型名B,加上NodeA的名字a进行查找,即在词典中查找“B.a”,若仍未查到,将NodeB的父节点对应的类型名C,加上其它子节点的名字进行查找,即在词典中查找“C.b.a”,如此逐层上溯,直到在词典中查到选中节点的父节点的完整类型名,得到选中节点的父节点对应的类型structNode;在structNode的子变量列表中找到选中节点的名字后,对变量信息显示框赋值。
4.根据权利要求1所述的一种基于接口控制文件的软件测试用例辅助设计方法,其特征在于:
所述步骤3的详细步骤如下:
设界面上有一个树形列表控件TestCaseList,可从步骤2的IcdTreeList中选择根数据块;则测试用例编辑界面可设计为,选择并拷贝根数据块到TestCaseList后,待编辑的数据块每行都显示有初始值、变化步长;树形列表控件的数据显示格式示例见表2,其中变量名字列具有树形层级嵌套的结构,每个变量名字节点对应一组初始值、步长、最小值、最大值;只有变量名字叶节点的值才能编辑,非叶节点的值编辑后无效;
表2 树形列表的数据显示格式示例
一个树形列表的数据对应一个测试用例,用户在编辑其上的数据后选择发送测试用例,软件即可将当前编辑界面的数据块组织为字节流,通过TCP socket接口发送给经过插桩修改了数据接收方式、同样运行在PC机上的被测软件,向使用VC++编译运行的被测软件发送数据时,组织字节流的规则如下:
步骤3.1
对树形列表控件的各个数据块,分别执行以下步骤;
步骤3.2
对数据块的根节点,若其有子节点,则对每个子节点,递归执行步骤3.3-步骤3.8;若其没有子节点,说明其数据类型为简单数据类型,直接执行步骤3.8;
步骤3.3
使用步骤2.13-步骤2.14的处理方式,获取当前叶子节点的类型信息,若当前叶子节点是结构体位域元素,则执行步骤3.4-步骤3.7,否则执行步骤3.8;
步骤3.4
判断该叶子节点是否有上一个同父叶子节点,且上一个同父叶子节点也是按位域元素处理的,且这两个叶子节点的数据类型相同,且当前已拼接的位数加上当前叶子节点的位域位数小于这两个叶子节点的数据类型对应的字节数*8,(若条件不成立则转到步骤3.7)则将计算当前叶子节点的值加上步长*已过去的程序运行周期,将得到的值按已经拼接的位数左移,再加上已拼接的值;将已拼接的位数加上此叶子节点的位域位数;
步骤3.5
查看步骤3.4的叶子节点是否有下一个同父叶子节点,若有且下一个叶子节点不是位域元素,或下一个叶子节点的数据类型和当前节点不一致,则执行步骤3.6;
步骤3.6
若当前拼接的位数恰好等于当前节点的数据类型对应的字节数*8,或当前叶子节点没有下一个叶子节点,或步骤3.5的情况成立,则将当前拼接的值转化为字节流,输出到待发送字节流中,结束本次递归;
步骤3.7
若步骤3.4的条件不成立,则若当前叶子节点有下一个同父叶子节点,且下一个叶子节点也是位域元素、数据类型和当前叶子节点相同、数据类型对应的字节数*8大于这两者的位域位数之和,则将此节点按位域元素处理,预备和下一个叶子节点拼接,否则执行步骤3.8;
步骤3.8
若步骤3.4和步骤3.7的条件不成立,直接将当前叶子节点按照其数据类型的字节数转换为字节流,输出到待发送字节流中。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201811487116.7A CN109614329B (zh) | 2018-12-06 | 2018-12-06 | 一种基于接口控制文件的软件测试用例辅助设计方法 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201811487116.7A CN109614329B (zh) | 2018-12-06 | 2018-12-06 | 一种基于接口控制文件的软件测试用例辅助设计方法 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN109614329A true CN109614329A (zh) | 2019-04-12 |
CN109614329B CN109614329B (zh) | 2021-11-02 |
Family
ID=66006543
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN201811487116.7A Active CN109614329B (zh) | 2018-12-06 | 2018-12-06 | 一种基于接口控制文件的软件测试用例辅助设计方法 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN109614329B (zh) |
Cited By (5)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN110162480A (zh) * | 2019-05-31 | 2019-08-23 | 苏州简约纳电子有限公司 | 一种结构化诊断对象的自动化解析方法 |
CN111752840A (zh) * | 2020-06-28 | 2020-10-09 | 中电长城(长沙)信息技术有限公司 | 一种跨系统的金融自助设备sp自动测试方法、设备及介质 |
CN113157256A (zh) * | 2021-03-25 | 2021-07-23 | 北京达佳互联信息技术有限公司 | 接口代码的生成方法、装置、电子设备、存储介质及产品 |
CN113505054A (zh) * | 2021-04-08 | 2021-10-15 | 中国航空无线电电子研究所 | 一种无人机控制站的网络数据静态测试系统和测试方法 |
CN116275587A (zh) * | 2023-04-17 | 2023-06-23 | 霖鼎光学(江苏)有限公司 | 一种激光切割工件的控制系统 |
Citations (11)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN1776643A (zh) * | 2004-11-15 | 2006-05-24 | 华为技术有限公司 | 一种软件产品健壮性的测试方法及装置 |
CN101237662A (zh) * | 2008-02-29 | 2008-08-06 | 深圳华为通信技术有限公司 | 生成手机自动化测试用例的方法及装置 |
CN101996132A (zh) * | 2009-08-14 | 2011-03-30 | 中兴通讯股份有限公司 | 公用对象请求代理程序体系结构接口自动测试方法和装置 |
CN102096631A (zh) * | 2009-12-11 | 2011-06-15 | 华为技术有限公司 | 接口测试方法及装置 |
KR20120121950A (ko) * | 2011-04-28 | 2012-11-07 | (주)아이엔에스랩 | 애플리케이션 그래픽 유저인터페이스 테스트 자동화 시스템 및 그 방법 |
CN103176896A (zh) * | 2011-12-23 | 2013-06-26 | 阿里巴巴集团控股有限公司 | 一种测试用例的生成方法及装置 |
CN104268072A (zh) * | 2014-09-03 | 2015-01-07 | 武汉烽火网络有限责任公司 | 图形化脚本编辑器及快速开发通信设备测试脚本的方法 |
CN104516818A (zh) * | 2014-12-29 | 2015-04-15 | 北京四方继保自动化股份有限公司 | 一种适用于逻辑组态软件中编译器的自动化测试系统及其方法 |
CN105718617A (zh) * | 2014-12-05 | 2016-06-29 | 中国航空工业集团公司航空动力控制系统研究所 | 用于Matlab自动测试的Bus结构体反向自动建模方法 |
CN105930268A (zh) * | 2016-04-19 | 2016-09-07 | 努比亚技术有限公司 | 一种基于树型的黑盒测试用例生成方法及其系统 |
CN107870863A (zh) * | 2017-11-28 | 2018-04-03 | 中国电子科技集团公司第五十四研究所 | 一种基于xml的分布式自动化测试方法 |
-
2018
- 2018-12-06 CN CN201811487116.7A patent/CN109614329B/zh active Active
Patent Citations (11)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN1776643A (zh) * | 2004-11-15 | 2006-05-24 | 华为技术有限公司 | 一种软件产品健壮性的测试方法及装置 |
CN101237662A (zh) * | 2008-02-29 | 2008-08-06 | 深圳华为通信技术有限公司 | 生成手机自动化测试用例的方法及装置 |
CN101996132A (zh) * | 2009-08-14 | 2011-03-30 | 中兴通讯股份有限公司 | 公用对象请求代理程序体系结构接口自动测试方法和装置 |
CN102096631A (zh) * | 2009-12-11 | 2011-06-15 | 华为技术有限公司 | 接口测试方法及装置 |
KR20120121950A (ko) * | 2011-04-28 | 2012-11-07 | (주)아이엔에스랩 | 애플리케이션 그래픽 유저인터페이스 테스트 자동화 시스템 및 그 방법 |
CN103176896A (zh) * | 2011-12-23 | 2013-06-26 | 阿里巴巴集团控股有限公司 | 一种测试用例的生成方法及装置 |
CN104268072A (zh) * | 2014-09-03 | 2015-01-07 | 武汉烽火网络有限责任公司 | 图形化脚本编辑器及快速开发通信设备测试脚本的方法 |
CN105718617A (zh) * | 2014-12-05 | 2016-06-29 | 中国航空工业集团公司航空动力控制系统研究所 | 用于Matlab自动测试的Bus结构体反向自动建模方法 |
CN104516818A (zh) * | 2014-12-29 | 2015-04-15 | 北京四方继保自动化股份有限公司 | 一种适用于逻辑组态软件中编译器的自动化测试系统及其方法 |
CN105930268A (zh) * | 2016-04-19 | 2016-09-07 | 努比亚技术有限公司 | 一种基于树型的黑盒测试用例生成方法及其系统 |
CN107870863A (zh) * | 2017-11-28 | 2018-04-03 | 中国电子科技集团公司第五十四研究所 | 一种基于xml的分布式自动化测试方法 |
Non-Patent Citations (3)
Title |
---|
任志伟: "嵌入式软件测试技术研究", 《软件导刊 软件理论与方法》 * |
李飞宇: "基于内存建模的测试数据自动生成方法研究", 《中国博士学位论文全文数据库 信息科技辑》 * |
皮基庆: "一种C语言静态代码检测工具的研究与实现", 《中国优秀博硕士学位论文全文数据库(硕士)信息科技辑》 * |
Cited By (10)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN110162480A (zh) * | 2019-05-31 | 2019-08-23 | 苏州简约纳电子有限公司 | 一种结构化诊断对象的自动化解析方法 |
CN110162480B (zh) * | 2019-05-31 | 2023-02-24 | 泛升云微电子(苏州)有限公司 | 一种结构化诊断对象的自动化解析方法 |
CN111752840A (zh) * | 2020-06-28 | 2020-10-09 | 中电长城(长沙)信息技术有限公司 | 一种跨系统的金融自助设备sp自动测试方法、设备及介质 |
CN111752840B (zh) * | 2020-06-28 | 2023-08-08 | 中电长城(长沙)信息技术有限公司 | 一种跨系统的金融自助设备sp自动测试方法、设备及介质 |
CN113157256A (zh) * | 2021-03-25 | 2021-07-23 | 北京达佳互联信息技术有限公司 | 接口代码的生成方法、装置、电子设备、存储介质及产品 |
CN113157256B (zh) * | 2021-03-25 | 2024-03-19 | 北京达佳互联信息技术有限公司 | 接口代码的生成方法、装置、电子设备、存储介质及产品 |
CN113505054A (zh) * | 2021-04-08 | 2021-10-15 | 中国航空无线电电子研究所 | 一种无人机控制站的网络数据静态测试系统和测试方法 |
CN113505054B (zh) * | 2021-04-08 | 2023-12-12 | 中国航空无线电电子研究所 | 一种无人机控制站的网络数据静态测试系统和测试方法 |
CN116275587A (zh) * | 2023-04-17 | 2023-06-23 | 霖鼎光学(江苏)有限公司 | 一种激光切割工件的控制系统 |
CN116275587B (zh) * | 2023-04-17 | 2023-10-27 | 霖鼎光学(江苏)有限公司 | 一种激光切割工件的控制系统 |
Also Published As
Publication number | Publication date |
---|---|
CN109614329B (zh) | 2021-11-02 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN109614329A (zh) | 一种基于接口控制文件的软件测试用例辅助设计方法 | |
Purdom | A sentence generator for testing parsers | |
US7320007B1 (en) | Dynamic generation of target files from template files and tracking of the processing of target files | |
US20160275058A1 (en) | Method and system of text synthesis based on extracted information in the form of an rdf graph making use of templates | |
CN101401075A (zh) | 程序调测系统中的映射方法和程序调测系统 | |
US7617085B2 (en) | Program product supporting specification of signals for simulation result viewing | |
US20130152061A1 (en) | Full fidelity parse tree for programming language processing | |
CN116450616A (zh) | 一种基于解析树的通用异构关系型数据库sql迁移方法 | |
Heering et al. | Incremental generation of lexical scanners | |
CN114528846A (zh) | 一种用于人工智能的概念网络及其生成方法 | |
US6889219B2 (en) | Method of tuning a decision network and a decision tree model | |
CN108491227A (zh) | 一种基于lua和redis的安全配置系统及方法 | |
Pereira et al. | An IOPT-net state-space generator tool | |
KR100345277B1 (ko) | Xml 문서의 논리적인 구조정보 추출기 | |
CN111381826A (zh) | 生成代码文件的语法树的方法、装置及电子设备 | |
Mokhov | Introducing MARF: a modular audio recognition framework and its applications for scientific and software engineering research | |
US20040205707A1 (en) | Logical separation of code and content | |
CN114528218A (zh) | 测试程序的生成方法、装置、存储介质以及电子设备 | |
JPH11272503A (ja) | プログラムのテストデータ自動生成装置 | |
CN113282495A (zh) | 一种基于轨迹监控的Java软件故障定位方法 | |
CN111381827A (zh) | 生成代码文件的语法树的方法、装置及电子设备 | |
CN104699916B (zh) | 一种通用的多样本想定生成方法及系统 | |
Emdi | The Implementation of a Network Codasyl-DML Interface for the Multi-Lingual database System | |
CN116975257A (zh) | 一种基于句法结构删减的自动文摘事实性增强方法 | |
CN117667089A (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 |