EMMA 是一個開源、面向 Java 程序測試覆蓋率收集和報告工具。它經過對編譯後的 Java 字節碼文件進行插裝,在測試執行過程當中收集覆蓋率信息,並經過支持多種報表格式對覆蓋率結果進行展現。EMMA能夠統計幾種覆蓋率:class,method,block, line。支持版本迭代的覆蓋率統計html
EMMA基本是四步曲:插樁(instr),運行,收集(ctl),報告(report)。下面分別詳細的介紹下java
下載地址:http://sourceforge.net/projects/emma/files/emma-testing/apache
目前流行使用的是v2.1.*,由於支持ctl命令app
將emm.jar cp /usr/local/jdk/jre/lib/ext 下面,安裝完成工具
command:java emma instr -cp /usr/local//anrs/lib/anrs.jar -m overwrite -ix +com.* -Dmetadata.out.file=test.em測試
參數介紹:ui
-cp,指定插樁的路徑,多個jar包能夠用,分割spa
-m:輸出模式.net
overwrite:從新jar包,anrs.jar命令行
default:copy, 須要加上-d參數,指定輸出路徑。有插樁,才cp一份class到指定路徑
fullcopy:須要加上-d參數,指定輸出路徑。 無論有沒有插樁,都cp一份class到指定路徑
-merge:合併。
default:yes。 若是metadata指定輸出的文件同樣,將兩次插樁信息進行合併
no。不合並兩次插樁信息
-ix:指定須要插樁的class
+com.*: + 指包含
-com.*:-指排除
支持多個+和-,用逗號分隔
這個功能對咱們關注被改動的代碼頗有做用
-Dmetadata.out.file: 指定元數據(metadata)輸出路徑。默認是當前路徑
咱們在測試過程當中, 通常都會去更新幾回jar包,而且咱們但願統計出這個版本測試的覆蓋率,咱們就須要把幾回的元數據進行合併
通常狀況下,直接運行應用程序便可。EMMA會啓動一個監聽端口,用來後面收集信息(ctl)。這個端口是固定的,47653。
若是咱們的應用是多進程的,就會出現啓動失敗。
其實EMMA也提供了一個命令,進行端口設置:-Demma.rt.control.port=39123
還有host指定,-Demma.rt.control.host=192.168.22.22. default is localhost
這個參數須要加在程序啓動命令裏
EMMA還有簡單的配置文件:java -Demma.properties=my.properties
my.properties format: tag=value
能夠配置的參數參考:http://emma.sourceforge.net/reference/ch03s02.html#prop-ref.tables
通常有兩種收集信息方法:
1. 程序退出,自動收集,在當前運行目錄下生成coverage.ec
2. 命令行:
java -cp /usr/jdk/jdk1.6.0_23/jre/lib/ext/emma.jar emma ctl -connect localhost:47653 -command coverage.get,coverage.ec
合併.ec文件
因爲 EMMA 中測試覆蓋率是經過與 「*.em」 文件關聯得到代碼信息的,所以當代碼發生變化時,已經運行過的測試沒必要徹底重複,只需將獲得的 「*.ec」 文件合併(新獲得的 「*.ec」 文件放在後面),而後關聯最新的 「*.em」 文件便可獲得代碼變化後的覆蓋率信息,這方便了 EMMA 支持版本變化的測試。在生成新的測試報告的時候,須要注意 「*.ec」 的時間必定要晚於 「*.em」 文件。
1. 自動合併。若是生成的.ec文件名字相同,自動合併。
2. 命令行合併:java -cp /usr/jdk/jdk1.6.0_23/jre/lib/ext/emma.jar emma merge -input SM1.ec, SM2.ec -outfile SM.ec
.ec 文件須要按照時間從前到後排列,才能保證合併信息正確(參考網上說法。但我測試的結果發現,自動合併與merge合併的結果不一致,自動合併的結果更準確。因此最好使用自動合併)
默認合併爲coverage.es。
貌似如今的版本outfile參數不起做用,都會合併爲coverage.es
清除執行統計信息
若是咱們想要每一個測試用例的獨立覆蓋率報告,須要將內存中的執行信息清除掉。
目前有兩種清除方法:
1. 重啓應用
2. 命令行:reset
java -cp /usr/jdk/jdk1.6.0_23/jre/lib/ext/emma.jar emma ctl -connect localhost:47653 -command coverage.reset
reset只能清除內存中記錄的方法、塊、行的執行信息,可是沒法清除類覆蓋信息。
command:
java -cp /usr/jdk/jdk1.6.0_29/jre/lib/ext/emma.jar emma report -r html -in anrs.em coverage.ec –sp src/-Dreport.html.out.file=coverage.html
參數介紹
-r: report type:html,txt,xml
-sp: sourcecode path
<http://www.51testing.com/?uid-170805-action-viewspace-itemid-87390>
"emma ctl:
coverage.get: RPC failure while executing [coverage.get]
Exception in thread "main" com.vladium.emma.EMMARuntimeException: coverage.get:
RPC failure while executing [coverage.get]
at com.vladium.emma.ctl.CtlProcessor._run(CtlProcessor.java:242)"
須要在應用執行目錄下進行插樁,就能夠解決這個issue
Exception in thread "main" java.lang.NoClassDefFoundError: com/vladium/emma/rt/R
T
at org.apache.jmeter.NewDriver.$VRi(NewDriver.java)
at org.apache.jmeter.NewDriver.<clinit>(NewDriver.java)
errorlevel=1
因爲java加載ApacheJMeter.jar包時ClassLoader順序非預期,經過-
Xbootclasspath/p:E:\alibaba\tools\emma-stable-2.1-lib\emma.jar 強制優先加載emma.jar。
故修改應用啓動腳本爲(以jemeter爲例)
%JM_START% %JM_LAUNCH% -Xbootclasspath/p:E:\alibaba\tools\emma-stable-2.1-lib\emma.jar %
JVM_ARGS% %ARGS% -jar "%JMETER_BIN%ApacheJMeter.jar" %JMETER_CMD_LINE_ARGS%
應用程序會啓動多個進程,啓動腳本也會執行jar包。---須要解決emma端口衝突
測試過程當中,因爲bug會修改代碼,版本迭代。但願統計這些版本的整個覆蓋率信息---emma支持多個版本的覆蓋率統計
但願每一個case都有本身獨立的覆蓋率統計信息,同時也要有整個的覆蓋統計信息。
每一個case執行的步驟:
1. 判斷是否更新了jar包
1.1 更新:插樁,指定同個文件名合併到一塊兒
1.1.1 stop app
1.1.2 設置 EMMAPORT 環境變量
1.1.3 啓動一個應用進程,指定EMMAPORT:-Demma.rt.control.port=$EMMAPORT
1.1.4 循環1.1.2 & 1.1.3,啓動完全部的進程
1.2 未更新:
1.2.1 清除執行信息:
java -cp /usr/jdk/jdk1.6.0_23/jre/lib/ext/emma.jar emma ctl -connect localhost:47653 -command coverage.reset
2. 執行case
3. 收集執行信息
3.1 把全部進程的執行信息收集到一個文件裏
java -cp /usr/jdk/jdk1.6.0_23/jre/lib/ext/emma.jar emma ctl -connect localhost:47653 -command coverage.get,coverage.ec
3.2 每一個case須要有獨立的執行信息
cp coverage.ec coverage_caseNo.ec
4. 生成報告
測試完這個版本後,生成報告