LoginSignup
5
4

More than 5 years have passed since last update.

JSCover + WebDriverでテスト対象のJavaScriptのカバレッジを計測する

Last updated at Posted at 2013-12-17

追記: この記事ではJSCoverをプロキシモードで利用する方法を説明したが,いくつかのアプリケーションで,動作が不安定な場合(レスポンスが帰ってこない)ことがあった.過去にはこういうissueもあったようだが,関連はわからない.JavaScriptがサーバ側で動的に生成されるのでなければ,file-systemモードなどを利用するほうが安心かもしれない


Selenium WebDriverですでに書かれたテストが存在するときに,JavaScriptのカバレッジを記録したい.

JSCoverとは

Javaで書かれたJavaScriptのカバレッジ測定用プログラム.以前はJSCoverageというものが有名だったが,現在はJSCoverに引き継がれたっぽい.公式サンプルがgithubにあるが,要点をここにまとめておく.

導入

pom.xmlに以下のdependencyを追加する

    <dependency>
      <groupId>com.github.tntim96</groupId>
      <artifactId>JSCover</artifactId>
      <version>1.0.6</version>
      <scope>test</scope>
    </dependency>

ついでにJUnitとSelenium (WebDriver)も導入しておく

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.10</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.seleniumhq.selenium</groupId>
      <artifactId>selenium-java</artifactId>
      <version>2.38.0</version>
      <scope>test</scope>
    </dependency>

方針

JSCoverの使い方もいろいろあるっぽい( 公式ドキュメント )が,今回はプロキシモードを利用する.JSCover自体がプロキシの働きをして,テスト時に動的にカバレッジ測定用にJavaScriptを書き換えてくれる.

  1. JSCoverをプロキシとして起動
  2. WebDriverが上のプロキシを利用する用に設定
  3. テストを行い,JSCoverの画面を自動操作してカバレッジ測定結果をHTML形式で保存

※ 以下のサンプルでは簡単のため常にカバレッジを計測しているが,実際の運用ではフラグなどを立てて必要な時だけカバレッジを図るようにしたほうがパフォーマンス上好ましいかも知れない

JSCoverをプロキシとして起動

    private static Thread server;

    // JSCover起動用オプション
    // 3129ポートを利用してプロキシとして起動する
    private String[] args = new String[]{
            "-ws",
            "--port=3129",
            "--proxy",
            "--local-storage",
           // カバレッジ測定除外設定,今回はjquery関係のファイルは無視
            "--no-instrument-reg=.*jquery.*",
            "--report-dir=" + getReportDir()
    };

    protected String[] getArgs() {
        return args;
    }

    @Before
    public void setUp() throws IOException {
        File jsonFile = new File("js-cover-report/jscoverage.json");
        if (jsonFile.exists())
            jsonFile.delete();
        // プロキシサーバの遅延初期化
        if (server == null) {
            server = new Thread(new Runnable() {
                public void run() {
                    try {
                        Main.main(getArgs());
                    } catch (IOException e) {
                        throw new RuntimeException("Err", e);
                    }
                }
            });
            server.start();
        }
    }

WebDriverが上のプロキシを利用する用に設定

    private static WebDriver driver = getInstrumentedDriver();
    // JSCoverプロキシを利用する用設定したFirefoxDriverインスタンスの取得
    public static WebDriver getInstrumentedDriver() {
        Proxy proxy = new Proxy().setHttpProxy("localhost:3129");
        DesiredCapabilities cap = new DesiredCapabilities();
        cap.setCapability(CapabilityType.PROXY, proxy);
        return new FirefoxDriver(cap);
    }

テストを行い,JSCoverの画面を自動操作してカバレッジ測定結果をHTML形式で保存

    @Test
    public void awesomeTestAndSaveJSCoverage() {
        driver.get("http://localhost/your_test_target");

        /* 何かしらのテスト */

        // JSCoverのカバレッジ一覧ページを開く
        driver.get("http://localhost/jscoverage.html");
        // 画面を自動で操作して"Store Report"ボタンを押下,カバレッジ測定結果を記録する
        new WebDriverWait(driver, /* 最大2秒待つ,この値は適当 */ 2).until(
                ExpectedConditions.elementToBeClickable(By.id("storeTab"))).click();
        new WebDriverWait(driver, 2).until(
                ExpectedConditions.elementToBeClickable(By.id("storeButton"))).click();
        new WebDriverWait(driver, 2).until(
                ExpectedConditions.textToBePresentInElement(By.id("storeDiv"), "Coverage data stored at"));

        // 測定結果をWebDriverで開く
        driver.get("file:///" + new File(getReportDir() + "/jscoverage.html").getAbsolutePath());
        // この先は人間が見てもいいし,WebDriverを使ってさらに自動化しても良い
    }

上記を合わせたコードをhttps://gist.github.com/daisy1754/8002254 においておく.

5
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4