Karma でのスナップショットテスト用 Chai プラグイン

スナップショットのシリアライズ

このプラグインは シリアライズモジュール と同じものを使用しており、Jest ライブラリでも使用されています。

スナップショットのフォーマット

スナップショットはさまざまなフォーマットで保存できます。現時点でサポートされているフォーマットは 2 つあります。mdindented-md です。

Markdown フォーマット

このフォーマットは、アサーションプラグイン内でコードブロックの言語を指定する場合に推奨されています。このフォーマットを使用すると、コードエディターがコードブロックの構文を自動的にハイライトします。

# `src/html.js`

## `Sub Suite`

####   `HTML Snapshot`

```html
<div>
  <span />
</div>
```

インデント付き Markdown フォーマット

# `src/html.js`

## `Sub Suite`

####   `HTML Snapshot`

    <div>
      <span />
    </div>

スナップショットのファイルパス

スナップショットのファイルパスはルートスーツケースの名前に基づいて抽出され、__snapshots__ ディレクトリ内のテスト対象ファイルと一緒に保存されます。

スナップショットのファイルパスは、カスタム pathResolver をスナップショット設定で指定することで変更できます。

使用例

$ npm install karma karma-webpack karma-sourcemap-loader karma-snapshot karma-mocha \
              karma-mocha-snapshot karma-mocha-reporter karma-chrome-launcher mocha \
              chai chai-karma-snapshot webpack --save-dev

Karma 設定

// karma.conf.js
const webpack = require("webpack");

module.exports = function (config) {
  config.set({
    browsers: ["ChromeHeadless"],
    frameworks: ["mocha", "snapshot", "mocha-snapshot"],
    reporters: ["mocha"],
    preprocessors: {
      "**/__snapshots__/**/*.md": ["snapshot"],
      "__tests__/index.js": ["webpack", "sourcemap"]
    },
    files: [
      "**/__snapshots__/**/*.md",
      "__tests__/index.js"
    ],

    colors: true,
    autoWatch: true,

    webpack: {
      devtool: "inline-source-map",
      performance: {
        hints: false
      },
    },

    webpackMiddleware: {
      stats: "errors-only",
      noInfo: true
    },

    snapshot: {
      update: !!process.env.UPDATE,
      prune: !!process.env.PRUNE,
    },

    mochaReporter: {
      showDiff: true,
    },

    client: {
      mocha: {
        reporter: "html",
        ui: "bdd",
      }
    },
  });
};

ソースファイル

// src/index.js

export function test() {
  return "Snapshot Test";
}

テストファイル

// __tests__/index.js
import { use, expect, assert } from "chai";
import { matchSnapshot } from "chai-karma-snapshot";
import { test } from "../src/index.js";
use(matchSnapshot);

describe("src/index.js", () => {
  it("check snapshot", () => {
    // 'expect' syntax:
    expect(test()).to.matchSnapshot();
    // 'assert' syntax:
    assert.matchSnapshot(test());
  });
});

テストの実行

$ karma start

スナップショットの更新

$ UPDATE=1 karma start --single-run

スナップショットの刈り取り

$ PRUNE=1 karma start --single-run

設定

function resolve(basePath, suiteName) {
  return path.join(basePath, "__snapshots__", suiteName);
}

config.set({
  ...
  snapshot: {
    update: true,           // Run snapshot tests in UPDATE mode (default: false)
    prune: false,            // Prune snapshots for removed tests (default: true)
    format: "indented-md",  // Snapshot format (default: md)
    checkSourceFile: true,  // Checks existince of the source file associated with tests (default: false)
    pathResolver: resolve,  // Custom path resolver
  }
});

カスタムスナップショットフォーマット

スナップショットの設定オプション format はカスタムシリアライズフォーマットでも機能します。カスタムスナップショットシリアライザーは次のようなインターフェイスを持つ必要があります。

interface SnapshotSerializer {
  serialize: (name: string, suite: SnapshotSuite) => string,
  deserialize: (content: string) => { name: string, suite: SnapshotSuite },
}