簡體   English   中英

Rails + Capybara-webkit – javascript 代碼覆蓋率?

[英]Rails + Capybara-webkit – javascript code coverage?

我正在考慮使用 capybara-webkit 對應用程序進行一些接近現實的測試。 這是絕對必要的,因為該應用程序具有非常豐富的基於 JS 的 UI,而 Rails 部分主要是 API 調用。

問題是:是否有任何工具可以集成到測試管道中,可以檢測 Javascript 代碼並報告其覆蓋范圍? 這里的關鍵是能夠輕松地集成到測試工作流程中(就像 rcov/simplecov)——我不喜歡這個想法自己用 jscoverage 或模擬來做:)

提前謝謝了。

更新:從 JSCover 1.05 版開始,不再需要我在之前的答案中概述的技巧。 我已經更新了我的答案以反映這一點。

我設法讓JSCover在 Rails + Capybara管道中工作,但確實需要一些黑客才能讓它工作。 我構建了一個小 rake 任務:

  1. 使用 rails 資產管道生成腳本
  2. 調用 java jar 來檢測所有文件並在臨時目錄中生成一個空報告
  3. 修補 jscover.js 腳本以在“報告模式”下運行(只需在末尾添加 jscoverage_isReport=true)
  4. 將結果復制到 /public/assets 以便測試無需任何更改即可獲取它,因此可以在瀏覽器中自動打開覆蓋率報告

然后我添加了一個設置任務來在測試開始時清除瀏覽器的 localStorage 和一個在結束時寫出完成報告的拆卸任務。

def setup
  unless $startup_once
    $startup_once=true
    puts 'Clearing localStorage'
    visit('/')
    page.execute_script('localStorage.removeItem("jscover");')
  end
end
def teardown
  out=page.evaluate_script("typeof(_$jscoverage)!='undefined' && jscoverage_serializeCoverageToJSON()")
  unless out.blank? then
    File.open(File.join(Rails.root,"public/assets/jscoverage.json"), 'w') {|f| f.write(out) }
  end
end

無論如何,最終結果效果很好,這樣做的好處是它也適用於無頭瀏覽器,因此它也可以包含在 CI 中。

*** 更新 2:這是一個自動執行步驟的 rake 任務,將其放在 /lib/tasks 中

# Coverage testing for JavaScript
#
# Usage:
# Download JSCover from: http://tntim96.github.io/JSCover/ and move it to
#   ~/Applications/JSCover-1
# First instumentalize the javascript files:
#   rake assets:coverage
# Then run browser tests 
#   rake test
# See the results in the browser
#   http://localhost:3000/assets/jscoverage.html
# Don't forget to clean up instrumentalization afterwards:
#   rake assets:clobber
# Also don't forget to re-do instrumentalization after changing a JS file


namespace :assets do
  desc 'Instrument all the assets named in config.assets.precompile'
  task :coverage do
    Rake::Task["assets:coverage:primary"].execute
  end

  namespace :coverage do
    def jscoverage_loc;Dir.home+'/Applications/JSCover-1/';end
    def internal_instrumentalize

      config = Rails.application.config
      target=File.join(Rails.public_path,config.assets.prefix)

      environment = Sprockets::Environment.new
      environment.append_path 'app/assets/javascripts'
      `rm -rf #{tmp=File.join(Rails.root,'tmp','jscover')}`
      `mkdir #{tmp}`
      `rm -rf #{target}`
      `mkdir #{target}`

      print 'Generating assets'
      require File.join(Rails.root,'config','initializers','assets.rb')
      (%w{application.js}+config.assets.precompile.select{|f| f.is_a?(String) && f =~ /\.js$/}).each do |f|
        print '.';File.open(File.join(target,f), 'w') {|ff| ff.write(environment[f].to_s) }
      end
      puts "\nInstrumentalizing…"
      `java -Dfile.encoding=UTF-8 -jar #{jscoverage_loc}target/dist/JSCover-all.jar -fs #{target} #{tmp} #{'--no-branch' unless ENV['C1']} --local-storage`
      puts 'Copying into place…'
      `cp -R #{tmp}/ #{target}`
      `rm -rf #{tmp}`
      File.open("#{target}/jscoverage.js",'a'){|f| f.puts 'jscoverage_isReport = true' }

    end

    task :primary => %w(assets:environment) do
      unless Dir.exist?(jscoverage_loc)
        abort "Cannot find JSCover! Download from: http://tntim96.github.io/JSCover/ and put in #{jscoverage_loc}"
      end
      internal_instrumentalize
    end

  end

end

現在已將其添加到 JSCover(在主干中)- JSCover 上的相關線程在此處

我設法讓 JSCover 在 Rails + Capybara 管道中工作,但它確實需要相當多的黑客才能讓它工作

這些更改現在位於 JSCover 的主干中,並將成為 1.0.5 版的一部分。 那里也有工作示例(包括一個 Selenium IDE 記錄示例)和文檔。

需要一些額外的工作才能使分支檢測工作,因為它使用無法輕松序列化為 JSON 的對象

這是在新代碼中使用的執行此操作的函數。

無論如何,最終結果效果很好

我同意。 這使得 JSCover 可被更高級別的工具使用,這些工​​具不適用於 iFrame 或通過這種方法避免的多個窗口。 這也意味着可以通過兩個調整將代碼覆蓋率添加到現有的 Selenium 測試中:

  1. 使測試通過 JSCover 代理運行
  2. 在測試套件結束時保存覆蓋率報告

有關更多信息,請參閱 JSCover 的文檔。 包含這些更改的 1.0.5 版應該會在幾天內發布。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM