VideoFlowcodeGitHubTry itCoreRenderersReact Video EditorPlaygroundExamplesDocscodeGitHubTry it
← Back to Blog

Unit Testing Your Video: How to Assert on Motion and Timing with VideoFlow

July 8, 2026 · By VideoFlowLearn how to apply unit testing to your video automation. Discover how to use VideoFlow and VideoJSON to assert on timing, motion, and assets in your CI/CD pipeline.Unit Testing Your Video: How to Assert on Motion and Timing with VideoFlow

Unit Testing Your Video: How to Assert on Motion and Timing with VideoFlow

If you've ever shipped a video automation pipeline only to find out a week later that your title cards were overlapping or the background music was cut short, you know the pain of "silent failures." In traditional video editing, you "eyeball" the result. But when you are generating thousands of videos programmatically, manual review is impossible.

The solution isn't more eyes; it's better code. Because VideoFlow treats video as data, you can apply the same unit testing rigour to your motion graphics that you apply to your database schemas.

Why Unit Testing Video Matters

Video automation is often part of a larger business logic. Perhaps you are generating a "Year in Review" for a SaaS user, or a personalized ad for an e-commerce customer. If the startTime of a layer is calculated incorrectly based on dynamic data, your video might look broken, or worse, convey the wrong information.

By unit testing your video logic, you ensure that timing is precise, assets exist, and motion is smooth. This approach catches errors in your builder functions before they ever reach the renderer.

Magnifying glass inspecting a JSON tree representing a video layer

Step 1: Asserting on the Compiled VideoJSON

The core of VideoFlow is the VideoJSON schema. When you call $.compile(), you get a portable, serializable representation of your video. This is your primary assertion target. Instead of rendering an MP4 and trying to "see" if it's right, you can inspect the JSON structure directly using standard testing libraries like Vitest or Jest.

import VideoFlow from '@videoflow/core';
import { expect, test } from 'vitest';

test('title card should appear for exactly 3 seconds', async () => {
  const $ = new VideoFlow();
  const title = $.addText({ text: 'Hello World' });
  
  title.fadeIn('500ms');
  $.wait('2s');
  title.fadeOut('500ms');

  const json = await $.compile();
  const titleLayer = json.layers.find(l => l.type === 'text');

  // Assert on the timing settings
  expect(titleLayer.settings.startTime).toBe(0);
  expect(titleLayer.settings.endTime).toBe(3); // 0.5s + 2s + 0.5s
});

Step 2: Validating Keyframes and Animations

One of the most powerful features of the VideoFlow builder API is the ability to animate any property. But complex animations often involve math that can go wrong. You can verify that your animations have the correct number of keyframes and that they target the right properties.

test('background image should blur over 5 seconds', async () => {
  const $ = new VideoFlow();
  const bg = $.addImage({ filterBlur: 0 }, { source: 'bg.jpg' });
  
  bg.animate(
    { filterBlur: 0 },
    { filterBlur: 10 },
    { duration: '5s' }
  );

  const json = await $.compile();
  const bgLayer = json.layers.find(l => l.type === 'image');
  const blurAnim = bgLayer.properties.animations.find(a => a.property === 'filterBlur');

  expect(blurAnim.keyframes).toHaveLength(2);
  expect(blurAnim.keyframes[1].time).toBe(5);
  expect(blurAnim.keyframes[1].value).toBe(10);
});

Step 3: Headless Verification with @videoflow/renderer-server

Sometimes, you need to go beyond the JSON and verify that the media itself is behaving. You can use @videoflow/renderer-server to perform sanity checks on specific frames. For example, you can assert that a renderer can successfully load all assets in a project before committing to a long render job.

import ServerRenderer from '@videoflow/renderer-server';

test('all assets should be reachable', async () => {
  const $ = new VideoFlow();
  $.addImage({}, { source: 'https://example.com/missing.jpg' });
  const json = await $.compile();

  const renderer = new ServerRenderer(json);
  // This will throw if the asset cannot be fetched or decoded
  await expect(renderer.renderFrame(0)).rejects.toThrow();
  await renderer.cleanup();
});

CI/CD pipeline for video verification

Integrating Video Tests into CI/CD

Just like your Git-Flow for Video allows you to version-control your creative assets, a CI/CD integration allows you to block "broken" videos from ever reaching production.

In your GitHub Actions or GitLab CI pipeline, you can run your test suite as a pre-render step. Rendering a 1080p video might take minutes and cost compute dollars; running a $.compile() assertion takes milliseconds and costs practically nothing. This ensures that a developer changing a shared branding component doesn't accidentally break the text alignment or timing across thousands of videos.

Conclusion

Treating video as code opens up a world of engineering best practices that were previously locked behind proprietary GUI tools. By asserting on your VideoJSON, you can ship automation pipelines with the confidence that every frame is exactly where it should be.

Ready to start building? Head over to the VideoFlow Playground to experiment with the API in real-time, or check out the official documentation to learn more about advanced composition. For the full source and to contribute to the engine, visit the VideoFlow GitHub repository.

VideoFlow

Open-source toolkit for composing videos from code.

Product

CoreRenderersReact Video EditorPlayground

Learn

DocsAPI referenceExamplesvs. Remotionvs. FFmpeg

Project

GitHubLicenseContactTermsPrivacy

From the blog

All posts →Generating Multi-Language Video at Scale: The Localization PlaybookBrowser-Side Video Export: Zero-Server Rendering with WebCodecsHow to Build a Dynamic Video Editor in React in 10 MinutesHow to Build a Video Rendering API in Node.js (Without FFmpeg)Cinematic GLSL: Stacking Effects for a Retro VHS Look in VideoFlowCinematic Text: Mastering Typography and Text Effects in VideoFlowHow to Generate Personalized Video Ads from a CSV with TypeScriptThe Git-Flow for Video: Why Your MP4s Should Be Diffable JSON
© 2026 VideoFlow. Apache-2.0 core.