Rails + Capybara-webkit – javascript 代码覆盖率? [英] Rails + Capybara-webkit – javascript code coverage?

查看:63
本文介绍了Rails + Capybara-webkit – javascript 代码覆盖率?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在考虑使用 capybara-webkit 对应用程序进行一些接近现实的测试.这是绝对必要的,因为该应用具有非常丰富的基于 JS 的 UI,而 Rails 部分主要是 API 调用.

I am looking into using capybara-webkit to do somewhat close-to-reality tests of app. This is absolutely neccessary as the app features a very rich JS-based UI and the Rails part is mostly API calls.

问题是:是否有任何工具可以集成到测试管道中,可以检测 Javascript 代码并报告其覆盖范围?这里的关键是能够轻松地集成到测试工作流程中(就像 rcov/simplecov)——我不喜欢这个想法自己用 jscoverage 或模拟来做 :)

The question is: is there any tools to integrate into testing pipeline which could instrument Javascript code and report its coverage? The key here is the ability to integrate into testing workflow (just like rcov/simplecov) easily – I don't like the idea do it myself with jscoverage or analogue :)

非常感谢.

推荐答案

更新: 从 JSCover 1.05 版开始,不再需要我在之前的答案中概述的技巧.我已经更新了我的答案以反映这一点.

Update: Starting from JSCover version 1.05 the hacks I outlined in my previous answer are no longer needed. I've updated my answer to reflect this.

我设法让 JSCover 在 Rails + Capybara 管道中工作,但确实需要一些黑客攻击让它工作.我构建了一个小 rake 任务:

I managed to get JSCover working in the Rails + Capybara pipeline, but it did take some hacking to get it to work. I built a little rake task that:

  1. 使用 rails 资产管道生成脚本
  2. 调用 java jar 来检测所有文件并在临时目录中生成一个空报告
  3. 修补 jscover.js 脚本以使其在报告模式"下运行(只需在末尾添加 jscoverage_isReport=true)
  4. 将结果复制到/public/assets 以便测试无需任何更改即可获取它,因此可以在浏览器中自动打开覆盖率报告

然后我添加了一个设置任务,在测试开始时清除浏览器的 localStorage 和一个拆卸任务,在最后写出完成的报告.

Then I added a setup task to clear out the browser's localStorage at the start of the tests and a teardown task that writes out the completed report at the end.

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 中.

Anyway, the end result works nicely, the advantage of doing it this way is that it also works on headless browsers so it can also be included in CI.

*** 更新 2:这是一个自动执行步骤的 rake 任务,将其放入/lib/tasks

*** Update 2: Here is a rake task that automates the steps, drop this in /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

这篇关于Rails + Capybara-webkit – javascript 代码覆盖率?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆