《Parasoft-Jtest(2)分析》由会员分享,可在线阅读,更多相关《Parasoft-Jtest(2)分析(43页珍藏版)》请在金锄头文库上搜索。
1、高效单元测试补充 Parasoft Jtest(2) 林若钦林若钦第四部分第四部分 Junit Junit扩展扩展高效单元测试本章内容:qBugDetective 进行静态代码分析qJtest动态测试动态测试q桩函数高效单元测试1、BugDetective 进行静态代码分析 简介(1)n软件缺陷主要分为以下三种:n需求实现不正确 因为需求未被正确地实现,导致软件未如预期那样工作。n需求缺失或不完整 由于客户/开发者未预见到某些功能的必要性并且未给出相应需求或者由于开发者没有成功实现相应的需求,造成软件不能完成某些必要的操作或者处理某些特定情景。n用户误操作 软件设计时未考虑用户误操作的影响,从
2、而导致软件形成不可预知的路径。高效单元测试1、BugDetective 进行静态代码分析 简介(2)n建立一个强健的回归测试套件(robust regression suite)是检测需求实现正确性最有效的方法,而负面测试(negative testing)则是防止误操作的最佳方法。尽管如此,查找需求缺失还是一项很棘手的工作,因为开发者并不知道所查找的是什么。数据流分析是目前唯一已知能帮助开发者解决这些问题的自动化测试技术,它允许开发者在不运行程序的前提下分析代码中的路径。例如,假设数据流分析在Java程序中查找到一处空指针异常。通过检查造成该异常的路径,并且推敲造成该潜在程序终止的条件,开发
3、者也许能找到缺失的需求 诸如设计计划阶段未预见到的情况等。如果开发者只注重于编写验证需求的测试用例,这些问题是不可能被发现的。高效单元测试1、BugDetective 进行静态代码分析 简介(3)n除了需求缺失,数据流分析还能发现代码结构上存在的问题以及应用程序中的逻辑错误。类似于模式匹配静态分析、单元测试、http单元测试、容器测试(in-container tests)、模块测试、API测试以及其它所有用来验证软件的测试一样,数据流分析也应该被用作回归测试套件的一个部分。这样,自动日常地运行包括数据流分析和所有其它测试在内的完整回归测试套件就能确定用户的代码修改添加是否引入了新问题、破坏了
4、既有功能或者造成其它未预见到的副作用。高效单元测试1.、静态代码流分析- 背景n静态代码分析这个术语对软件业的不同人有着不同的含义。在业界主要有以下两种静态代码分析方法:n(1)执行程序或者基于数据流的分析;n(2)基于模式(pattern-based)的分析。n对于需要执行程序的这种方法,静态代码分析意味着从逻辑上执行程序,有时甚至仅仅是符号化地执行程序来查找诸如内存崩溃、泄漏以及异常等问题。这种测试的主要优点在于不需要测试用例就可以查找代码中的问题。当开发者正在编写某些代码时,这时他们对代码的细节是了如指掌的,这也是预防代码缺陷以及安全性漏洞的最佳时机,这种执行程序的分析方法能为开发者提供
5、在桌面环境下迅速查找软件缺陷以及安全性漏洞所必需的“及时反馈”。高效单元测试1.、Parasoft的静态代码分析以及BugDetective技术nParasoft的静态代码分析技术支持基于数据流以及基于模式的这两种静态代码分析方法。Parasoft的这种基于数据流的静态代码分析技术被称为BugDetective,它能方便地为用户检测出跨越多个方法、类或者包的运行时问题以及程序不稳定性因素(诸如空指针异常、SQL以及其它注入、资源泄漏以及Java中的无效迭代等);n使用Parasoft BugDetective,开发者能在早期发现、诊断并且修复基于模式的静态代码分析和/或单元测试所不能检测到的软
6、件错误。在早期发现这些缺陷能节省软件开发过程中花在诊断以及可能的重复工作上的大量时间。n在Parasoft Jtest中,BugDetective包含以下两个用途:n1. 用作Jtest静态代码分析工具以检测代码中包含的上述缺陷。n2. 用以与Jtest单元测试引擎协同使用以验证单元测试中所报告的异常在实际运行时 是否会被触发。高效单元测试1.、BugDetective的优点(1)n利用现有资源完成更全面的测试:利用现有资源完成更全面的测试:nBugDetective很好的补充了其它的测试技术,它允许用户在没有测试用例的情况下发现代码中的问题,从而免去了用户开发、执行以及维护复杂的测试用例的麻
7、烦。通过检测程序中的潜在分支,BugDetective为用户提供了一个传统测试方法难以完成的路径覆盖率(path coverage)分析。因此,BugDetective通常能够检查出测试未覆盖到的程序在处理一些罕见情况下出现的问题。此外,如果对代码进行了修改,用户可以直接搜寻其中的缺陷而不必更新或重新生成测试用例。n自动查找跨越多个类的缺陷:自动查找跨越多个类的缺陷:n传统的自动化单元测试工具只能帮助用户查找包含在同一个类中的缺陷。这一差异很关键。大多数对类进行了深入测试的开发者都是先修改有明显问题的代码,然后还是遇到了诸如空指针异常一类错误,并且这样的错误一般都需要数天的时间才能被诊断出来,
8、因为其原因往往是由隐蔽或复杂且又跨越多个函数甚至是多个封装的执行路径造成的。使用BugDetective能够在瞬间发现这些问题。高效单元测试1.、BugDetective的优点(2)n注重于实际运行中会出现的缺陷及误操作:注重于实际运行中会出现的缺陷及误操作:nBugDetective能自动准确地发现与数据或数据流相关的缺陷。在大多数情况下,BugDetective所报告的冲突都是在实际中的误操作(而不是单元测试所查找到的可能或假设的误操作)。例如,除非下述代码中的strlen函数被程序调用并且被赋予一个空值,否则BugDetective不会报告任何冲突,而单元测试则不管向strlen赋空值与
9、否都会报告代码有问题:public int strlen (string str)Return str.length();高效单元测试1.5、与BugDetective协同工作nBugDetective这种独特静态分析技术能判断应用程序的执行路径是否与用作规则的“可疑行为”的特征相符。每发现一处缺陷,BugDetective都详细列举出造成该缺陷的完整执行路径,并以缺陷自我暴露处的代码为终结。为了缩短诊断及修复缺陷的时间并降低其难度,BugDetective对数据流路径的细节加入了扩充标注(如针对空指针异常冲突的描述就包括了在任一时刻执行路径中包含空值的变量)。高效单元测试1.、Bugdete
10、ctive 静态数据流分析的具体操作流程n1)打开随书附带的例程com.embest.eclipse.jtest.demo,展开这个工程,找到com.embest.eclipse.jtest.demo.bugdetectiveAndParameteredTest包下的“NullPointer.java”文件。n2)在菜单栏中依次选择菜单 “Jtest”-“Test Using”-“Builtin”-“ BugDetective (License Required)”,如下图示。高效单元测试高效单元测试开始Bugdetective自动化检测,如图所示。高效单元测试3)检测完成后,在这个对话框中可
11、以查看相关信息:高效单元测试4)在菜单栏中依次选择菜单项“Jtest”-“Show View”-“Tasks”,在Jtest视图中依次展开节点,可以查看比较详细的Error信息,如图示:高效单元测试结果分析n通过上图可以清楚看到有两个比较重要的点: n冲突源点(冲突源点(Violation origin): 这是冲突的“根源”。通常,这是“错误数据”的发源地。例如,在空指针异常规则中,其冲突源点也就是空值的源头,本例子中的第19行和第20行。n 冲突节点(冲突节点(Violation point):): 这是对“错误数据”的使用导致在程序中产生缺陷的节点。在空指针异常这个例子当中,该点既是变量
12、间接引用该空值的地方,本例子中的第29行和第39行。高效单元测试n5)右键单击报告中的冲突(用黄色提示图标显示出的节点)并在快捷菜单中选择相应的命令(Show Violation Origin或者Show Violation Point)能够让用户方便地访问冲突源点以及冲突节点。例如,“空指针异常”规则的冲突将会弹出Show Violation Origin(赋空值处)和Show Violation Point(发生空指针异常处)命令来帮助用户理解代码中产生该异常的原因。高效单元测试6)用户也可以右键选择冲突源点和冲突节点,在弹出的菜单中选择“Go to”,如图所示,即可定位到源代码中出错的位
13、置,如图所示。高效单元测试7)当然用户也可以双击Jtest视图中的冲突源点和冲突节点,来查看源代码中源点和节点的位置。上述三种方法都可以定位到源代码中可能存在bug的地方,如图所示:高效单元测试n8)由于第19行为变量sFirstLine对象赋值null,那么在第29行就存在隐含的问题:当程序执行完try这个模块后,还存在sFirstLine为null的可能性,那么在第29行使用该对象的属性的时候,就抛出异常。n如果测试人员发现代码中隐含的bug,那么请及时通知软件开发人员。如果是开发人员发现,或者开发人员受到测试人员的报告,则应及时修正。高效单元测试1.7小结nBugDetective的这种
14、独特的数据流分析技术能帮助软件开发团队在不实际运行代码的情况下发现关键的运行时缺陷,同时,它还能验证单元测试用例所暴露出的缺陷是否是在运行时会表现出来的“实际缺陷”。BugDetective能检测出很多能够逃避模式匹配静态分析以及单元测试的缺陷,而且这些缺陷往往也是人工测试以及检测所难以发现的。n当BugDetective同模式匹配静态分析、单元测试、容器测试(针对Java而言)、API测试、模块测试等测试一起构成完整的回归测试套件时,它能帮助开发团队:q 迅捷可靠地修改代码 帮助开发团队迅速建立一个回归测试安全网,它能在缺陷被引入代码后迅速地将其定位出来,并且还能帮助开发团队确定代码修改是否
15、破坏了其既有功能性,即使项目庞大的代码库没有通过测试或者只进行了很少量的测试。q 控制开发成本以及项目结点 尽早发现错误,以最低成本最迅速地对这些错误进行修复,同时广泛地测试潜在用户路径以查找难以发现的问题,避免推迟软件发布周期以及发布补丁包的可能。q优化开发资源 自动纠正约80%的编码问题,节约大量花在逐行审查代码以及调试上的时间,使开发者能更加着重于检查设计、算法以及实现等方面的问题。q低风险地享受前沿技术带来的便捷 降低测试复杂的企业级程序的难度(如SOA/Web服务程序以及Java EE应用程序等)。q获取对Java代码的质量以及完成程度有个可视化的报告 提供按需定制的客观代码资源的评
16、估并且以质量和项目节点为目标全程跟踪开发流程。高效单元测试动态测试指通过人工或者利用工具运行程序进行检查,分析程序的执行状态和程序的外部表现。动态测试通过运行被测程序,检查运行结果与预期结果的差异,并分析运行效率和健壮性等性能,由构造测试实例、执行程序、分析程序的输出结果三部分组成。单元测试、集成测试、确认测试、系统测试、验收测试、白盒测试、黑盒测试等都是动态测试。 Jtest的自动化动态测试完成单元测试、集成测试、白盒测试、黑盒测试等工作,可以自定义所执行测试的级别和范围,以便体现用户不同的需求和测试习惯。 关于Jtest的容器测试、回归测试、覆盖率分析以及Tracer测试将按照独立的章节进
17、行详细介绍。 2 Jtest动态测试动态测试 引述高效单元测试2.1 基于Jtest自动化测试nJtest提供了高效的方法执行白盒测试。完全自动执行所有的白盒测试过程,自动生成和执行精心设计的测试用例。自动标记任何运行失败,并以一种简单的图示化结构显示。 nJtest允许定制白盒测试用例的生成,和在什么层次上(项目、文件、类或方法)执行测试;Jtest通过自动生成大量测试用例,向程序注入数据流,考察程序是否会由于非法数据的输入而产生异常,导致程序不可控,从而检测程序的坚固性。 n同时,Jtest根据程序功能定义好每个入口,自动生成大量的功能性的测试用例,对程序进行功能测试,从而检测程序的功能。
18、通过自动化黑盒测试的大部分操作,减轻了这类测试的负担。 高效单元测试2.1.1了解和熟悉自动化单元测试配置n1)启动Jtest后,在菜单栏依次选择菜单项:“Jtest”-“Test Configurations”,在弹出的Test Configurations对话框的左边树形视图中,依次展开结点“Builtin”-“Unit Testing”,如图所示,在Unit Testing结点下列出了Parasoft Jtest 单元测试所有方法。如“Generate Unit Tests”,用来自动化生成单元测试用例;“Run Unit Tests”,用来自动化执行测试用例,等等。后面重点介绍桩函数,
19、回归测试,容器测试,以及Monitoring测试。 n2)对如何自定义和修改配置在前面讲静态测试时做了详细的讲述,这里在使用自定义配置来进行动态测试,是一样的,不做详细赘述。 高效单元测试2.2 自动化生成并执行测试用例下面讲述如何使用Parasoft Jtest的自动化单元测试功能。 1)打开例程com.embest.eclipse.jtest.demo。 2)选定目标进行测试,用户可针对文件、包或工程进行测试。这里展开com.embest.eclipse.jtest.demo,选择com.embest.eclipse.jtest.demo.bugdetectiveAndParametere
20、dTest分支,选择SortArrayList.java文件。3) 自动生成测试用例。 打开菜单依次选择菜单项“Jtest”-“Test Using”-“Builtin”-“Unit Testing”-“Generate Unit Tests”;开始针对要测试的源码生成单元测试用例; 高效单元测试在执行完成后,在工作空间中会生成在原来工程名后添加了.jtest的工程 高效单元测试4)用户可以通过在Test Configurations对话框中,复制此配置到User-Defined结点下,然后进行编辑修改配置:依次在编辑界面上选择标签页GenerationTest Class,如图所示: 高效单
21、元测试5)在Test Class中可以进行对生产的用例进行配置,对输出的Class进行的名称或者路径需要修改,可以通过点击选择按钮“Edit”打开对话框Edit Pattern for Unit Test Classes,如图所示,进行修改编辑,在每个参数的编辑框中可以通过点击按钮“Add Variable”在打 开的对话框Add Variable中选择抽取对应的参数。 高效单元测试6)依次展开生成的工程,如图所示,工程包和文件都是遵照之前的配置生成的, 其中文件SortArrayListTest.java为生成的用例文件。 高效单元测试n7)在生成的测试用例中,用户可以查看到对于被测文件的每
22、个方法,都会根据不同的条件,产生相对应的测试用例。如果用例中出现一些exception,会以注释的方式出现相对应的用例处,以提示用户。另外用户可以在Test configurations中将Run Unit Tests或者General and Run Unit Tests复制到User Defined结点下进行设置, 通过选择标签页Execution Severities,打开Severities标签页,如图所示: 高效单元测试n8)在Initial Severity Levels组中,点击Add按钮,打开Specify exception and severity对话框,在Exceptio
23、n文本框中输入java.lang.NullPointerException异常,然后在Severity组合框中设置安全等级,这里设置为Severity 1,如图示: 完成后点击Ok,最后在关闭Test Configurations对话框的之前,点击按钮Apply,将先编辑的配置应用。再此选择被测文件,使用配置的测试规则,进行测试,本例使用Run Unit Tests再次进行测试。测试完成后,在Jtest视图中查看到以下问题: 高效单元测试2.3 提取参数化的测试用例1)在生成测试用例后,用户还可以在生成的对应测试工程中右键选择测试文件SortArrayListTest.java,在打开的菜单中
24、依次选择菜单项JtestExtract Parameterized Test Case,如图示: 高效单元测试2)打开Test Case Parameterization对话框,选择通过生成含有探索和边角用例值的Excel工作薄,如图所示,如果不需要其他配置,直接使用默认配置点击按钮“Finish”: 高效单元测试完成后在测试用例的目录中生成Excel文件,如图所示: 高效单元测试在用例文件中,会自动添加一段代码,如图示高效单元测试3)将文件保存,选择菜单Jtest Test Using Builtin Run Unit Tests。 测试结果如图所示: 高效单元测试2.4总结本节举例讲述如何
25、利用Parasoft Jtest的自动化单元测试功能。开发测试人员首先使用工具对待测代码自动生成测试用例,然后自动化执行测试用例。此类测试可暴露意料之外的异常,并检查类在结构方面是否合理;助于开发测试人员在早期发现程序存在的问题,并提高程序的坚固性。 高效单元测试桩函数提供被调函数的占位,使得可以独立地进行单元测试而不依赖外部文件或函数。在使用桩函数时,Jtest 会重定向执行流程,调用一个桩函数替代原有函数。 桩函数主要有两个用途: 将正在测试的代码从集成环境中隔离出来。 在不可能影响函数行为、且需要使用替代实施的情况下进行测试。 用户可以为任何测试用例定义自己的桩函数,不管是自动生成的测试
26、用例还是用户定义的测试用例。当用户使用用户定义的桩函数时,可以完全控制外部函数的返回值 无需具有真正可用的外部函数。 3 桩函数 引述高效单元测试3.1 Jtest桩函数的使用1) 打开菜单栏依次选择菜单项Jtest Test Configurations,打开Test Configurations对话框,在此对话框中,依次展开左边树形视图的结点Builtin Unit Testing。在Unit Testing结点下,可以看到有几项如General Aggressive Stubs and Run Tests、General External Stubs and Run Tests等,如图所
27、示。这些定制的规则,可以根据用户的不同需求使用。一般来说,在Generate Unit Tests中已经默认配置了对桩函数的使用,只是用户定制的要求不同。高效单元测试n2)对桩函数的使用的例程,是Jtest自带的工程,可以通过菜单项FileNewOther打开New 对话框,在New对话框中展开节点Jtest,选择其子节点Jtest Example Project,在工作区中建立Jtest Example工程,选择包examples.stubs下的FileExample.java文件,打开此文件后,如图示: 高效单元测试3)在代码中,调用了对象file的相关方法, 然后通过选择Generate
28、 Unit Tests进行测试,生成的测试文件,如图所示: 对于用例,查看桩函数stubsAnalyze2(Member method,Object _this, Object args)方法,对于file的每个属性,都给定了一个确定的值,供被调函数使用,这样保证,在使用被测对象的时候,对于file的每个属性都有一个给定的状态和值,从而不用考虑,file的属性到底是否在外部进行定义。 高效单元测试4)对于桩函数的使用,可以对用例进行修改,自行生成桩函数的模板。过程如下: A:将方法testAnalyze1()修改为: public void testAnalyze1() throws Throwable File file = (File) Stubs.makeStubObject (File.class);String result = FileExample.analyze (file);B:然后右键点击方法名testAnalyze1()在弹出的菜单中依次选择菜单项JtestMake Stubs Method Template,生成模板为高效单元测试5)另外对桩函数的配置用户在配置面板Test Configurations中在标签页GeneralFilter,在Filter标签页中对于用例的生成,以及桩函数的生成进行配置。