4

私はcapybara-webkitを使用して、アプリの現実に近いテストを行うことを検討しています。アプリは非常に豊富なJSベースのUIを備えており、Railsの部分はほとんどAPI呼び出しであるため、これは絶対に必要です。

問題は、Javascriptコードをインストルメント化してそのカバレッジを報告できるテストパイプラインに統合するツールはありますか?ここで重要なのは、テストワークフロー(rcov / simplecovのように)に簡単に統合できることです。jscoverageやanalogを使って自分でやるというアイデアは好きではありません:)

よろしくお願いします。

4

2 に答える 2

1

これは JSCover (トランク内) に追加されました - JSCover の関連スレッドはこちらです。

Rails + Capybara パイプラインで JSCover を動作させることができましたが、動作させるにはかなりのハッキングが必要でした。

これらの変更は現在 JSCover のトランクにあり、バージョン 1.0.5 の一部になります。実用的な例 (Selenium IDE で記録された例を含む) とドキュメントもそこにあります。

JSON に簡単にシリアル化できないオブジェクトを使用するため、分岐検出を機能させるには追加の作業が必要です。

これは、新しいコードで使用されるこれを行う関数です。

とにかく、最終結果はうまく機能します

同意します。これにより、このアプローチでは回避される iFrame や複数のウィンドウではうまく機能しない高レベルのツールで JSCover を使用できるようになります。また、次の 2 つの調整により、既存の Selenium テストにコード カバレッジを追加できることも意味します。

  1. JSOver プロキシを介してテストを実行する
  2. テスト スイートの最後にカバレッジ レポートを保存します。

詳細については、JSCover のドキュメントを参照してください。これらの変更を含むバージョン 1.0.5 は、数日中にリリースされる予定です。

于 2013-09-15T07:25:59.727 に答える
1

更新: JSCover バージョン 1.05 以降、以前の回答で概説したハックは不要になりました。これを反映するように回答を更新しました。

Rails + Capybara パイプラインでJSCoverを動作させることができましたが、動作させるにはいくつかのハッキングが必要でした。私は小さなレーキタスクを構築しました:

  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: これはステップを自動化するレーキ タスクです。これを /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
于 2013-08-24T16:15:10.247 に答える