Who this is for. Anyone about to publish a job. Afterwards you can run a new job end to end without writing to a customer, a partner or production data, and you know which jobs need a staged first run.

The procedure

  1. Build it on a development site. Point HTTP requests at the partner's sandbox or at a request-capture service, through site data, so the production values never enter the development site. Mail from a non-production environment is redirected (Testing email safely).
  2. Make a test record for the job to act on: a test form, page, product or person, named so nobody mistakes it.
  3. Narrow the trigger to it. An entity event trigger has a Record field (and a parent field, such as the form a submission belongs to): set it to the test record while you work.
  4. Put a guard first. A template condition at the top that carries on only for the test record, or for an email address you control, keeps a published job harmless while you iterate. Remove it, or widen it, last.
  5. Disable a dangerous step. Unpublish a top-level action and the run skips it, with a skipped row in the log. Alternatively swap a delete or an outbound write for a Render Template that prints what would have been sent, and read it in the run.
  6. Run it on purpose with the buttons below, read the run (Reading a job run), fix, repeat.
  7. Run it twice with the same input and compare: the second run must change nothing (the idempotency test).

Unpublishing works only for actions at the top level of the job. An action inside a condition branch or a loop runs whatever its published state, so move it out, or put the guard condition around it.

Running a job from the admin

ButtonWhat it doesWatch for
Run with recordRuns the job's entity event trigger for an entity, method and record id you choose, without editing the recordIt ignores the trigger's Record and parent narrowing, and there is no snapshot of earlier values, so getPreEventData() is empty: a condition that compares before and after sees every field as previously empty
Run jobRuns the job with no data, as a scheduled run wouldThe run has no event at all, so test scheduled jobs that way only
Run as web requestSends a request to one of the job's web events, with a method, path parameters, query parameters, body, headers and content type you setThe run is queued in the background: read its result in Batch Logs

Each run is an ordinary run, with its own entry in Batch Logs. The same runs can be started through the API with POST /cdna-api/hooks/hook/{id}/run (reference).

What cannot be tested safely, and the staged first run

Some jobs cannot be proven on production with test data: bulk deletes, a loop over every record, anything that emails customers or charges them, anything that writes to a partner without a sandbox. For those, go in stages:

  1. Run it on a recent copy of the production data on a development site (Refreshing a development copy), with mail redirected.
  2. On production, narrow the trigger or the selection to one record you own, and run it once.
  3. Widen it to a small batch: a limit of 10 on the Retrieve Records, or a condition on a category.
  4. Widen it to everything, with Batch persistence at Always for the first week, and read the runs every day.