In 70 seconds
One test, from the failure to the proof.
Follow one real test from the OpenCSMS demo. A pull request breaks the station screen, the comment names the cause, the trace shows the page as it failed, and one command proves the fix.
The player loads from YouTube when you press play. Watch on YouTube ↗
Less plumbing
Setup moves out of the test.
The same scenario against the same application, written as a plain fixture and with ProtoTest. The scenario lines stay; the plumbing around them is composed once for the suite or declared on the test that needs it.
Compare both files, line by line →- Run the application
A factory per fixtureThe suite host- A tenant of its own
SetUp and a helperAn attribute- Authenticate each call
Shared default headersPer test, from its context- Clean up after a failure
TearDown, if SetUp got farOwned, reversed and traced
Evidence
A failure explains itself.
Every call, check, wait and cleanup lands in a .prototrace archive next to the report. Open it and the failing check is one step away, with the values that differed and the source line that asserted them.
The trace also shows time nothing was recorded, so a real wait is visible instead of guessed.
Test execution / REST · GET /api/v1/organization
Failed2.2 ms+1.15 s into the test Evidence Shape mismatch failed with 1 error(s): [$.status]: Values did not match. (Expected: "past_due", Actual: "active") The shape check's 12 recorded attributes; open the run in the viewer to read them."past_due" → "active"The response it judged
{ "status": "active", "planId": "growth", "seatCount": 1, ... }33await Task.Delay(TimeSpan.FromSeconds(1));34 35using var organization = await Proto.Context.Rest().GetAsync("/api/v1/organization");36organization37 .Should.HaveHttpStatus(HttpStatusCode.OK)38 .Should.MatchShape(new { status = SubscriptionStatuses.PastDue });39}
Exception JsonShapeMismatchException
Attributes 12
For coding agents
Your agent reads the evidence, not the logs.
A local MCP server hands a coding agent the failed check, the call it judged and the source line as one small document. The agent spends its context on the fix instead of on finding out what happened.
The server is read-only and nothing leaves the machine: no account, no telemetry, no upload. The same diagnosis renders in a terminal and in the pull request comment.
list_runs1 run · 1 test failedget_failureTheAddressWasHardcodedForOneMachine · connection refused · Program.cs:65get_diagnosisthe call it judged, its ancestors, the source snippet, the state changeseditthe file and line the diagnosis namedprototest verifythe pull request verdict: coverage, contract and run gates
One model
Different boundaries. The same test.
Choose the integrations your scenario crosses. Each joins the same host, context, cleanup and trace, so one test can write through an API and read back from the database or the browser.
Exercise your APIs
REST, GraphQL and gRPC clients with shared authentication, shape checks and contract coverage.
SupportedArrange data and inspect the store
Reusable test data, test-scoped SQL connections and EF Core contexts, with optional transaction rollback.
SupportedFollow a journey in the browser
Page objects and flows through Playwright or Selenium, with screenshots and page coverage.
SupportedPublish and await messages
In-memory messaging or RabbitMQ. Add the MassTransit bridge when you need its test harness.
Supported · MassTransit previewCompose the environment
ASP.NET Core, background workers and run-owned containers. Aspire and WireMock are available in preview.
Supported · preview extensionsReach devices and documents
Typed device clients over WebSocket, MQTT, TCP or a serial port, and assertions on generated Excel workbooks.
PreviewEvery integration → · Recipes that combine them · Build one for your own domain
How it fits
Your runner runs the tests. ProtoTest holds what is around them.
- 01
Compose the host
Applications, clients and infrastructure, registered once for the suite.
Host composition → - 02
Arrange the context
Attributes and builders prepare the identity, data and clients one test needs.
Execution context → - 03
Own the cleanup
Whatever a test provisions is released in reverse order, also when it fails.
Lifecycle and cleanup → - 04
Keep the evidence
Calls, checks and cleanup land in the test’s trace, report and coverage.
Trace and reports →
Keep your runner and your assertions. Add a setup class and the integrations you need, then move one scenario at a time. Compare the setup · Choose your runner · Adoption and exit costs
< 1 msof a 36 ms test in a real suite with a database and a broker is ProtoTest. Where the rest goes →Try it
Your first suite, ready to run.
The template creates a small API and four integration tests. The .NET 10 SDK is enough. The default starter runs without containers or a browser.
After the green run, the trace and HTML report are under Shop.Tests/bin/Debug/net10.0/TestResults/.
dotnet new install ProtoTest.Templates
dotnet new prototest -n Shop
cd Shop
dotnet testWhy ProtoTest exists
Once an integration suite grows, most of the work shifts to setup, infrastructure and failures that only happen sometimes. ProtoTest gives every integration the same context, lifecycle and trace, so that work is solved once. What is specific to your application stays in your test project. Project and support