執行 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