关键词:
软件测试
符号执行
静态分析
程序约束
预言数据
摘要:
软件测试是提高软件可靠性的重要手段。在软件测试方法中,覆盖测试是一种基本的白盒测试方法,为满足测试充分性,覆盖测试需要测试数据能取得尽可能高的覆盖率。与其他测试数据自动生成方法相比,基于约束的测试数据生成方法更具确定性且易实现对特定目标的覆盖,其生成的测试数据在覆盖测试中更具优势。然而,取得上述优势的前提是可实现对目标程序的精确约束建模。约束建模的精度不足会导致输入变量产生欠约束问题,进而对生成测试数据的正确性、友好性等产生影响,使测试数据无法实现预期覆盖或难以被测试人员理解和使用。本文以解决程序约束建模过程中的欠约束问题及其衍生问题为目标,对如何提取程序中的隐性约束、如何改善测试数据的友好性以及如何缓解不友好测试数据产生的不利影响三个方面展开研究。本文的主要工作和创新点如下:1)单元覆盖测试中的隐性约束提取方法研究在单元覆盖测试中,当诸如除、解引用等危险操作作用于输入变量时,为保证函数单元的正常执行,输入变量要满足一定的前置条件,这些前置条件未显式的存在于函数中,是对输入变量的隐性约束,无法通过传统符号执行方法获得。不满足隐性约束的测试数据在执行时会发生错误或崩溃,无法实现预期覆盖。本文提出了一种规则导向符号执行方法用于隐性约束的提取。该方法的核心思想是:使用预定义规则对传统符号执行进行增强,解决无法提取隐性约束所导致的欠约束问题。首先,对C语言中运算符的语义进行了系统的分析,预定义了四类隐性约束提取规则并应用于符号执行过程中,预定义规则提供了一种层次化的匹配模型用于准确的识别并提取语句中的隐性约束。其次,根据隐性约束的分布特点,对约束建模对象进行了扩展,除常规的分支语句外,还对可能存在隐性约束的赋值语句、声明语句进行了分析建模。最后,提出了完整路径约束的概念,将隐性约束与已有路径约束合取构成完整路径约束,通过求解完整路径约束可以获得可正常执行的测试数据,从而实现覆盖,提高测试的充分度。实验结果表明,所提方法可以准确的提取隐性约束;与同类工具相比,所提方法可以有效的提高存在隐性约束程序的覆盖率。2)友好测试数据生成方法研究针对欠约束变量在约束求解过程中由于约束不足可能生成不友好测试数据这一问题。本文提出了一种挖掘常量信息用于欠约束变量的约束补全和引导友好测试数据生成的方法。该方法首先搜集与输入变量相关联的相关常量和存在欠约束问题的输入变量。然后,提出了聚合分析和排序分析方法用于处理搜集到的相关常量,聚合分析通过对相关常量集进行数据清洗和集中来获得约束补全信息;排序分析基于关联操作的语义实现对相关常量的启发性强弱的推理,并选取强启发相关常量作为种子数据。最后,提出了约束补全方法,使用约束补全信息对欠约束变量进行约束补全;提出了启发式测试数据生成算法,利用种子数据引导友好测试数据生成;通过为欠约束变量生成完整约束和引入种子数据实现对测试数据友好性的改善。对一个开源实际工程进行了实验,实验结果表明,与不使用本方法的工具相比,所提方法可以改善测试数据的友好性并具有良好的效率。3)基于静态分析的预言数据选取方法研究当无法改善测试数据友好性或改善效果不佳时,不友好测试数据由于难以理解、计算为测试人员进行测试预言构建、快速发现故障带来诸多困难。本文提出了一种路径敏感的预言数据选取方法,该方法通过为测试人员选取多个预言数据进行观测将测试预言问题划分为若干子预言问题,缓解了不友好测试数据为测试预言构建带来的困难;此外,选取多个预言数据进行观测还获得了更多捕获错误状态的机会,减少了漏报。该方法首先引入了关键路径分析方法,对程序路径进行基于故障观测能力的排序,为测试人员指引了测试预言构建的顺序。然后,提出了定量分析方法和定性分析方法用于为每条路径选取预言数据。定量分析根据候选预言数据间的替换关系缩减预言数据集的规模,以减少测试预言构建的工作量。定性分析根据预言数据的故障观测能力对预言数据进行排序,以帮助测试人员更快的发现程序中的故障。实验结果表明,所提方法可以发现仅观测默认输出测试预言方法无法发现的故障,且具有较好的故障观测效率,能帮助测试人员更快的发现故障。