@toloka-platform/sdk/testing exports runCodeNode, typed Vitest test helpers, and expect. Use them to test authored nodes and connected pipeline flows before applying changes.
Import this entry point from Vitest test files. It sets up Vitest fixtures, so importing it from a plain Bun script fails.
Install test tools
Start with Bun and the SDK, then install project test dependencies:python3. Task UI tests require network access to the hosted labeling-interface launcher as well as the local Chromium download. They use no platform credentials and create no platform project. Use synthetic or redacted test data because the launcher executes with access to the data you supply.
For a new project, save this as tsconfig.json:
tsconfig.json
Test a Code node
Create a node that trims whitespace withcode(), then assemble the pipeline with definePipeline():
pipelines/normalize/pipeline.ts
test.code. Use test.pipeline to test a flow, writing each step yourself: it does not execute graph connections. Call runCode for each Code node, or renderUi and submit for a labeling interface. Supply the input state, merge the declared outputs into that state, choose the branch to follow, and assert the completed fields. Use a representative local row, redacted when needed, and add separate scenarios for branches and failures.
This pipeline has one Code node, so its flow test makes one runCode call:
pipelines/normalize/pipeline.spec.ts
run(inputs, options?) calls runCodeNode(node, inputs, options?). The runner executes the Python node’s async main(inputs) and returns its output object as Promise<Record<string, unknown>>.
The runner inherits the process environment, adds authored static environment values, then applies
env overrides. It does not fetch project secrets. Imports must be available to that Python executable; local package availability does not establish platform support. See the Code node runtime.
Call runCodeNode directly for ordinary Vitest tests, including failure assertions. These tests supplement the typed node test:
pipelines/normalize/errors.spec.ts
Test a labeling interface
Task UI is the testing API for a node’s labeling interface. Save this minimalgeneration() fixture as pipelines/label/pipeline.ts. It exercises the interface locally; configure audience, pricing, quality, and onboarding using the Generation node reference before applying it for labeling work.
pipelines/label/pipeline.ts
.ui.spec.ts file beside the pipeline. A test.ui callback receives a render helper bound to its node:
pipelines/label/pipeline.ui.spec.ts
render({ data }) to supply input values. Each session gets a fresh browser context and page, with automatic cleanup after the test. One Chromium process is shared per Vitest worker.
Submission data can include echoed inputs; assert the output fields you need.
preprocess and postprocess contain JavaScript function bodies, not TypeScript. Only data is in scope there; CONST is available in ui.code only. Use componentDocumentation when a component’s value is structured or array-valued, then test that shape through setValue, getValue, and submit.
For an ordinary Vitest test, the ui fixture provides ui.render(pipeline, node, options?). ui is a callback fixture, not an export. Plain tests can inspect components or assert invalid submissions, but they do not satisfy required typed node coverage.
Errors and hardware coverage
Hardware-backed components such as file pickers and cameras make
task.coverage.complete false. By default, submit() rejects. To test only the available paths, pass allowPartialCoverage: true to render, inject values matching the component contract, and assert the resulting mapping. Hardware-backed output paths are excluded from entity validation. This does not verify capture, upload, or recording constraints; exercise them on a real device.
Run the local gate
Run the CLI from the project root:
Pass
{ timeout: milliseconds } after the callback to change the test timeout. The code runner’s timeoutMs remains a separate limit.
missing, failed, and infrastructure_error results block the gate. Hardware partial coverage is reported without blocking. toloka apply reruns the gate before resolving credentials or writing platform state. Platform node checks remain separate from these local tests.