Testing workflows and workers

July 28, 2026 · View on GitHub

Test projects

Project / directoryScope
Tests/ (conductor-csharp.test.csproj)Core SDK.
Tests/ApiUnit/Resource-API units, no server.
Tests/Definition/Workflow definition building.
Tests/Worker/Worker behaviour.
Tests/Executor/WorkflowExecutor.
Tests/Telemetry/Metrics collection.
Tests/Integration/End-to-end, against a live server.
Tests/Api/Resource APIs against a live server.
Tests/TestData/, Tests/Helper/Fixtures and helpers.
Conductor.AI.Tests/Agent unit tests.
Conductor.AI.E2eTests/Agent E2E suites, against a live server.
Conductor.AI.{OpenAI,GoogleADK,SemanticKernel}.Tests/Framework adapters.

The split that matters: unit tests need no server, integration and E2E tests do. CI runs them as separate jobs for that reason.

Unit-testing a worker

A worker is a plain class — construct a Task, call Execute, assert on the TaskResult. No server, no host:

var worker = new GreetWorker();
var task = new Task
{
    InputData = new Dictionary<string, object> { ["name"] = "Conductor" }
};

var result = worker.Execute(task);

Assert.Equal("Hello, Conductor!", result.OutputData["greeting"]);

This is the payoff of the stateless-worker design principle in workers.md — a worker with no workflow-specific state is trivially unit-testable.

Unit-testing definitions

ConductorWorkflow builds a definition in memory, so assertions can be made without registering anything:

var workflow = new ConductorWorkflow().WithName("wf").WithVersion(1)
    .WithTask(new SimpleTask("greet", "greet_ref"));

Assert.Equal("wf", workflow.Name);

Mocking the API surface

Every resource API has an interface (IWorkflowResourceApi, ITaskResourceApi, and so on), so code that takes the interface can be tested against a mock rather than a server. See api-map.md.

Integration tests

Tests/Integration/ runs against a real server. CI runs this as Run integration tests (v5) in pull_request.yml, with the server endpoint and auth key supplied as secrets.

Locally, point at a server and run:

export CONDUCTOR_SERVER_URL=http://localhost:8080/api
dotnet test Tests/conductor-csharp.test.csproj

Agent E2E suites

Conductor.AI.E2eTests/ is organised by feature, one numbered suite per area — basic validation, tool calling, CLI tools, HTTP tools, stateful domains, PDF and media tools, PLAN_EXECUTE refs, skills, agent client, auth headers, schedules, and SDK parity.

They are driven by .github/workflows/agent-e2e.yml, which downloads a server jar, starts it, waits for /health, starts an MCP testkit, and runs the suites. That workflow also has a Guard against vacuous run step asserting tests actually executed — worth knowing about, because a suite that silently collects zero tests would otherwise look like a pass.

Extending the matching suite is usually the fastest way to reproduce a suspected SDK bug. See debugging.md.

Testing agents without a server

Agent construction and serialization are testable offline. runtime.PlanAsync(agent) requires a server (it compiles server-side), but AgentConfigSerializer output and builder validation — for instance that Build() throws ConfigurationException when sub-agents lack a strategy — do not.

Coverage

CI produces a Cobertura report and uploads to Codecov. Unit tests in a unit-test project rather than among the integration suites keep that signal meaningful.