Юнит-тестирование анимаций в JavaScript с использованием anime.js требует понимания, как библиотека управляет временем и состоянием объектов. Анимации в anime.js не мгновенны — они изменяют свойства объектов постепенно, поэтому тестирование должно учитывать временные промежутки и события жизненного цикла анимации.
Для начала необходимо подключить anime.js в проект.
В юнит-тестах чаще всего используется среда Jest, так
как она поддерживает мокирование времени с помощью
jest.useFakeTimers() и позволяет контролировать асинхронные
процессы:
import anime from 'animejs/lib/anime.es.js';
jest.useFakeTimers();
Мокирование таймеров критично для тестирования, так как anime.js
использует requestAnimationFrame или
setTimeout для обновления состояния анимации. Контроль
времени позволяет “прокрутить” анимацию вперед без реального
ожидания.
Основная цель юнит-теста анимации — убедиться, что свойства объекта
меняются корректно. Пример для анимации opacity
элемента:
const obj = { opacity: 0 };
const animation = anime({
targets: obj,
opacity: 1,
duration: 1000,
easing: 'linear'
});
// Начальное состояние
expect(obj.opacity).toBe(0);
// "Продвигаем" время на 500 мс
jest.advanceTimersByTime(500);
// Проверка промежуточного состояния
expect(obj.opacity).toBeCloseTo(0.5, 1);
// Завершение анимации
jest.advanceTimersByTime(500);
expect(obj.opacity).toBe(1);
Ключевой момент: toBeCloseTo необходим
для проверки чисел с плавающей точкой, так как анимации изменяют
свойства постепенно, а не дискретно.
Anime.js поддерживает события begin,
update, complete, которые можно использовать
для проверки вызовов коллбэков:
const onBe gin = jest.fn();
const onUpd ate = jest.fn();
const onCompl ete = jest.fn();
anime({
targets: obj,
opacity: 1,
duration: 1000,
easing: 'linear',
begin: onBegin,
update: onUpdate,
complete: onComplete
});
jest.advanceTimersByTime(1000);
expect(onBegin).toHaveBeenCalledTimes(1);
expect(onUpdate).toHaveBeenCalled();
expect(onComplete).toHaveBeenCalledTimes(1);
События позволяют убедиться, что анимация запускается, обновляется и завершается как ожидается.
Для сложных анимационных сценариев с последовательностью
(timeline) важно проверять каждый шаг:
const timeline = anime.timeline({ autoplay: false });
timeline
.add({
targets: obj,
x: 100,
duration: 500
})
.add({
targets: obj,
y: 200,
duration: 500
});
timeline.play();
// Проверка первого шага
jest.advanceTimersByTime(500);
expect(obj.x).toBe(100);
expect(obj.y).toBe(0);
// Проверка второго шага
jest.advanceTimersByTime(500);
expect(obj.y).toBe(200);
Тестирование timeline особенно важно, когда анимации влияют на последовательное изменение нескольких свойств или объектов.
Анимации с опцией loop или
direction: 'alternate' требуют особого внимания:
const loopAnimation = anime({
targets: obj,
x: [0, 100],
duration: 1000,
loop: 2,
easing: 'linear'
});
loopAnimation.play();
jest.advanceTimersByTime(2000);
expect(obj.x).toBe(100); // После двух циклов
Важно учитывать количество циклов и направление, чтобы корректно проверять финальное состояние.
toBeCloseTo для свойств с плавающей
точкой.Юнит-тестирование анимаций с anime.js повышает надёжность интерфейсов и позволяет автоматизировать проверку динамических эффектов без необходимости визуальной инспекции.