C# API reference · vanilla-test 2.1.0

One suite, one result, typed transitions.

The dependency-free net8.0 package exposes four public types. The separate .NET 10 tool turns an existing MSTest project into a browser WebAssembly AppBundle.

Namespace and package

GitHub package assetvanilla-test 2.1.0
Target frameworknet8.0
NamespaceVanillaTest
Runtime dependenciesNone beyond the .NET base class library
Public typesVanillaTestSuite, TestResult, VanillaTestException, VanillaTestError
dotnet add package vanilla-test --version 2.1.0 --source ./packages

VanillaTestSuite

A sealed, single-use, sequential suite. Its public parameterless constructor creates an empty instance with no active case.

MemberReturnContract
VanillaTestSuite()Creates an empty isolated suite.
Expects(string description)voidStarts one case. Descriptions use ordinal, case-sensitive uniqueness; an empty string is allowed.
Pass()voidRecords the active case as passed when it has no earlier decision.
Fail()voidRecords the active case as failed when it has no earlier decision.
Done()voidCloses the active case; no decision defaults to failure.
Report()TestResultRejects an active case, otherwise seals the suite and returns the same cached result thereafter.

First-decision rule

test.Expects("first decision wins");
test.Pass();
test.Fail();
test.Done();

Console.WriteLine(test.Report().Ok); // True

Calling Pass() or Fail() again while the same case is active is a no-op. Calling either method without an active case throws VanillaTestException.

TestResult

A sealed immutable summary. Users obtain it from Report(); its constructor is internal.

PropertyTypeMeaning
PassedIReadOnlyList<string>Read-only numbered rows that passed, in original case order.
FailedIReadOnlyList<string>Read-only numbered rows that failed, in original case order.
TotalintCompleted passed plus failed cases.
FailureCountintNumber of failed cases.
Okbooltrue when FailureCount is zero, including an empty suite.
ReportstringPlain-text summary with totals followed by failed and passed rows.

Rendered rows preserve their original one-based number and exact description:

1) .expects first passes
2) .expects second fails

Passed and Failed are backed by read-only snapshots. Casting them to a mutable collection does not make mutation valid.

VanillaTestException and VanillaTestError

VanillaTestException is a sealed InvalidOperationException with an Error property containing the stable enum value. A rejected lifecycle transition does not otherwise advance the suite.

ErrorThrown whenMessage
SuiteAlreadyReportedExpects() follows a successful report.this vanilla-test suite has already reported
TestAlreadyActiveExpects() is called while a case is active.a test is already active; call Done() first
DuplicateDescriptionAn exact description is reused in one suite.test descriptions must be unique
NoActiveTestPass(), Fail(), or Done() has no active case.there is no active test; call Expects() first
ActiveTestNotDoneReport() is called while a case is active.the active test is not complete; call Done() before Report()

Expects(null) throws ArgumentNullException. Constructing VanillaTestException with an undefined enum value throws ArgumentOutOfRangeException.

Lifecycle state

StateAllowed next callsRejected calls
Empty or between casesExpects(), Report()Pass(), Fail(), Done()
Case activePass(), Fail(), Done()Expects(), Report()
ReportedReport() returns cached resultExpects(); decision/completion calls still have no active case
Sequential by design.

A suite owns one mutable active case and is not a concurrent scheduler. Use a separate VanillaTestSuite instance for each independent flow.

vanilla-test.tool 2.1.0

Run the full native test suite with the standard .NET host. Install the .NET 10 global tool only for a browser test or benchmark AppBundle:

dotnet test
dotnet tool install --global vanilla-test.tool --version 2.1.0 --add-source ./packages
dotnet vanilla-test --browser [--bench] [--project PATH] [--out-dir PATH] [--page PATH]
OptionContract
--browserRequired explicit build mode.
--benchBuilds a benchmark executable whose --browser-sample mode runs one validated workload and returns an integer status.
--project PATHSelects an MSTest or benchmark .csproj. Without it, the current directory must contain exactly one project.
--out-dir PATHAppBundle output relative to the selected project. Default: dist/vanilla-test, or dist/vanilla-test-benchmark with --bench.
--page PATHCompatible custom test HTML page relative to the selected project; rejected with --bench.
--help, -hPrints usage and exits successfully.
--version, -VPrints the tool version and exits successfully.

Unknown options, missing values, missing projects/pages, ambiguous default projects, non-executable benchmark projects, unsafe nonempty output directories, metadata failures, publish failures, and incomplete AppBundles are reported as tool errors with exit code 2.

Generated browser host contract

The tool publishes a generated net10.0, browser-wasm, self-contained AppBundle. It references the selected project and MSTest.TestFramework 4.3.3. It does not invoke Microsoft.Testing.Platform.

SupportedDeliberately outside the host
Public instance [TestMethod] discovery on [TestClass]MTP and adapter protocol emulation
Parameterless synchronous, Task, and ValueTask methodsParameterized and data-row expansion
[Ignore], test initialization and cleanupTestContext or other runner injection
Per-method construction and sync/async disposalNative filters and rich adapter diagnostics

Discovery order is ordinal by declaring type full name and then method name. The host prints PASS, FAIL, or SKIP lines, followed by total, failed, succeeded, and skipped counts. Any failure produces a nonzero result.

Benchmark mode creates a separate generated host with VanillaTestBrowserBenchmark.Run() exported to JavaScript. Each call invokes the selected executable with one --browser-sample argument. That project owns the workload, result validation, and status; the AppBundle supplies only the .NET runtime and managed export boundary.

Compatible page hooks

HookPurpose
data-csharp-browser-resultReceives the aggregate human-readable result.
data-csharp-browser-scoreReceives MSTest and browser-check totals.
data-csharp-browser-checksReceives one row per browser-side check.
data-csharp-browser-targetMust visibly contain browser-wasm.
data-csharp-browser-consoleReceives captured .NET and adapter console output.
data-csharp-browser-site-checkNames a visible element assertion.
data-csharp-browser-expectedOptionally requires exact visible text.
<script type="module" src="./browser.js">Loads the generated adapter beside the page.

The tool validates the result, score, checks, target, and module hooks before publishing. The console and site-check hooks make a custom page fully observable.