Skip to main content

Fix a failure with one change per run

The problem​

You can read a failing trace. Now use it to decide what to change. Changing several things at once makes the next result harder to explain.

The loop that works is short. Run the suite, open the trace, read the failing check, change one thing, run again and compare the two traces.

Do it​

1. Read the failing check​

The visibility failure sent an empty project name and asserted the status:

using var response = await Proto.Context.Rest()
.Body(new CreateProjectRequest(""))
.PostAsync("/api/v1/projects");

response.Should.HaveHttpStatus(HttpStatusCode.Created);

The check failed with a message starting Expected HTTP status 201 (Created), but received 400 (BadRequest). That message also includes the problem body. Open l0-visibility-drill.prototrace in the viewer and look at the request entry. Its response attachment names validation_failed and the empty name parameter.

The test did not check the body, but the failed run already showed it. The application rejected an invalid request as expected.

2. Change one thing​

Make this test check the rejection of an empty name. Expect HTTP 400 and check the problem code and message:

response
.Should.HaveHttpStatus(HttpStatusCode.BadRequest)
.Should.MatchShape(new
{
code = ProblemCodes.ValidationFailed,
message = JsonValue.StringContaining("name")
});

The paired test sends the same empty-name request through the same composed client. Its expectation changes from successful creation to a specific validation failure.

Choose that expectation from the behavior you want to test. If a valid request should succeed, receiving HTTP 400 still needs investigation.

3. Run again and compare​

Open l0-visibility-fix.prototrace beside the first trace. The request now has two passing checks: HTTP status and JSON shape. A later shape mismatch can identify which checked property differs.

4. When the trace is silent, the missing answer is the fix​

The environment failure has no HTTP request operation in its trace. Its execution phase, the test body, ran about two seconds and failed with a connection error.

Check the source to explain the missing request. This test creates a raw HttpClient inside its body and calls a hardcoded address. That client bypasses ProtoTest's REST instrumentation. The paired test uses Proto.Context.Rest(), which takes its address from the composition and records the request.

What happened​

The visibility trace showed why the request failed. The environment trace showed the execution failure. The source explained why no request operation appeared.

Keep each change focused so you can compare its effect. IDs, timings and setup details can also differ between runs. Compare the relevant request and checks rather than expecting identical traces.

When a failure looks random, walk the four questions in order:

  • Time: a real wait does not move the test clock. The fix advances it before reading the organization.
  • State: the test guessed prj_1. The fix creates a project and checks its tenant's list.
  • Environment: the address was hardcoded. The fix takes it from the composition.
  • Visibility: the request had an empty name. The fix checks HTTP 400 and the validation problem body.

Use these questions to choose what to inspect next. A missing operation is a reason to check instrumentation and source, not a diagnosis by itself.

Check yourself​

The environment trace has a connection error but no HTTP request operation. The visibility trace already shows the validation body. What should each test change?

Verify
Compare l0-environment-drill.prototrace and l0-visibility-drill.prototrace in the viewer, then read the two fixes.

Remember​

  • Run, open the trace, read the failing check, change one thing, run again.
  • A trace turns a failed run into facts you can act on without rerunning it.
  • Use the four questions to choose what to inspect. Check source when the trace leaves something unexplained.

Go deeper​