Building Testable Cloudflare Workers

Author: Tom Cranstoun
When we started building Cloudflare Workers, we hit a wall that every edge computing developer eventually faces: how do you test code that only runs in a proprietary runtime?

The Testing Problem

Cloudflare Worker tutorials follow a predictable pattern: write your logic inside the fetch handler, use HTMLRewriter for DOM manipulation, cross your fingers, and deploy. Testing? Set up complex mocks, spin up local Cloudflare environments, or skip it entirely.

We've seen production bugs that could have been caught in seconds with proper tests. Teams avoid refactoring because they can't verify that changes work. Debugging edge cases in production happens because local testing is too painful.

There's a better way.

Pure Functions Change Everything

The solution isn't better mocking tools or test frameworks. It's architecture.

Your core business logic doesn't need the Cloudflare runtime. Your HTML transformations, metadata extraction, and content processing can run in plain JavaScript and be tested anywhere.

The Two-File Pattern

We use a strict architectural pattern: two files only.

  1. cloudflare-worker.js - Your production worker code
  2. cloudflare-worker.test.js - Your complete test suite (83 tests)

No fragmented test files. No complex test directory structures. No "I think there's a test for that somewhere" moments. Everything you need to understand the worker's behaviour is in a single test file.

What Makes This Work

Pure Functions First

Instead of writing logic that depends on HTMLRewriter element handlers, we write pure functions that transform strings. The mindset shift:

Old way: "How do I use HTMLRewriter to replace this content?" Our way: "What string operation do I need, and how can I test it?"

Your transformations become just JavaScript. No runtime. No mocks. No ceremony.

Example: Our replacePicturePlaceholder() function takes an HTML string and returns the modified HTML as a string. Test it anywhere - your laptop, CI/CD, or even a web browser console. The Cloudflare runtime never comes into play until deployment.

Processing Order Matters

We learned this through production bugs: transformations (ADD) must happen before removals (DELETE).

Remove HTML comments too early? Your JSON-LD injection triggers disappear. Clean up metadata first? Your content transformations fail silently. These bugs are subtle and painful.

Our pattern enforces the correct order through architecture, not documentation.

Testing Without Infrastructure

Run 83 tests in seconds. No Docker containers. No Cloudflare dev environment. No port conflicts. Just:

npm test

Every pure function has multiple test cases. Edge cases are covered. Refactoring is safe.

Production Use at allabout.network

This pattern runs in production, serving real traffic with:

Content authors write metadata. The worker generates structured data. Search engines get valid schema.org objects every time.

Development Workflow

The repository includes AI-assisted development tools:

Make a change, get instant feedback, deploy with confidence.

The Numbers

Who Should Use This

Download This Repo If You:

  1. Build Cloudflare Workers and find testing complex
  2. Maintain edge computing infrastructure and need confidence in deployments
  3. Teach web development and want to show clean architecture patterns
  4. Care about maintainability more than shipping code quickly
  5. Want AI-assisted development that improves code quality
  6. Debug in production too often, and want local testing that works

What's Included

The repository contains:

The Philosophy

Testability drives good architecture.

When you force yourself to test without runtime dependencies, you write cleaner functions. When you limit yourself to one test file, you avoid over-engineering. When you must explain your code to tests, you write more apparent logic.

The constraints aren't limitations - they're guardrails that lead to better code.

Getting Started

The repository is open source and ready to use:

  1. Clone the repo from GitHub
  2. Read the tutorial at cloudflare/two-file-testing-tutorial.md
  3. Run the tests to see the pattern in action
  4. Explore the AI tools (if using Claude Code):
    • Try /check-cloudflare-tests to validate the two-file pattern
    • Use code-architecture-reviewer agent after making changes
    • Experience commit guardrails that enforce documentation updates
    • Let pre-commit hooks keep everything in sync
  5. Adapt to your needs (the pattern works for any Cloudflare Worker)

You'll find:

Why We're Sharing This

We spent too much time learning these lessons. We wrote production code the wrong way. We debugged runtime-dependent tests. We experienced the pain of untestable workers.

You don't have to.

This repository represents our learnings distilled into a reusable pattern. It's the worker architecture we wish we'd found when we started. It's the testing approach that finally made edge computing maintainable.

Download it. Use it. Build something better.

Ready to Transform Your Workers?

⭐ Star the repository: github.com/ddttom/cloudflare-worker

Quick start:

git clone https://github.com/ddttom/cloudflare-worker.git

cd cloudflare-worker/cloudflare/files

npm install

npm test

Watch 83 tests pass in seconds. No setup. No Docker. No runtime simulation. Just pure JavaScript testing.

Then explore the tutorial at cloudflare/two-file-testing-tutorial.md to understand the pattern.

Your future self - debugging production - will thank you.

Questions? Issues? Open a GitHub issue or discussion. We're here to help you build better Cloudflare Workers.

/fragments/ddt/proposition

Related Articles

Back to Top