Open7

TypeScript + Karma + QUnit のテスト環境構築

Yasuhito TakamiyaYasuhito Takamiya

Karma や QUnit なんて今どき使ってる人いなさそうだな。TypeScript で書いています。環境は Rails + Webpacker です。

やりたいこと

  • ユニットテストを Karma で動かす
  • ソースマップを付ける
  • 失敗したテストコードを VS Code や Emacs でハイライト
Yasuhito TakamiyaYasuhito Takamiya

ひとまず現状の Karma の設定 (karma.conf.js) を見直してみる:

const webpackConfig = require("./config/webpack/test.js")

module.exports = function (config) {
  config.set({
    webpack: webpackConfig,

    webpackMiddleware: {
      noInfo: true,
    },

    // files と exclude で参照されるルートパス
    basePath: ".",

    // テストに使うブラウザ
    browsers: ["ChromeHeadless"],

    // テストフレームワーク
    frameworks: ["qunit"],

    // ブラウザにロードするテストファイル (のパターン)
    files: ["app/javascript/test/**/*.ts"],

    // files から除外するファイル (のパターン)
    exclude: [],

    // 使うプリプロセッサのマップ
    preprocessors: {
      "app/javascript/test/**/*.ts": ["webpack"],
    },

    // テスト結果のリポーター
    reporters: ["progress"],

    // ファイルが変更したときに自動的にテストを実行するかどうか
    autoWatch: false,

    // CI 用。true だとテストを一度だけ実行する
    singleRun: true,
  })
}

よくわからないこと

Yasuhito TakamiyaYasuhito Takamiya

けっきょく、これ↓はコンパイル時にバンドルの情報とか余計なものを出さない、という設定らしい。出ている気がするけどあとで見てみる。

 // ...

  webpackMiddleware: {
     noInfo: true,
   },

  // ...
Yasuhito TakamiyaYasuhito Takamiya

次の設定でソースマップまではできるようになった。ポイントはすべてのテストをまとめる test/index_test.js というファイルを作り、webpacker でインラインソースマップをつけること。こうするとテストのファイルごとの実行ができなくなる (常にすべて実行) だけど、ほかに簡単な方法がないから仕方がない。

karma.conf.js

var webpack = require('webpack');
const webpackConfig = require("./config/webpack/test.js")

module.exports = function (config) {
  config.set({
    webpack: webpackConfig,

    webpackMiddleware: {
      noInfo: true,
    },

    basePath: ".",

    browsers: ["ChromeHeadless"],

    frameworks: ["qunit"],

    files: ["app/javascript/test/index_test.js"],

    exclude: [],

    preprocessors: {
      "app/javascript/test/index_test.js": ["webpack", "sourcemap"],
    },

    reporters: ["progress"],

    autoWatch: false,

    singleRun: true,
  })
}

config/webpack/test.js

process.env.NODE_ENV = process.env.NODE_ENV || 'development'

const environment = require('./environment')
const config = environment.toWebpackConfig();
config.devtool = 'inline-source-map'

module.exports = config

app/javascript/test/index_test.js

const testsContext = require.context('.', true, /\.ts$/);

testsContext.keys().forEach(testsContext);