Skip to content

Adds Amazon.Lambda.DurableExecution.Testing#2428

Closed
GarrettBeatty wants to merge 1 commit into
devfrom
durabletesting2
Closed

Adds Amazon.Lambda.DurableExecution.Testing#2428
GarrettBeatty wants to merge 1 commit into
devfrom
durabletesting2

Conversation

@GarrettBeatty

@GarrettBeatty GarrettBeatty commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds Amazon.Lambda.DurableExecution.Testing — a NuGet package for testing durable workflows.

Write your test once against IDurableTestRunner<TInput, TOutput> and run it either:

  • locally (DurableTestRunner) — in-process on the real runtime engine with an in-memory backend (fast, no AWS), or
  • against a deployed function (CloudDurableTestRunner) — invokes the real Lambda and polls for the result.

Both return the same TestResult<TOutput> for assertions (status, result, error, and per-step inspection via GetStep/GetResult<T>).

Supports time-skipping, the callback flow, and sibling-function registration. Adds an internal IDurableServiceClient seam to the runtime package (no public API change).

Example

using Amazon.Lambda.DurableExecution.Testing;
using Xunit;

public class OrderWorkflowTests
{
    [Fact]
    public async Task MultiStepWorkflow_Succeeds()
    {
        await using var runner = new DurableTestRunner<int, int>(
            handler: async (input, ctx) =>
            {
                var doubled = await ctx.StepAsync(async (_, _) => input * 2, name: "double");
                return await ctx.StepAsync(async (_, _) => doubled + 10, name: "add_ten");
            });

        var result = await runner.RunAsync(5);

        result.EnsureSucceeded();
        Assert.Equal(20, result.Result);

        // Inspect individual steps
        var step = result.GetStep("double");
        Assert.Equal(OperationStatus.Succeeded, step.Status);
        Assert.Equal(10, step.GetResult<int>());
    }
}

The same assertions run unchanged against a deployed function by swapping the runner:

await using var runner = new CloudDurableTestRunner<int, int>(
    functionArn: "arn:aws:lambda:us-east-1:123456789012:function:order-processor:live");

var result = await runner.RunAsync(5);
result.EnsureSucceeded();

Day-long WaitAsync / callback workflows complete in milliseconds locally (time-skipping is on by default), and ctx.InvokeAsync siblings resolve in-process via RegisterFunction / RegisterDurableFunction. See the package README for the callback and sibling-invoke patterns.

Test plan

  • 106 unit tests passing on net8.0 and net10.0
  • Portable scenarios verified end-to-end against real deployed functions
  • Existing runtime tests unaffected

@GarrettBeatty GarrettBeatty changed the title Durabletesting2 Adds Amazon.Lambda.DurableExecution.Testing Jun 26, 2026
@GarrettBeatty GarrettBeatty marked this pull request as ready for review June 26, 2026 14:53
@GarrettBeatty GarrettBeatty requested review from a team as code owners June 26, 2026 14:53
@GarrettBeatty GarrettBeatty requested review from normj and philasmar June 26, 2026 14:53
return new TestResult { Status = "should_not_reach" };
}
=> DurableFunction.WrapAsync<StepsRequest, StepsResult>(
ChildContextWorkflows.FailsAsync, input, context);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moved all of these common workflows to a different re-usable file so that the local and cloud runner tests can also re-use the existing integ tests

@GarrettBeatty

Copy link
Copy Markdown
Contributor Author

closing this to separate it into two prs to make release easier

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant