workflow-tester
v0.2.0
Published
Contract-driven tests for n8n workflows: generate the payload variants a trigger can receive and check every expression against them, offline
Maintainers
Readme
workflow-tester
Find the payloads that break your n8n workflow before someone sends them. When a webhook arrives with a field set to null or an optional object missing, n8n turns the broken expression into undefined and shows no error. workflow-tester runs your workflow's expressions against those payloads and tells you which ones break and where. It runs offline, with no n8n instance.

Installation
Requires Node.js 24 or newer.
Run it without installing:
npx workflow-tester --helpAdd it to a project:
npm install --save-dev workflow-testerBuild from source:
git clone https://github.com/LudwigGerdes/workflow-tester.git
cd workflow-tester
pnpm install && pnpm buildGetting started
Set up a project:
npx workflow-tester initThis creates:
.workflow-tester/
├── README.md
└── tests/
└── example.test.yamlDownload a sample sign-up workflow and a test file with three cases, then run them:
curl -L --create-dirs -o workflows/signup.json https://raw.githubusercontent.com/LudwigGerdes/workflow-tester/main/docs/demo/signup.json
curl -L -o .workflow-tester/tests/signup.test.yaml https://raw.githubusercontent.com/LudwigGerdes/workflow-tester/main/docs/demo/signup.test.yaml
npx workflow-tester runExpected output:
workflows/signup.json
✗ no profile object, flat name — the ?? gotcha 1 expectation(s) fail
✗ node.Normalize.output[0].json.name: expected "Bob", got undefined
! "profile" is not produced here at Normalize → assignments.assignments[1].value
! "plan" is not produced here at Normalize → assignments.assignments[2].value
! no email at all every expectation held
! "email" is not produced here at Normalize → assignments.assignments[0].value
! "profile" is not produced here at Normalize → assignments.assignments[1].value
! "plan" is not produced here at Normalize → assignments.assignments[2].value
! "email" is not produced here at Normalize → assignments.assignments[3].value
✓ pro user with nested profile
1 passed, 1 failed, 1 warned in 354msThe first case fails because the workflow reads $json.body.profile.first_name when there is no profile.
Usage
Write a test by hand, in .workflow-tester/tests/:
workflow: ../../workflows/signup.json
cases:
- id: flat-name
when:
trigger: webhook
payload:
email: [email protected]
name: Bob
then:
node.Normalize.output[0].json.name: BobRun every test:
workflow-tester runGenerate tests from the payloads GitHub or Stripe can send:
workflow-tester contracts add workflows/issue-triage.json --vendor github --events issues-opened
workflow-tester gen
workflow-tester run --only generatedTurn a run you already made in n8n into a test:
workflow-tester capture workflows/invoice.json --execution execution.jsonReport in a format your CI understands:
workflow-tester run --format junitDocumentation
Full documentation is at workflowtools.dev/workflow-tester:
- Command line
- Writing tests
- Generating tests from GitHub and Stripe payloads
- Capturing real runs
- Pre-commit and CI
- FAQ and compatibility
License
MIT © Ludwig Gerdes
Bundled n8n node descriptions and the GitHub and Stripe payload catalogues are covered by THIRD_PARTY_NOTICES.md. Not affiliated with n8n GmbH, GitHub or Stripe.
