Precept 0.10.0

Artifacts and logging

PreceptTestContext.Current is ambient for the running test and flows across await. Log(...) lines become that test's standard output; AttachAsync(...) records files. RegisterForDisposal(...) ties a resource to the test — disposed after the after-scenario hook, so hooks can still capture diagnostics from it.

Failing a test after its last line#

RegisterVerification(...) registers a check that runs after the test body and its after-scenario hook, and whose failure fails a test that would otherwise have passed:

PreceptTestContext.Current?.RegisterVerification(() => session.VerifyNoErrorsAsync());

For a verdict a module reaches on the test's behalf rather than one the test asked for — a console error the page logged while nobody was looking, a request that failed after the last assertion passed. The test cannot check those itself, because the moment they matter is after the last line it wrote. Precept.Web uses it for FailOnConsoleErrors and FailOnPageErrors.

Checks run in the order they were registered, before anything registered for disposal is disposed — so a check still has the page or the connection it is checking — and the outcome is settled before disposal, so a failure decided here still gets that module's failure screenshot and trace captured on the way out. A test that already failed keeps its own failure and the check's is logged instead: the first thing to go wrong is the one worth reporting, and a console error is usually a symptom of it.

What a test logged is reported as the platform's StandardOutputProperty, so it reaches a TRX as <StdOut>, a test explorer's output pane, and every reporter — whether the test passed or failed. A failure additionally repeats the log under its message, so a failed test explains itself even where output is suppressed.

Seeing the Gherkin steps a scenario ran#

Reqnroll traces each step as it executes, and Precept routes that trace into the running test rather than to the process console. That is what puts the steps in the TRX, in a test explorer, and on a ReportPortal test item — and it is why two scenarios running in parallel no longer interleave their steps.

The console is the platform's decision, not Precept's, and it takes two flags — Normal output does not list passing tests at all, so there is nowhere to hang their output:

dotnet run --project tests/Acme.Tests -- --output Detailed --show-stdout All
пройдено Adding two numbers (105ms)
  Standard output
    Given a clean calculator
    -> done: CalculatorSteps.GivenACleanCalculator() (0,0s)
    When I press add
    add(50 + 70) = 120
    -> done: CalculatorSteps.WhenIPressAdd() (0,0s)

Anything a step logs itself lands in the right place in that sequence. Under dotnet test the same flags work for failing and skipped tests, but the SDK's own logger never lists passing ones, so a passing scenario's steps are only in the TRX and the reporters. Whether successful steps are traced at all stays Reqnroll's call, through trace.traceSuccessfulSteps in reqnroll.json.

Each test writes into its own directory under ArtifactDirectory. The directory is named after the test but deliberately kept short — Windows caps a full path at 260 characters, and past that an artifact is still written while the TRX writer's copy of it fails with "attachment not found". The directory is created the first time something asks for a path inside it, which a module recording on failure does before the test runs, so a test that passes is left with an empty one — and that is removed once the test is over. What survives a run is a directory per test that produced a file, which is what a pipeline publishing the root should ship. A retried test's reruns write into attempt-2, attempt-3 and so on under that directory, so the first attempt's files survive them.

Recorded files are reported to the platform as file artifacts of the test that produced them. With --report-trx they are copied next to the .trx and listed as <ResultFile> entries of that test's result, which is what Azure DevOps' PublishTestResults task uploads as attachments. The TRX copies every file whatever its size; the reporters that upload files apply a size cap of their own, see what gets attached:

- task: PublishTestResults@2
  inputs:
    testResultsFormat: VSTest
    testResultsFiles: '**/*.trx'
    publishRunAttachments: true

Precept implements the platform's ITrxReportCapability, so a TRX also carries the declaring class name, the test's categories as <TestCategory> entries, the lines it logged as <StdOut>, and its failure split into <ErrorInfo><Message> and <StackTrace>.

Precept 0.10.0 · MIT · © 2026

Esc