
Когда вы пишете модульный тест для компонента Canvas, вы всегда обнаруживаете, что издеваетесь над собственным DOM и его функциями, чтобы заставить его работать с контекстом Node.js. И интересно, есть ли более простой способ, оказывается есть.
Недавно я начал исследовать, как проводить модульное тестирование компонента Canvas, потому что мне нужно протестировать игровой проект pixi.js.
Обычно есть некоторый аргумент, что вы не проводите модульное тестирование чего-либо, относящегося к элементу DOM, как только вы измените элемент, вероятно, тест всегда будет терпеть неудачу.
Однако с тех пор, как появились более мощные инструменты модульного тестирования, существует множество сред модульного тестирования, предоставляющих моментальные снимки или неглубокий рендеринг, чтобы обойти болевые точки разработчика в интерфейсе тестирования. Но для элемента canvas DOM я обнаружил, что их не так много.
Реальный рендеринг важен
Для приложения веб-игры результат рендеринга Canvas — это самое главное. Мне нужно готовое решение наподобие Jest framework, и после попытки использовать Jest для тестирования приложения pixi.js, имитации компонента и просто тестирования данных вместо рендеринга, я решил написать свой собственный инструмент:
Canvest, среда модульного тестирования для компонента Canvas.
Использование Canvest для модульного тестирования компонента Canvas
Сначала установите его с помощью npm:
$ npm i @canvest/canvest-cli --save-dev
Создайте скрипт в вашем package.json:
"scripts": {
...
"test": "canvest",
...
},
После добавления скрипта давайте просто создадим файл test.canvest.js в папке canvest.

Давайте напишем что-нибудь в:
describe('Test', function () {
it('should pass', function() {
var a = 1;
var b = 2;
expect(a + 1).to.equal(b);
});
});
После того, как вы запустили npm test , canvest-cli запустится и откроет веб-страницу, чтобы показать вам все результаты модульного теста, которые находятся в папке canvest, если имена файлов соответствуют шаблону *.canvest.(js|ts).

На данный момент это похоже на Mocha, который выполняет простую логику JavaScript. Давайте создадим настоящее приложение pixi.js, вот мой пример, показывающий логотип дракона:



Написание модульных тестов Canvest
Давайте создадим тестовый файл canvest dragon.canvest.js в папке /canvest.

Здесь я пишу модульный тест, который сначала создает приложение pixi.js и устанавливает для конфигурации preserveDrawingBuffer значение true как pixi.js с использованием контекста WebGL2, без этого моментальный снимок canvest будет черным изображением, поскольку WebGL отобразит его и очистит Холст перед тем, как сделать снимок.
После добавления логотипа дракона на сцену я вызываю функцию update, чтобы повернуть логотип на 0.0 и сделать снимок с помощью функции snapshot.
Затем я вызвал функцию update, чтобы повернуть логотип на 0.1 , сделать второй снимок и сравнить первый с этим вторым, чтобы исключить их равенство, что точно не удастся.

Как только я изменил renderNo1.isEqual(renderNo2) на notEqual , тест прошел.

Использование автоматического сравнения Canvest
Теперь я обнаружил, что на самом деле просто хочу проверить, что мой компонент логотипа всегда отображает поворот одинаково, когда он равен 1.5 , а не сравнивать рендеринг во время выполнения. Итак, я создаю функцию autoShot, просто передаю ей имя и Canvas DOM, она сохранит снимок в виде файла на локальном диске:

При вызове autoShot Canvest создаст снимок в папке canvest/autoShot:

После кэширования снимка я просто изменил реализацию функции update внутри класса Dragon и уменьшил ее вращение еще на 0,1. Затем модульный тест не удался:


Вот как легко выполнить модульное тестирование Canvas с помощью Canvest, и вам не нужно имитировать все функции Canvas или оконных элементов DOM, которые вызывают болезненную ошибку.