[技術博客]JSCover+selenium得到js代碼覆蓋率

本文檔講解了咱們是如何使用JSCover來得到Selenium的測試樣例的js代碼文件的執行覆蓋率的。javascript

事實上網上有挺多博客講這玩意兒了,不過徹底按照網上已有的教程去弄的的話,並沒有法知足咱們的須要。html

參考連接:java

  1. https://www.cnblogs.com/bhlsheji/p/4
  2. https://stackoverflow.com/questions/9495625/selenium-is-there-any-js-javascript-code-coverage-tool-which-we-can-integrate
  3. http://tntim96.github.io/JSCover/manual/manual.xml

工具介紹

Selenium

瀏覽器自動化測試工具。能夠模擬用戶對瀏覽器的操做,從而起到自動化測試的效果。具體怎麼用,網上一堆教程,不贅述了。python

selenium會在測試樣例的編寫中被使用,咱們還會使用selenium的executeScript調用JSCover提供的hook來保存覆蓋率數據。git

JSCover

js代碼覆蓋率檢測工具。原理是插樁js代碼,該項目在github上開源,它也有託管在github上的官網。附帶一提,根據個人使用經驗來看,有問題不要查百度、也不要查它的user manual,而是應該查github上的issue。github

JSCover咱們只使用它的JSCover-all.jar文件,下下來之後就拿出來這個就好了。chrome

原理性流程

  1. 使用JSCover對js代碼進行插樁,使得咱們可以得到代碼覆蓋率。
  2. 對插樁後的代碼執行測試樣例。
  3. 將各測試樣例的代碼覆蓋率導出保存起來。
  4. 合併各測試樣例的代碼覆蓋率
  5. 使用合併後的代碼覆蓋率文件生成測試報告

流程示意圖

實際流程的分步講解

0. 預準備jscoverage.js

這一步是由於jscover自身存在的問題,緣由以後再講解。總之先得在不啓用local-storage的狀況下對代碼進行一次插樁,獲得jscoverage.jsjson

示例指令:java -Dfile.encoding=UTF-8 -jar JSCover-all.jar -fs D:/code_origin D:/code_instrumented瀏覽器

  • -Dfile.encoding=UTF-8:設定編碼,避免網頁代碼中的中文在插樁後變成亂碼。
  • -jar JSCover-all.jar:指定JSCover-all.jar的所在路徑。
  • -fs:指定使用文件插樁模式。咱們只使用該模式,除此以外還有proxy模式,不過咱們不使用,緣由見最下。
  • D:/code_originD:/code_instrumented:前者爲原來的js代碼文件所在的目錄,後者爲想把插樁後的代碼保存到的目錄。

執行完上述指令後,應該就能在插樁後的代碼的所在目錄(也就是示例中的D:/code_instrumented)中找到jscoverage.js文件,將它保存到一個合適的地方,留待以後使用。工具

1. 代碼插樁

代碼插樁分爲兩部分,一部分是給網頁的js代碼文件插樁,使得執行時可以獲得覆蓋率變量。另外一部分是在測試樣例的執行末尾利用selenium提供的executeScript調用JSCover提供的hook,這本質就是個動態插樁的過程,它使得咱們可以保存下來覆蓋率數據。

網頁的js代碼文件插樁

示例指令:java -Dfile.encoding=UTF-8 -jar JSCover-all.jar -fs --local-storage D:/code_origin D:/code_instrumented

事實上,它和上一步「預準備」中的指令的差異僅在於--local-storage而已。local-storage的含義是「是否啓用HTML5的local-storage功能來保存代碼覆蓋率變量」。若是不啓用的話,JSCover就會用一個js變量來保存代碼覆蓋率變量,而衆所周知,js變量是沒法跨頁面的,這也就致使每當咱們切換頁面時,代碼覆蓋率變量就會丟失。因此咱們須要啓用local-storage來保存代碼覆蓋率變量。

不過JSCover在local-storage模式下生成的jscoverage.js文件存在bug,因此咱們在上一步「預準備」時須要先在非local-storage下生成一個jscoverage.js文件。這個文件僅僅是用來顯示測試報告用的,不會影響到代碼覆蓋率數據。

hook調用

這一部分能夠參考參考連接3(官方手冊)中的作法。官網代碼的python版:

json_str = driver.execute_script("return jscoverage_serializeCoverageToJSON();")

以後將json_str保存成jscoverage.json,而後放到插樁後的代碼所在目錄下,覆蓋掉原來的jscoverage.json文件就好了。

不過由於官網這種作法是一個類一個jscoverage.json,一個類在selenium中就表示一類測試樣例,而咱們有好多好多類測試樣例,因此就會有好多好多代碼覆蓋率文件jscoverage.json。因此咱們須要在執行時分別保存它們,在所有執行完後再合併它們。合併會在後面再講解。

假設咱們有三個Selenium的測試類,分別將叫TC_A, TC_B, TC_C。那咱們能夠生成相似如下的一個目錄結構

- coverage
    - TC_A
        - jscoverage.json
    - TC_B
        - jscoverage.json
    - TC_C
        - jscoverage.json

這僅僅只須要在保存json_str時操做一下就好了,再也不贅述。

2. 執行測試樣例

這一部分和平時如出一轍,僅僅須要注意要執行插樁後的網頁代碼文件,而不是插樁前的。

3. 合併代碼覆蓋率文件

在執行測試樣例後,一切正常的話,就能獲得相似在第一步中描述的那樣的代碼覆蓋率文件的目錄結構了:

- coverage
    - TC_A
        - jscoverage.json
    - TC_B
        - jscoverage.json
    - TC_C
        - jscoverage.json

示例指令: java -cp JSCover-all.jar jscover.report.Main --merge coverage/* D:/code_instrumented

  • coverage/*:也就是上述的目錄結構的頂層目錄的路徑。
  • D:/code_instrumented:合併後的代碼覆蓋率文件的保存目錄。咱們直接指定爲插樁後的代碼的所在目錄,省去手動覆蓋的麻煩。

注意,若是隻有一個jscoverage.json的話,是沒法使用上述指令進行合併的,畢竟只有一個,JSCover會報錯。這時候請手動複製那惟一一個jscoverage.json,覆蓋掉原來的jscoverage.json

4. 生成測試報告

把咱們在「預準備」時搞到的jscoverage.js翻出來,而後覆蓋掉插樁後的代碼所在目錄下的jscoverage.js,再修改一下它,將jscoverage_isReport改成true:

var jscoverage_isReport = true;

最後打開jscoverage.html便可。可能會啥都沒,這時候你打開瀏覽器的控制檯看看報啥錯吧,例如chrome的話,一般而言都是Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.,而後百度百度解決一下,或者換個瀏覽器再試試,或者本身改改jscoverage.html,都行。我是最後直接用Edge打開了。

最後應該是這樣子的:

點開一個文件的話,就能看見哪些行被覆蓋了,哪些沒有:

不使用JSCover的Proxy模式的緣由

Proxy模式要方便不少,能夠省去插樁網頁代碼的步驟。由於proxy模式下,jscover會截獲全部瀏覽器的發包和收包,對於全部發過來的js文件,它都會自動進行插樁。

不過由於JSCover的Proxy模式須要修改瀏覽器代理。而咱們目前的本地測試環境使用了Fiddler做爲瀏覽器代理,這兩個代理衝突了,也就只能二選一,因此咱們沒有使用JSCover的Proxy模式,不過要是你的項目不使用瀏覽器代理來搭建本地測試環境,能夠考慮用用JSCover的proxy模式,真的方便不少。

相關文章
相關標籤/搜索