Test a workflow
Write vitest tests for code steps using captured fixtures, and use cori check for static validation.
Two layers of testing
Cori workflows have two testing surfaces:
- Static validation —
cori checkvalidates the manifest, step file structure, and declared tools without executing anything. - Unit tests — vitest tests for
codesteps, using captured input/output fixtures.
cori check — static validation
cori check ./my_workflowRun this before every commit. It catches:
- Missing or malformed manifest fields
- Step files that don't export the right shape (
input,output, default step) - Declared tools or MCP servers that can't be found
- Type mismatches between step outputs and the next step's inputs
Unit testing code steps
code steps are pure functions — they're the easiest to test. Write a vitest test that calls the step's run function with a fixture input and asserts the output.
import { describe, it, expect } from 'vitest';
import step, { input, output } from '../steps/03_check_gpsr';
describe('03_check_gpsr', () => {
it('filters rows missing manufacturer', () => {
const testInput = input.parse({
rows: [
{ id: '1', name: 'Widget', manufacturer: 'ACME' },
{ id: '2', name: 'Gadget', manufacturer: '' },
{ id: '3', name: 'Doohickey' },
],
});
const result = output.parse(step.run({ input: testInput }));
expect(result.valid_rows).toHaveLength(1);
expect(result.valid_rows[0].id).toBe('1');
expect(result.issues).toHaveLength(2);
});
});Run tests from inside the workflow directory:
cd ./my_workflow
npx vitest tests/Why cli and mcp_tool steps usually don't need unit tests
cli and mcp_tool steps are thin wrappers around external tools. Their behavior is the external tool's responsibility. Testing them would be integration-testing the tool, not the step.
Focus unit tests on code steps, where your logic lives. For llm steps, unit testing the prompt is rarely valuable — test the output parsing/schema validation instead.
Captured fixtures (real inputs and outputs from a conversation) are better test inputs than invented ones. When an agent authors a workflow, it can generate test fixtures directly from the conversation artifacts.
Suggested test structure
my_workflow/
tests/
03_check_gpsr.test.ts # test for each code step
fixtures/
03_check_gpsr_input.json # captured real input
03_check_gpsr_output.json # expected outputLoad fixtures in tests:
import fixture from './fixtures/03_check_gpsr_input.json';
const testInput = input.parse(fixture);