GitHub Actionsでthree.jsの単体テスト
はじめに
この記事は、GitHub Actions上でthree.jsの単体テスト方法を記録、共有するためのものです。
node.jsでWebGLを利用したコードを単体テストし、GitHub Actions上で処理します。ヘッドレスブラウザやelectronは使用しません。
想定する読者
この記事は、以下の読者を想定して書かれています。
- JavaScriptの開発経験がある
- Jestを使ったことがある
- three.jsを使ったことがある
- リポジトリをGitHubで管理している / 管理したい
JavaScriptの解説やJestのインストールガイドはこの記事には含まれません。
想定する環境
この記事は、以下の環境を想定して書かれています。記事を読む前に、お手元の環境をご確認ください。
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [12.x, 14.x, 16.x]
GitHub Actions上の仮想環境はubuntu-latest、node.jsのバージョンは12から16までを想定しています。
また、テスティングフレームワークはJestを利用します。
"devDependencies": {
"jest": "^27.0.4",
}
先に結論だけ
GitHub Actionsでthree.jsを単体テストする最小限のリポジトリを作りました。
WebGLを利用した単体テスト
Jestはnode.jsで稼働するJavaScriptテスティングフレームワークです。Jestにはjsdomという、JavaScriptで記述されたDOM実装が含まれています。このjsdomを使ってCanvasを作成し、WebGLを利用するコードをテストします。
Jestでjsdomを利用する
Jestでjsdomを利用するには、設定ファイルを作成し環境にjsdom
を指定します。
▼jest.config.js
module.exports = {
testEnvironment: "jsdom",
};
もしくは、jestコマンドに--env=jsdom
オプションを追加します。
▼package.json
"scripts": {
"test": "jest --env=jsdom"
}
課題
jsdomは軽量化のため、標準設定ではCanvas要素をdiv要素で代用します。そのため、CanvasRenderingContext2DやWebGLRenderingContextはテストで使えません。
- Canvas要素のサポート
- WebGLRenderingContextのサポート
jsdomでWebGLをテストするためには、この2つの課題を解決しなければなりません。
Canvas要素のサポート
jsdomでCanvas要素をサポートするために、node-canvasを利用します。
npm install canvas --save-dev
jsdomはnode-canvas
のインストールを自動で検知します。ユーザーがなにか設定をする必要はありません。
const canvas = document.createElement("canvas");
テストコード上でdocument.createElementを呼び出すと、node-canvas
からCanvas要素が返されます。
WebGLRenderingContextのサポート
jsdomでWebGLRenderingContextをサポートするために、headless-glを利用します。headless-glはnode.js上でWebGLRenderingContextを作成するモジュールです。
npm install gl --save-dev
テストコードでは、以下のようにWebGLRenderingContextを生成します。
const gl = require('gl')(width, height)
width, heightには好きなサイズを指定できますが、THREE.WebGLRendererのsetSize関数で変更されてしまうため、最小限のサイズを指定します。
const gl = require('gl')(1, 1)
テストコードの作成
node-canvas
とheadless-gl
を使ってテストを作成します。
▼./__test__/Test.spec.js
const THREE = require("three");
jest.spyOn(console, "error").mockImplementation()
describe("Test", () => {
const canvas = document.createElement("canvas");
test("2d context should be exist", () => {
const context = canvas.getContext("2d");
expect(context).toBeTruthy();
})
test("generate webgl context", ()=>{
const gl = require("gl")(1,1);
expect(gl).toBeTruthy();
})
test("generate webgl renderer", ()=>{
const gl = require("gl")(1,1);
const renderer = new THREE.WebGLRenderer({context:gl, canvas:canvas});
renderer.setSize(640, 480);
expect(renderer.getContext()).toBeTruthy();
expect(renderer.getContext()).toBe(gl);
expect(renderer.domElement.width).toBe(640);
})
})
このテストで、以下の課題2点が確認できました。
- Canvas要素のサポート
- WebGLコンテキストのサポート
また、CanvasとWebGLコンテキストを利用してWebGLRendererが生成できました。
GitHub Actionsで実行する
ここまでで作成したテストはそのままではGitHub Actionsで動作しません。GitHub Actionsの仮想環境ubuntu-latest
には、headless-glが依存するいくつかのパッケージが含まれていないためです。
解決方法1 : macos-latestかwindows-latestを使う
この問題のもっとも簡単な解決方法は、仮想環境のmacos-latest
かwindows-latest
への変更です。この2つの仮想環境は、headless-glの動作に必要なパッケージをすべて含んでいます。
jobs:
build:
runs-on: macos-latest
ただしmacos-latest
とwindows-latest
はLinuxにくらべ、それぞれ2倍と10倍のコストがかかります。
公式ドキュメント : GitHub Actionsの支払いについて
パブリックリポジトリでは、GitHub Actionsの費用は利用者に請求されません。しかしサーバー資源の浪費は避けるべきです。
解決方法2 : 動作に必要なパッケージをインストールする
GitHub Actionsのstepsでは、sudoコマンドが使えます。必要なパッケージをインストールすれば、ubuntu-latest
でheadless-glが動作します。
headless-glに必要なパッケージは以下の通りです。
- libxi-dev
- xvfb
- libgl1-mesa-dev
このパッケージをインストールし、テスト実行前に仮想フレームバッファーXvfb
を起動します。
steps:
- uses: actions/checkout@v2
# ここでパッケージをインストール
- name: install apt packages for headless-gl
run: sudo apt-get install libxi-dev xvfb libgl1-mesa-dev
# ...中略...
# npm testの実行直前に xvfb-run --auto-servernum で仮想フレームバッファーXvfbを起動
- run: xvfb-run --auto-servernum npm test
参考 : Usage on GitHub Actions with xvfb
これでheadless-glが動作します。
参考記事
以上、ありがとうございました。
Author And Source
この問題について(GitHub Actionsでthree.jsの単体テスト), 我々は、より多くの情報をここで見つけました https://qiita.com/masato_makino/items/20200a32d574fe82c633著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .