8
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Jest + jsdomでCanvas要素を単体テストする

Last updated at Posted at 2021-06-09

はじめに

この記事は、Jest(jsdom)でContext2Dインターフェイスを利用するCanvas要素の単体テスト方法を記録、共有するためのものです。

想定する読者

この記事は、以下の読者を想定して書かれています。

  • JavaScriptの開発経験がある
  • Jestを使ったことがある

JavaScriptの解説やJestのインストールガイドはこの記事には含まれません。

想定する環境

この記事は、以下の環境を想定して書かれています。記事を読む前に、お手元の環境をご確認ください。

$ node --version
v16.3.0
$ npm --version
7.15.1

また、この記事で扱うパッケージは以下の通りです。

▼package.json

"devDependencies": {
  "canvas": "^2.8.0",
  "jest": "^27.0.4",
  "pixi.js-legacy": "^6.0.4",
}

WebGLの単体テストは想定していません。WebGLコンテンツをテストしたい場合、Puppeteerの導入を検討してください。

参考記事 : JestでPuppeteerを動かしてCIで実行する

先に結論だけ

JestでCanvas要素をテストする最小限のリポジトリを作りました。

JestとCanvas

Jestは、ブラウザ環境を想定したテストのためにjsdomを内包しています。jsdomとはDOMをJavaScriptで実装したものです。Pure JavaScriptで実装されているため、node.js上で動作します。jsdomを通じて、ユーザーはテストに必要なDOMを組み立てて操作します。

jsdomのCanvasサポート

jsdomはテストやスクレイピングを目的としています。そのためjsdom単体ではCanvas要素をサポートしていません。Canvas要素をDOMツリーに追加しようとすると、jsdomはdiv要素を代わりに挿入し、処理を簡略化します。

jsdomでCanvas要素をサポートする場合、node-canvasを追加します。

jsdom README : Canvas support

jsdom includes support for using the canvas package to extend any canvas elements with the canvas API. To make this work, you need to include canvas as a dependency in your project, as a peer of jsdom.
jsdomには、canvasパッケージを使用して任意の canvas 要素をcanvas APIで拡張するためのサポートが含まれています。これを動作させるには、jsdom のピアとして、プロジェクトに canvas を依存関係として含める必要があります。

jsdomはnode-canvasがパッケージ内にインストールされていることを自動で認識します。ユーザーがなにか設定する必要はありません。node-canvasがインストールされている場合、JestはCanvasに関わる処理をnode-canvasに渡します。

Canvasのテスト

それでは実際にCanvasをテストしてみます。今回はCanvas描画ライブラリとしてPixiJSの2Dコンテキスト対応版pixi.js-legacyを使います。

モジュールのインストール

プロジェクトにJestとnode-canvas、pixi.js-legacyをインストールします。

npm install --save-dev jest canvas pixi.js-legacy
npm v7以降の場合

npm v7から、peerDependenciesに指定されたモジュールが自動的にインストールされるようになりました。jsdomはpeerDependenciesにnode-canvasを指定しています。そのため、node-canvasを個別にインストールする必要はありません。

テストの作成

テストファイルを作成します。

▼./__test__/Test.spec.ts

jest.spyOn(console, "error").mockImplementation()

describe("Test", () => {
    const PIXI = require("pixi.js-legacy");
    jest.spyOn(console, "log").mockImplementation((x) => x);

    const app = new PIXI.Application({
        width: 640,
        height: 480,
        forceCanvas: true,
    });
    document.body.appendChild(app.view);

    test("app should be exist", () => {
        expect(app).toBeTruthy();
    })
})

テスト環境を指定して実行

Jestの設定ファイルを作成し、環境にjsdomを指定します。

▼jest.config.js

module.exports = {
  testEnvironment: "jsdom",
};

もしくは、jestコマンドに--env=jsdomオプションを追加します。

▼package.json

"scripts": {
  "test": "jest --env=jsdom"
}

テスト結果

> minimal-test-environment-jest-pixijs@0.1.0 test
> jest --env=jsdom

 PASS  __test__/Test.spec.js
  Test
    ✓ app should be exist (2 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        1.393 s
Ran all test suites.

プロセスは終了コード 0 で終了しました

テストがパスすれば成功です。

GitHub Actions

node-canvasはGitHub Actions上でも動作します。ubuntu-latest上でaptコマンドを使ってパッケージを追加するなどの作業は必要ありません。

たとえばnode.js用のテンプレートを使えば、そのままテストがGithub Actions上で動作します。

以上、ありがとうございました。

8
2
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
8
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?