Page 11 - 《软件学报》2020年第12期
P. 11
成浩亮 等:一种手绘制导的移动应用界面测试方法 3677
4: t v ←t v [p t L.W(p t )] //将坐标点转化为对应的控件
5: end while
6: G.V←G.V∪{t v }
7: V(s)←t v //缓存,以便从动作步 s 找到图中的对应节点
8: end while
9: while (s 1 ;s 2 )∈subSequence(L.l) do
10: G.E←G.E∪{(V(s 1 ),V(s 2 ))}
11: end while
12: while (et:etset)∈subSequence(L.l)∧et′∈etset do
13: s 1 ←lastStep(et) //找出动作序列 et 中的最后一个逻辑动作步
14: s 2 ←firstStep(et′) //找出动作序列 et′中的第 1 个逻辑动作步
15: G.E←G.E∪{(V(s 1 ),V(s 2 ))} //将这两个逻辑动作步连接形成的边加入到边集中
16: end while
17: while et∈eventTrace(L.l) do
18: s←firstStep(et)
19: G.V 0 ←G.V 0 ∪{V(s)} //初始动作步对应节点加入到抽象事件流图的起始节点集 G.V 0
20: end while
21: G.O←oracleExtract(L,V) //提取 L 中的测试目标
22: return G
算法 1 由布局文件 L 中记录的信息构建抽象事件流图 G,其中,第 1 行~第 8 行构造抽象事件流图的节点集
G.V.第 1 行的 logicStep 函数依次从图形序列中获得逻辑动作步 s,并由函数 vertexGenerate 生成抽象事件流图
的节点 t v .在第 3 行~第 5 行将节点中记录的坐标转为控件信息后,由第 6 行加入节点集 G.V.第 7 行临时记录了
映射 V,它将逻辑动作步 s 映射到对应的节点上.第 9 行~第 16 行进一步构造抽象事件流图的边集 G.E.函数
subSequence(⋅)的作用是将‘,’相连的动作序列集映射为单个的动作序列.第 9 行~第 11 行将 l 中绘制的动作步衔
接(即由‘;’相连的动作步)加入到抽象事件流图的边集 G.E 中,第 12 行~第 16 行进一步将 l 中绘制的动作步分叉
(即由‘:’相连的动作序列和动作序列集)加入到抽象事件流图的边集 G.E 中.第 17 行~第 20 行进一步将 l 中每一
个初始动作步的对应节点加入到抽象事件流图的起始节点集 G.V 0 .最终在第 21 行由 oracleExtract 函数来构造
抽象事件流图 G 中的测试目标映射 G.O.
算法 2 描述了 oracleExtract 函数的内部细节,该函数将布局文件记录的测试目标 L.O e 解析并提取出来,找
到其中每一个判定条件在模型 G 中的对应路径,并将其对应关系写入到 G.O 中.
该算法通过第 1 行~第 17 行的大循环,每次处理布局文件 L.l 中按测试语言语法定义的一条事件序列 et,将
该序列在模型 G 中所有对应路径形成的路径集 P 找到(第 2 行~第 14 行),并在第 15 行将 L.O e 中关于 et 的判定
条件写入到 O 中对应的每一条路径上.
算法 2. oracleExtract 函数:测试目标提取算法.
输入:L〈l,W,O e 〉,V;
输出:O //测试目标.
1: while et∈eventTrace(L.l) do
2: p←V(firstStep(et))
3: P←P∪{p} //路径 p 的起始节点加入到集合 P 中
4: while p∈P do
5: if (s 1 ;s 2 )∈subSequence(et)∧V(s 1 )==lastVertex(p) then
6: p←addVertex(p,V(s 2 )) //将 s 2 对应节点追加到路径 p 的末尾