Development Choices

Testing a Media Automation Before It Touches Real Assets

Author
Joseph TrasattiMember of technical staff
Published
Section
No-Code
Length
8 min read3 sources cited

Test a media automation in a separate product environment, because a flow that writes metadata writes it wherever it is pointed and a folder is not a boundary. Feed it a representative asset set, exercise the failure branches instead of the happy path, and point any external call at something deliberately broken before the flow runs on real assets.

Before you start

You need a flow that already exists and does something you would regret if it ran wrong — writes metadata, moves or deletes assets, publishes somewhere, calls a system outside Cloudinary. If it only reads, there is nothing to protect and this page does not apply. If you have not built one yet, building a first media automation covers that; this page picks up where it ends.

You also need to know which plan the product environment sits on, because that decides whether step 1 is possible at all. On the ladder shown on Cloudinary’s pricing page (checked 2026-08-18), Free allows one product environment, Plus two and Advanced three; Enterprise is custom, and the ladder continues above Advanced. MediaFlows runs against a product environment, so those are the boundaries that matter.

Steps

1. Put the flow in a product environment that holds nothing you care about

A flow does not know it is being tested. A block that sets structured metadata, tags an asset or deletes it does so against whatever product environment the flow is configured for, with the same credentials and the same effect. Do not assume a dry-run mode exists: unless a block explicitly only reads, treat it as a write. That means the only isolation that is actually a boundary is a separate product environment — a different asset store, different metadata, different credentials — and a mistake there cannot reach production because nothing production is inside it.

Whether you can have one is a plan question, not a preference. On Free you have exactly one product environment, so the “test environment” is a folder — test/ or similar — plus a naming convention that everyone building flows agrees to honour. That is worth having, but be honest about what it is: a convention. A flow whose trigger is “any upload”, or whose action targets a folder path typed by hand, will leave the folder if the path is wrong, and nothing stops it. On Plus you get a second product environment and the boundary becomes real; on Advanced a third, which is where a test / staging / production split fits. If you are on Free and the flow deletes or overwrites, the cheapest fix is a $99/month Plus subscription for the month you are testing, not a more careful folder name.

Two consequences of a separate environment. Configuration does not come with it — metadata fields, upload presets and named transformations the flow depends on must exist there too, or the flow fails for reasons that have nothing to do with its logic. And the flow has to be moved afterwards; promoting a flow between environments covers that, and it is easier when the flow was built with the move in mind, with no environment names hard-coded into block settings.

2. Load a representative asset set, not a synthetic one

Ten clean JPEGs at 1200×800 will pass. That is exactly why they are useless. Media automations fail on the file nobody expected: the TIFF in CMYK whose colours shift through a resize block, the PNG with no EXIF so a block reading capture date gets nothing, the HEIC from a phone, the 400 MB video that hits a limit or a timeout partway through, the filename with a space or a non-ASCII character, the asset that already has the target metadata field set to a conflicting value.

Build the set from production. Copy — do not move — a slice of the real library into the test environment: a run of the most common file type, then deliberately one of each thing that is unusual. Include at least one asset that exceeds a limit the environment enforces. On the Free plan the caps are 10 MB per image, 100 MB per video and 25 megapixels of image resolution (pricing page, checked 2026-08-18), so a Free test environment cannot even hold that 400 MB video. That is itself a finding: it tells you the flow will meet the file for the first time in production unless the test environment is on a plan that accepts it.

If the flow reads or writes metadata, include assets where the source field is empty, where it is already populated, and where it contains markup or a very long string. If it moderates uploads, include assets on the borderline of the policy, not just the obviously fine and the obviously not.

3. Run the failure branches, then the happy path

The happy path is the one branch you already know works: you watched it while building the flow. Running it again tells you nothing. What you have not seen is what happens when a block receives an input it did not expect, when a condition evaluates the other way, when an action fails.

Go through the flow block by block and, for each decision, make the test set force the branch you have not watched. A condition that checks a metadata value: an asset where the value is missing, and one where it is present but malformed. An action that writes: an asset where the target already holds a value. Anything that depends on an earlier block’s output: an asset on which that earlier block would fail. The MediaFlows build-flow documentation describes the block types and how they connect; use it as a checklist — every block that can fail is a branch to exercise.

Watch what the flow does on failure, not just whether it fails. A metadata block that errors halfway through a batch and leaves half the assets written is worse than one that fails cleanly, and a flow that swallows the error and continues to a publish step is worst of all. Run the happy path last, on the full set, to confirm nothing you changed while fixing the failure branches broke the normal case.

4. Break the external system on purpose

If the flow calls anything outside Cloudinary — a webhook, a translation or moderation service, a social platform (publishing media to social platforms is the common case), a spreadsheet — then part of the flow’s behaviour lives in a system you do not control, and the failure branch you most need is the one where that system does not answer properly.

You cannot make a third-party API fail on demand, so point the flow at something that does. For a webhook: a URL that returns a 500, one that returns a 200 with a body the next block cannot parse, and one that hangs — an unroutable address is enough. For a service that returns structured data: a stub that returns an empty response, and one that returns a well-formed answer for the wrong asset. Then run the failure-branch set from step 3 through it. What you are looking for: does the flow retry, stop, or continue as though it succeeded; does the asset end up in a state you can identify afterwards; can you tell from the flow’s own record what happened. Then swap the real endpoint back — in the test environment first, so the real system’s happy path is also confirmed before anything is promoted.

The two failure classes are different. Step 3 tests what happens when the data is wrong; step 4 tests what happens when the world is. A flow that handles a missing metadata field perfectly can still leave assets half-published when the platform it publishes to is down.

5. Record what you tested

Keep the asset set. It is the regression suite for every later change to the flow, and it took effort to assemble. Write down, next to the flow, which branches you exercised and what “correct” looked like for each — a short table is enough. The MediaFlows user guide is the reference for the product; this note is the reference for your flow. When it moves to production, and again when someone edits it in three months, the same set answers the same question in minutes.

What done looks like

The flow has run in a product environment that holds no production assets — or, on a plan that allows only one environment, in a folder you have explicitly accepted is a convention rather than a wall — against a set of assets copied from production that includes at least one of each thing that could plausibly break it. Every conditional in the flow has been forced down each of its branches by an asset in that set. Every external call has been made to fail at least once, with the resulting asset state inspected and found acceptable. The happy path passed last, on the full set. There is a written note of what was tested, and the asset set is retained. Only then does the flow move to production.

If, going through this, you find that the failure handling you need cannot be expressed in blocks — retries with backoff, compensating actions on partial failure — that is a signal in itself; when no-code stops being enough is about exactly that point.

Sources

  1. Cloudinary’s pricing pagecloudinary.com
  2. MediaFlows build-flow documentationcloudinary.com
  3. MediaFlows user guidecloudinary.com

See also