Kogoshvili.Temporal.Testing
1.0.3
dotnet add package Kogoshvili.Temporal.Testing --version 1.0.3
NuGet\Install-Package Kogoshvili.Temporal.Testing -Version 1.0.3
<PackageReference Include="Kogoshvili.Temporal.Testing" Version="1.0.3" />
<PackageVersion Include="Kogoshvili.Temporal.Testing" Version="1.0.3" />
<PackageReference Include="Kogoshvili.Temporal.Testing" />
paket add Kogoshvili.Temporal.Testing --version 1.0.3
#r "nuget: Kogoshvili.Temporal.Testing, 1.0.3"
#:package Kogoshvili.Temporal.Testing@1.0.3
#addin nuget:?package=Kogoshvili.Temporal.Testing&version=1.0.3
#tool nuget:?package=Kogoshvili.Temporal.Testing&version=1.0.3
Kogoshvili.Temporal.Testing
A replay/regression test harness for Temporal .NET workflows. It starts a real
Temporal test environment, runs a workflow to completion, snapshots its event
history, and replays it through WorkflowReplayer to surface non-determinism.
Unlike Kogoshvili.Temporal.Analyzers, this library references the real
Temporalio SDK and targets
net8.0.
Minimal setup
Replay recorded histories for a workflow type from a live Temporal service —
Cloud or self-hosted. The replayer registers the workflow type; the connection
comes from the shared Kogoshvili.Temporal.Configuration project (see
Configuration):
using Kogoshvili.Temporal.Configuration;
using Kogoshvili.Temporal.Testing;
using Temporalio.Workflows;
[Workflow]
public class GreetingWorkflow
{
[WorkflowRun]
public async Task<string> RunAsync(string name)
{
await Workflow.DelayAsync(TimeSpan.FromMilliseconds(1));
return $"Hello, {name}!";
}
}
var client = await TemporalConfig.ConnectAsync();
await foreach (var result in Replay.FromServerAsync<GreetingWorkflow>(
client,
workflowType: "GreetingWorkflow",
executionStatus: "Completed",
limit: 50))
{
result.ThrowIfFailed();
}
Configuration
The live-service replay path connects via the shared
Kogoshvili.Temporal.Configuration project, which reads the Temporal section
of appsettings.json (plus Temporal__* environment variables):
{
"Temporal": {
"TargetHost": "my-namespace.tmprl.cloud:7233",
"Namespace": "my-namespace",
"Tls": {
"ClientCertPath": "certs/client.pem",
"ClientPrivateKeyPath": "certs/client.key"
}
}
}
TemporalConfig.ConnectAsync() has overloads for no-arg, IConfiguration, and
TemporalConnectionOptions.
Golden files
Replay JSON histories checked into the repo — exported with the Temporal CLI
(temporal workflow show --output json), downloaded with the temporal-sharp
CLI, or exported from the web UI. No server, test environment, or credentials
needed at test time — only the workflow type under test.
history download fetches recorded histories from a live service using the
same shared configuration as the replay path (appsettings.json +
Temporal__* environment variables) and writes one *.json file per workflow
id:
temporal-sharp history download GreetingWorkflow --out histories --limit 50
using Kogoshvili.Temporal.Testing;
// One exported history; the workflow id is passed explicitly
var result = await Replay.FromJsonAsync<GreetingWorkflow>(
await File.ReadAllTextAsync("histories/greeting-replay.json"),
workflowId: "greeting-replay");
result.ThrowIfFailed();
// Every JSON history in a directory; file names (minus extension) become workflow ids
foreach (var result in await Replay.FromDirectoryAsync<GreetingWorkflow>("histories"))
{
result.ThrowIfFailed();
}
Full configuration
Replay sources
There are three ways to feed histories into WorkflowReplayer:
- Live service —
Replay.FromServerAsyncreplays recorded histories for a workflow type from a running Temporal service, optionally filtered by execution status and capped by a total count. - Checked-in golden files —
Replay.FromJsonAsync/Replay.FromDirectoryAsyncreplay JSON histories exported from the Temporal CLI (temporal workflow show --output json) or web UI and committed to the repo. - Live, local capture —
ReplayHarness.VerifyAsyncstarts a bundled local test environment, runs the workflow, and captures its history withFetchHistoryAsync. No external server or credentials needed.
ReplayHarness
ReplayHarness : IAsyncDisposable owns a WorkflowEnvironment and its
ITemporalClient (exposed as Environment / Client):
StartTimeSkippingAsync()/StartLocalAsync()— start a time-skipping or full local Temporal server. Option overloads accept the SDK'sWorkflowEnvironmentStartTimeSkippingOptions/WorkflowEnvironmentStartLocalOptions.CaptureAsync<TWorkflow, TResult>(workerOptions, runCall, startOptions)— run a workflow to completion and capture its result andWorkflowHistory.ReplayAsync<TWorkflow>(history)— replay a history viaWorkflowReplayer, returning the rawWorkflowReplayResult.VerifyAsync<TWorkflow, TResult>(workerOptions, runCall, startOptions)— capture + replay in one step.
ReplayResult
The outcome of a capture-and-replay run:
Succeeded— true when the workflow replayed without divergence.ReplayFailure— the non-determinism detected byWorkflowReplayer, or null.SnapshotJson— the captured history as JSON.ThrowIfFailed()— throwsReplayMismatchExceptionwhen the replay diverged.
Snapshot
Helpers for capturing and comparing event-history snapshots:
ToJson(history)/FromJson(json, workflowId)— serialize and rehydrate aWorkflowHistory.AssertEquivalent(expectedJson, actualJson)— throwsReplayMismatchExceptionwhen the snapshots diverge.AreEquivalent(expectedJson, actualJson)— structural equality ignoring key order and insignificant whitespace.
Edge cases
StartTimeSkippingAsync/StartLocalAsynclazily download the Temporal test-server/dev-server binary on first use, so the first test run needs network access.- The time-skipping environment is single-test-at-a-time; a full local server is
available via
StartLocalAsyncwhen that is a constraint. Replay.FromDirectoryAsyncuses each file name (without extension) as the workflow id.Replay.FromServerAsyncreturnsIAsyncEnumerable<WorkflowReplayResult>; callThrowIfFailed()per result or inspectReplayFailureto detect divergence.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- Kogoshvili.Temporal.Configuration (>= 1.0.3)
- Temporalio (>= 1.18.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.3 | 95 | 9/4/2026 |
| 1.0.2 | 94 | 9/3/2026 |
| 1.0.1 | 92 | 9/1/2026 |
| 1.0.0 | 95 | 8/31/2026 |
| 1.0.0-beta.10 | 74 | 8/28/2026 |
| 1.0.0-beta.9 | 62 | 8/28/2026 |
Replay/regression harness for Temporal .NET workflows: capture histories from a live server and replay them to catch non-determinism.