Thunder.DocSnippets
0.1.0
See the version list below for details.
dotnet add package Thunder.DocSnippets --version 0.1.0
NuGet\Install-Package Thunder.DocSnippets -Version 0.1.0
<PackageReference Include="Thunder.DocSnippets" Version="0.1.0" />
<PackageVersion Include="Thunder.DocSnippets" Version="0.1.0" />
<PackageReference Include="Thunder.DocSnippets" />
paket add Thunder.DocSnippets --version 0.1.0
#r "nuget: Thunder.DocSnippets, 0.1.0"
#:package Thunder.DocSnippets@0.1.0
#addin nuget:?package=Thunder.DocSnippets&version=0.1.0
#tool nuget:?package=Thunder.DocSnippets&version=0.1.0
DocSnippets
Make your C# XML doc <code> examples runnable as unit tests — the Rust doctest experience for .NET.
DocSnippets is a Roslyn source generator. Add the package, and every <code> block in your XML documentation becomes a compiled, executable NUnit/xUnit/MSTest test method. No extra tooling, no checked-in generated files.
<PackageReference Include="Thunder.DocSnippets" Version="..." />
Quick start
Add DocSnippets to your test project:
<PackageReference Include="Thunder.DocSnippets" Version="..." />Run
dotnet test. Done.
DocSnippets ships an MSBuild .targets file that automatically wires up the adjacent source project's .cs files as AdditionalFiles — no manual <ItemGroup> configuration required.
Writing snippets
Any <code> block in an XML doc comment is picked up automatically:
/// <summary>Adds two integers.</summary>
/// <example>
/// <code>
/// var result = calculator.Add(1, 2); // => 3
/// </code>
/// </example>
public int Add(int a, int b) => a + b;
The assertion comment is transformed into a framework-appropriate equality check at generation time. No assertion library is required in the snippet itself.
Inline assertion patterns
All four comment styles work on both declaration lines and expression lines:
| Pattern | Example | Meaning |
|---|---|---|
// => VALUE |
var x = f(); // => 42 |
Assert x equals 42 |
// result: VALUE |
var x = f(); // result: 42 |
Assert x equals 42 |
// VARNAME: VALUE |
DoSetup(); // myVar: 42 |
Assert myVar equals 42 |
// VALUE (bare literal) |
var x = f(); // 42 |
Assert x equals 42 |
On a declaration line (var x = f(); // => 3), the generator splits the line into the declaration statement and a separate assertion using the declared variable name. On an expression line (f(); // => 3), the entire expression becomes the assertion subject.
Bare literal comments (// 42, // true, // "hello") are only treated as assertions when the comment contains an unambiguous C# literal. Non-literal comments (// sum of values, // see above) are left unchanged.
Excluding a snippet
Add // doctest-ignore on the first line of any <code> block to skip it:
/// <code>
/// // doctest-ignore
/// // This example is illustrative — not executable.
/// var x = SomeExternalCall();
/// </code>
Configuration (docsnippets.json)
Add a docsnippets.json file alongside the source files (it is picked up automatically as an AdditionalFile by the shipped MSBuild targets) to configure the generator:
{
"snippetMode": "opt-out",
"assertionStyle": "NUnit",
"implicitUsings": ["MyLib", "MyLib.Models"]
}
| Key | Values | Default | Description |
|---|---|---|---|
snippetMode |
"opt-out", "opt-in" |
"opt-out" |
opt-out: all <code> blocks run. opt-in: only blocks containing // doctest run. |
assertionStyle |
"NUnit", "XUnit", "MSTest" |
(auto-detect) | Override the auto-detected test framework. |
implicitUsings |
Array of namespace strings | [] |
Namespaces added as using to every generated test class. |
Opt-in mode
Mark individual snippets with // doctest to include them when snippetMode is "opt-in":
/// <code>
/// // doctest
/// var x = Multiply(3, 4); // => 12
/// </code>
InternalsVisibleTo
If your snippets reference internal types, add this to your source project:
[assembly: InternalsVisibleTo("YourTestProject")]
Without it, snippets referencing internal members produce CS0122 errors that can be hard to diagnose.
Known limitations
- Tuple deconstruction —
var (a, b) = f(); // => ...is not supported. Use a separate assertion line. - Async snippets — snippets containing
awaitare not supported. The emitted test method is synchronous;awaitwill produce a compile error. - Single-assembly scanning — only direct
ProjectReferencesource projects are scanned. Transitive references are not.
What's in v0.1.0
- Inline assertion patterns — four comment styles on both declaration and expression lines:
// => VALUE,// result: VALUE,// VARNAME: VALUE, bare literal// 42 #linediagnostics — build errors in generated test methods now point to the original source line, not the generated fileassertionStyleconfig override — override auto-detected framework viadocsnippets.json//=>arrow alias —//=>accepted as shorthand for// =>- Assert value in test method name —
Add_ShouldBe_3naming from// =>assertions - Overload disambiguation — param-type suffix on overloaded method test names
- Operator and destructor name sanitization — valid C# identifiers for
operator +,~MyClass, etc. snippetMode: opt-in— only run explicitly marked snippets- MSBuild auto-wiring —
AdditionalFilesglob injected via shipped.targetsfile
Learn more about Target Frameworks and .NET Standard.
-
.NETStandard 2.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.1.3 | 104 | 4/30/2026 |
| 0.1.2 | 92 | 4/30/2026 |
| 0.1.1 | 109 | 4/28/2026 |
| 0.1.1-preview9 | 114 | 4/27/2026 |
| 0.1.1-preview8 | 102 | 4/27/2026 |
| 0.1.0 | 102 | 4/26/2026 |
| 0.1.0-preview7.1 | 61 | 4/26/2026 |
| 0.1.0-preview7 | 96 | 4/26/2026 |
| 0.1.0-preview6 | 94 | 4/25/2026 |