提升EvoSuite测试效果与优化安卓应用响应性的研究
1. EvoSuite在测试中面临的问题
EvoSuite在测试过程中遇到了多种问题,这些问题影响了其测试覆盖率和效果。下面将详细介绍这些问题及其具体表现。
1.1 内部类方法调用问题(O - ICM)
在某些情况下,EvoSuite无法生成使用内部类方法的调用序列。例如在
LinkedListMultimap
(GUAVA - 102)中,私有方法
removeNode
只能通过内部类
NodeIterator
的
remove
API调用,但EvoSuite虽然构造了
NodeIterator
实例,却未对其进行进一步的方法调用,导致
removeNode
方法未被覆盖。以下是相关代码示例:
// To cover: use NodeIterator’s remove API
public class LinkedListMultimap <K, V> {
private void removeNode(Node <K, V> node) {
if (node.previous != null) { /* not covered */ } ...
}
...
// NodeIterator is an inner class of LinkedListMultimap
private class NodeIterator {
public void remove () { ...
removeNode(current );
...
}
}
...
}
1.2 大搜索空间问题
大搜索空间问题包含多个子类别,具体如下:
-
不全面的方法测试(L - IMT)
:EvoSuite可能无法为某些方法生成调用序列。例如,
SparseImmutableTable
(GUAVA - 129)中的
createSerializedForm
方法虽为公共且无参数,但EvoSuite未生成其调用序列。在缓存模式中也存在此类问题,如
GUAVA - 212
中的
toString
方法,EvoSuite很少对其进行重复调用,导致
else
分支未被覆盖。代码示例如下:
// To cover: invoke toString () twice.
public String toString () {
String result = toString;
if (result == null) {
result = computeToString ();
toString = result;
} // The else branch was not covered
return result;
}
-
可迭代/流中的特定值问题(L - ISV)
:该类别要求特定的输入字节序列来满足分支条件。例如,
JPXFilter(PDFBOX - 220)的decode方法需要有效的JPEG2000格式的InputStream作为参数,EvoSuite未能提供有效输入,导致readJPX方法中的其他七个分支未被触及;PositionBuilder(SPOON - 105)的getEndOfComment方法需要一个char[]缓冲区作为参数,EvoSuite未能生成有效的测试用例来覆盖该方法内的相等性检查分支。 -
键值存储模式问题(L - KVS)
:此类别与分支条件中使用键值数据结构(如
Map)有关,增加了复杂度,因为需要在键、值和键值对组合三个维度上进行正确猜测。以Predictor(PDFBOX - 117)为例,分支条件predictor > 1未被覆盖,因为decodeParams中没有键为COSName.PREDICTOR的条目。代码示例如下:
// To cover: pass decodeParams argument containing entry
// { key = COSName.PREDICTOR , value = COSNumber > 1 }
static OutputStream wrapPredictor ( OutputStream out, COSDictionary decodeParams ) {
int predictor = decodeParams .getInt(COSName .PREDICTOR );
if (predictor > 1) { /* not covered */ }
else { return out; }
}
-
参数中的对象状态问题(L - OSA)
:该类别需要进一步改变作为方法参数传递的对象的状态。例如,
ImportScannerImpl(SPOON - 169)的visitCtClass方法中,由于getTypeMembers返回空可迭代对象,导致循环体未被覆盖,需要在调用visitCtClass方法之前调用ctClass.setTypeMembers()方法,但EvoSuite未进行此类调用;TreeMultiset(GUAVA - 39)的setCount方法中,newCount > 0的分支未被覆盖,因为EvoSuite未传递大于0的整数值作为参数。 -
调用对象中的对象状态问题(L - OSI)
:此类别需要进一步改变被测类(CUT)对象的状态以覆盖未覆盖的分支。例如,
ImportScannerImpl(SPOON - 169)的addClassImport方法中有三个if语句,条件检查targetType是否不为空,但EvoSuite未将targetType赋值为非空值,需要在调用addClassImport方法之前调用computeImports方法;LinkedListMultimap(GUAVA - 102)的isEmpty方法中,EvoSuite仅使用空列表进行测试,导致head != null的分支未被覆盖。
1.3 其他问题
-
文件系统访问问题(FSA)
:EvoSuite虽提供了虚拟文件系统(VFS)处理文件访问,但在某些情况下仍不足。例如,
FileSystemFontProvider(PDFBOX - 8)在构造时扫描文件系统中的字体文件,测试未找到字体文件,导致相关循环和分支未被覆盖;MavenLauncher(SPOON - 32)需要读取有效的Maven的pom.xml文件,若文件不存在,测试将无法覆盖某些分支。 -
JVM的
System.getProperty调用问题(JSC) :EvoSuite没有提供更新JVM通过System.setProperty存储的值的机制。例如,FileSystemFontProvider(PDFBOX - 8)中查询"pdfbox.fontcache"和"user.home"属性,由于EvoSuite未更新这些值,导致相关分支未被覆盖。 -
分支不可达问题(UBR)
:该类别涵盖了任何执行路径都无法覆盖的分支。例如,
CtLocalVariable - ReferenceImpl(SPOON - 20)的getDeclaration方法中,getFactory方法永远不会返回null,导致if (factory == null)分支未被覆盖。
2. 各主题的主要问题分布
不同主题有各自的主要问题,具体分布如下表所示:
| 主题 | 主要问题 | 受影响类的数量 |
| ---- | ---- | ---- |
| PDFBOX | 键值存储模式(L - KVS) | 10/20 |
| FESCAR | 构造失败(C - CF) | - |
| GUAVA | - | - |
| SPOON | - | - |
从图中可以看出,EvoSuite在不同主题上没有共同的主要问题,但每个主题都有其突出的问题。例如,键值存储模式问题主要影响
PDFBOX
,而构造失败问题主要影响
FESCAR
。
graph LR
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
A[EvoSuite测试问题]:::process --> B[内部类方法调用问题]:::process
A --> C[大搜索空间问题]:::process
A --> D[其他问题]:::process
C --> C1[不全面的方法测试]:::process
C --> C2[可迭代/流中的特定值问题]:::process
C --> C3[键值存储模式问题]:::process
C --> C4[参数中的对象状态问题]:::process
C --> C5[调用对象中的对象状态问题]:::process
D --> D1[文件系统访问问题]:::process
D --> D2[JVM的System.getProperty调用问题]:::process
D --> D3[分支不可达问题]:::process
综上所述,EvoSuite在测试过程中面临多种问题,这些问题影响了测试的覆盖率和效果。了解这些问题有助于研究人员和从业者更清晰地解决相关问题,提高EvoSuite的有效性。
3. 利用遗传改进优化安卓应用响应性
3.1 安卓应用响应性的重要性
响应性是安卓应用用户最为看重的质量之一。相关研究表明,59%的用户会给无响应的应用差评,无响应也是用户留下负面评价和放弃应用的常见原因之一。然而,目前关于安卓应用响应性自动化改进的研究相对较少,大多数方法侧重于问题检测,而非自动化改进。常见的改进技术如卸载和重构,存在一定局限性,因此搜索式方法可能是探索代码改进的有效途径。
3.2 遗传改进(GI)的应用
为了提高安卓应用的响应性,我们探索了遗传改进(GI)的应用。具体步骤如下:
1.
扩展GI框架
:对开源的GI框架Gin进行扩展,使其能够处理安卓应用。
2.
选择应用并测量指标
:选取四个开源安卓应用,将帧率作为响应性的代理指标进行测量。
3.
应用GI进行改进
:对这些应用的代码进行遗传改进操作。
在应用过程中,发现虽然在UI实现代码方面有一定的改进空间(最高可达43%),但应用的测试套件往往不够强大,导致生成了许多无效补丁。以下是具体的分析:
- UI实现代码改进 :在部分UI实现代码中,通过GI技术实现了帧率的提升,但由于测试套件无法充分验证代码修改的正确性,产生了大量无效补丁。
- 高覆盖率代码区域改进 :对测试套件覆盖率较高的代码区域应用GI,未找到能持续降低帧率的补丁。
这表明,尽管GI在提高安卓应用响应性方面具有潜力,但基于测试的技术目前受到UI元素测试套件可用性的限制。
3.3 具体代码示例及分析
虽然文档中未给出具体的代码示例,但可以推测在应用GI时,可能会涉及到对代码的修改和优化。例如,可能会对UI绘制代码进行调整,以提高帧率。以下是一个简单的伪代码示例,展示可能的优化思路:
// 原始代码
public void drawUI() {
// 复杂的绘制逻辑
for (int i = 0; i < elements.size(); i++) {
drawElement(elements.get(i));
}
}
// 优化后的代码
public void drawUI() {
// 减少不必要的计算
int size = elements.size();
for (int i = 0; i < size; i++) {
drawElement(elements.get(i));
}
}
在这个示例中,通过提前计算
elements
的大小,减少了每次循环中的计算量,可能会提高帧率。
4. 总结与展望
通过对EvoSuite测试问题和安卓应用响应性优化的研究,可以总结出以下要点:
| 研究内容 | 主要发现 |
|---|---|
| EvoSuite测试 | 存在内部类方法调用、大搜索空间、文件系统访问等多种问题,不同主题有各自的主要问题 |
| 安卓应用响应性优化 | GI有提高响应性的潜力,但受限于测试套件对UI元素的覆盖 |
graph LR
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
A[研究内容]:::process --> B[EvoSuite测试]:::process
A --> C[安卓应用响应性优化]:::process
B --> B1[多种测试问题]:::process
B --> B2[各主题主要问题不同]:::process
C --> C1[GI有潜力]:::process
C --> C2[受测试套件限制]:::process
未来,可以针对这些问题进行进一步的研究和改进。对于EvoSuite,可以探索更有效的搜索策略和测试用例生成方法,以解决大搜索空间和对象状态等问题。对于安卓应用响应性优化,可以加强测试套件的建设,提高其对UI元素的覆盖,从而更好地应用GI技术进行优化。同时,可以尝试将GI与其他优化技术相结合,以获得更好的效果。
超级会员免费看
58

被折叠的 条评论
为什么被折叠?



