执行 Selenium 测试时,当框架打开 Web 浏览器、闪电般执行测试,然后关闭该浏览器并生成 HTML 报告时,不要被吓到。这是一种在开发生命周期的早期更快更容易地发现问题的方法(此时它们更易处理)。
回页首
使用 Cobertura 报告代码覆盖率
是否达到 100% 就是问题所在
运行像 Cobertura 或者 Emma 这样的工具时,记住以下方面很重要:在一个特殊的方法中实现 100% 的行覆盖并不意味着该方法没有缺陷或者它已被完全测试。例如,如果您编写了一个针对 if 语句的测试,该测试包含逻辑 And,而测试针对的是表达式的左侧部分,则像 Cobertura 这样的工具将报告 100% 行覆盖,但是实际上,您仅执行了该语句的 50%;因此仅完成了 50% 的分支覆盖。
现在已经编写了一些测试,如何确定所有这些测试执行什么 呢?幸运的是,此问题可由像 Cobertura 这样的代码覆盖工具来解答。代码覆盖工具可报告测试覆盖率 —— 以行覆盖或分支覆盖形式表示 —— 它表示测试运行时所涉及的代码量。
清单 8 展示了一个 Ant 脚本。该脚本使用 Cobertura 生成一份关于代码覆盖率的 HTML 报告,代码覆盖率通过运行一系列 JUnit 测试获得:
清单 8. 使用 Ant 和 Cobertura 报告代码覆盖率
<target name="instrument-classes"> <mkdir dir="${instrumented.dir}" /> <delete file="cobertura.ser" /> <cobertura-instrument todir="${instrumented.dir}"> <ignore regex="org.apache.log4j.*" /> <fileset dir="${classes.dir}"> <include name="**/*.class" /> <exclude name="**/*Test.class" /> </fileset> </cobertura-instrument> </target> <target name="run-instrumented-tests" depends="instrument-classes"> <mkdir dir="${logs.junit.dir}" /> <junit fork="yes" haltonfailure="true" dir="${basedir}" printsummary="yes"> <sysproperty key="net.sourceforge.cobertura.datafile" file="cobertura.ser" /> <classpath location="${instrumented.dir}" /> <classpath location="${classes.dir}" /> <classpath refid="test.class.path" /> <classpath refid="project.class.path"/> <formatter type="plain" usefile="true" /> <formatter type="xml" usefile="true" /> <batchtest fork="yes" todir="${logs.junit.dir}"> <fileset dir="${test.component.dir}"> <patternset refid="test.sources.pattern"/> </fileset> </batchtest> </junit> </target> |
Cobertura 产生了一个如图 1 中所示的 HTML 报告。请注意行覆盖和分支覆盖的百分比是以包计算的。可单击每一个包,获得类级别的行百分比和路径百分比,甚至能看到执行的源代码行和它们执行的次数。
图 1. 使用 Cobertura 和 Ant 生成 HTML 报告
需要多高的代码覆盖率?
理想情况下,您可能想针对每个路径执行一次测试。也就是说,如果整个代码基址有 20,000 的循环复杂度的话,则需要 20,000 次测试。我从未遇到过具有 100% 的路径覆盖的项目,不过我曾见过具有近 100% 的行覆盖的团队。
已经介绍了多种类型的测试,甚至介绍了如何测量这些测试的覆盖率 —— 但是如何确保以正常的间隔执行 这些测试呢?恰好,这正是 CI 服务器(如 CruiseControl)大显身手的地方,接下来对它进行介绍。
持续运行测试
一旦将这些各式各样的开发人员测试类型合并到一个构建过程中时,可以将这些测试中的一些(或者全部)作为 CI 过程的一部分运行。例如,清单 9 是 CruiseControl 的 config.xml 文件的一个片段,我在其中定义了一些东西。首先,我让 CruiseControl 每两分钟监控一次 Subversion 库中的改变。如果发现任何改变,则 CruiseControl 将启动一个叫做 build-${project.name}.xml 的委托 构建脚本(通常,此脚本用 Ant 编写)。该委托构建脚本调用项目的构建脚本,后者执行编译并运行测试。
我也定义了一些逻辑,将所有不同类型的测试结果合并到一个 CruiseControl 日志文件中。而且,我还利用 CruiseControl 的功能将不同工具生成的报告链接(使用 artifactspublisher 标签)到 Build Artifacts 链接中,Build Artifacts 可以从 CruiseControl 的显示板应用程序中获得。
清单 9. 使用 CruiseControl 的 CI
... <modificationset quietperiod="30"> <svn RepositoryLocation="http://your-domain.com/trunk/brewery" username="bfranklin" password="G0Fly@Kite"/> </modificationset> <schedule interval="120"> <ant anthome="apache-ant-1.6.5" buildfile="build-${project.name}.xml"/> </schedule> <log dir="logs/${project.name}"> <merge dir="projects/${project.name}/_reports/unit"/> <merge dir="projects/${project.name}/_reports/component"/> <merge dir="projects/${project.name}/_reports/performance"/> <merge dir="projects/${project.name}/_reports/functional"/> <merge dir="projects/${project.name}/_reports/coverage"/> </log> <publishers> <artifactspublisher dir="projects/${project.name}/_reports/" dest="projects/artifacts/${project.name}"/> </publishers> ... |
原文转自:http://www.ibm.com/developerworks/cn/java/j-ap03137/index.html