Purview.SourceGeneratorFramework.Testing.TUnit
1.0.0-prerelease.35
See the version list below for details.
dotnet add package Purview.SourceGeneratorFramework.Testing.TUnit --version 1.0.0-prerelease.35
NuGet\Install-Package Purview.SourceGeneratorFramework.Testing.TUnit -Version 1.0.0-prerelease.35
<PackageReference Include="Purview.SourceGeneratorFramework.Testing.TUnit" Version="1.0.0-prerelease.35" />
<PackageVersion Include="Purview.SourceGeneratorFramework.Testing.TUnit" Version="1.0.0-prerelease.35" />
<PackageReference Include="Purview.SourceGeneratorFramework.Testing.TUnit" />
paket add Purview.SourceGeneratorFramework.Testing.TUnit --version 1.0.0-prerelease.35
#r "nuget: Purview.SourceGeneratorFramework.Testing.TUnit, 1.0.0-prerelease.35"
#:package Purview.SourceGeneratorFramework.Testing.TUnit@1.0.0-prerelease.35
#addin nuget:?package=Purview.SourceGeneratorFramework.Testing.TUnit&version=1.0.0-prerelease.35&prerelease
#tool nuget:?package=Purview.SourceGeneratorFramework.Testing.TUnit&version=1.0.0-prerelease.35&prerelease
Purview.SourceGeneratorFramework.Testing.TUnit
TUnit integration for testing incremental C# source generators built with Purview.SourceGeneratorFramework.
Installation
dotnet add package Purview.SourceGeneratorFramework.Testing.TUnit
What's included
TUnitSourceGeneratorTestBase<TGenerator>— ready-made base class for TUnit tests. It wires generator log output toTestContext.Current.OutputWriter.- Custom TUnit assertions for inspecting
DriverRunResultinstances directly in TUnit tests. - MSBuild
.props— automatically addsglobal usingdirectives forPurview.SourceGeneratorFramework.Testing.TUnitandPurview.SourceGeneratorFramework.Testing.TUnit.Assertions.
Usage
Reference the package from a TUnit test project:
<ItemGroup>
<PackageReference Include="TUnit" />
<PackageReference Include="Purview.SourceGeneratorFramework.Testing.TUnit" />
</ItemGroup>
Derive your test class from TUnitSourceGeneratorTestBase<TGenerator> and use the inherited GenerateAsync method:
using Purview.SourceGeneratorFramework.Testing.TUnit;
public class MyGeneratorTests : TUnitSourceGeneratorTestBase<MyGenerator>
{
[Test]
public async Task GeneratesExpectedSource()
{
var source = """
[MyNamespace.MyAttribute]
public partial class MyClass { }
""";
var result = await GenerateAsync(source);
result.AssertNoCompilationErrors();
var generated = result.AssertSingleGeneratedSource();
await Assert.That(generated).Contains("public static partial class MyClass");
}
}
The base class also provides access to the underlying SourceGeneratorTestRunner<TGenerator> behavior through GenerateAsync.
Using generated types in the TUnit project
If test source files use generated attributes or other generated declarations while the tests also
derive from TUnitSourceGeneratorTestBase<TGenerator>, reference the generator project both as an
analyzer and as a normal assembly:
<ItemGroup>
<ProjectReference
Include="..\..\src\MyGenerator\MyGenerator.csproj"
PrivateAssets="all"
OutputItemType="Analyzer"
ReferenceOutputAssembly="false"
/>
<ProjectReference
Include="..\..\src\MyGenerator\MyGenerator.csproj"
PrivateAssets="all"
ReferenceOutputAssembly="true"
/>
</ItemGroup>
For example, the analyzer reference allows a test fixture to use [MyGeneratedAttribute], while
the normal reference allows the test class to derive from
TUnitSourceGeneratorTestBase<MyGenerator>. Do not add OutputItemType="Analyzer" to the normal
reference.
For multi-target TUnit projects, the normal reference means the generator's Roslyn dependencies
participate in reference resolution for every target. Build the generator against the oldest
compatible Roslyn version (Roslyn 4.13 for a .NET 8–10 test matrix) and avoid forcing a newer
System.Collections.Immutable version through central package management. The framework's
RegisterEmbeddedAttribute helper can be used instead of Roslyn 4.14's
AddEmbeddedAttributeDefinition API when .NET 8 compatibility is required.
Which base class and method
| Roslyn type | Base class | Method |
|---|---|---|
| Generator | TUnitSourceGeneratorTestBase<TGenerator> |
GenerateAsync(source, options, ct) |
| Diagnostic analyzer | TUnitDiagnosticAnalyzerTestBase<TAnalyzer> |
AnalyzeAsync(source, options, ct) |
| Code fix (single) | TUnitCodeFixTestBase<TAnalyzer, TCodeFix> |
ApplyCodeFixAsync(source, options, ct) |
| Code fix (fix-all) | TUnitCodeFixTestBase<TAnalyzer, TCodeFix> |
ApplyFixAllAsync(sources, options, ct) |
| Refactoring | TUnitRefactoringTestBase<TRefactoring> |
RefactorAsync(source, options, ct) |
For cache tests, TUnitSourceGeneratorTestBase also exposes GenerateIncrementalAsync(...).
Easy starting point: derived options
Derive a SourceGeneratorTestOptions record that seeds namespaces and additional assemblies, then pass it
to every test:
public sealed record MyTestOptions : SourceGeneratorTestOptions
{
public MyTestOptions()
{
AdditionalNamespaces = AdditionalNamespaces.Add("My.Namespace");
AdditionalAssemblyTypes = AdditionalAssemblyTypes.AddRange(typeof(SomeDependencyType), typeof(TypeIdentity));
DisableSourceGeneratorPropertyName = "DisableMyGenerator";
}
}
public class MyGeneratorTests : TUnitSourceGeneratorTestBase<MyGenerator, MyTestOptions> { ... }
Use options.Compile() for CompileToAssembly, and the OnBeforeRun/OnBeforeRunAsync/OnAfterRun
hooks for per-run customisation. Code-fix/refactoring tests select actions with EquivalenceKey or
CodeActionIndex (and RefactorTestOptions.NodeSelector/Span).
Assertion extensions
All assertion extensions are under Purview.SourceGeneratorFramework.Testing.TUnit.Assertions (globally
imported). await Assert.That(...) is terminal and returns the value:
HasGeneratedMethod/HasGeneratedMethodReturnType/HasGeneratedClass/HasGeneratedProperty/HasGeneratedField/HasGeneratedSyntaxTree— return the syntax node;HasGeneratedMethod(name, TypeReference[])matches parameter types.HasFixedMethod— same for code-fix and refactoring results.HasDiagnostic/HasDiagnostics/HasNoDiagnostics/DoesNotHaveDiagnostic/HasNoErrorDiagnostics.HasSymbol(TypeIdentity)/HasSymbol("Namespace.Type").GeneratesCode(expected)/ContainsGeneratedCode(expected)(whitespace-flattened).
MethodDeclarationSyntax method = await Assert.That(result).HasGeneratedMethod("DoWork", [intType, nullableInt]);
await Assert.That(result).HasGeneratedSyntaxTree("Service.g.cs");
Incremental cache tests
GenerateIncrementalAsync proves the pipeline caches stage-by-stage (first run New, identical rerun
Cached/Unchanged, targeted changes mark only the affected stage Modified). A reference
implementation (ServiceRegistrationCacheTests) lives in the Purview.SourceGeneratorFramework source
repository's example generator tests; replicate it in your own project with your own stage names.
License
This project is licensed under the MIT license.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Purview.SourceGeneratorFramework.Testing (>= 1.0.0-prerelease.35)
- TUnit.Assertions (>= 1.65.51)
- TUnit.Core (>= 1.65.51)
-
net10.0
- Purview.SourceGeneratorFramework.Testing (>= 1.0.0-prerelease.35)
- TUnit.Assertions (>= 1.65.51)
- TUnit.Core (>= 1.65.51)
-
net8.0
- Purview.SourceGeneratorFramework.Testing (>= 1.0.0-prerelease.35)
- TUnit.Assertions (>= 1.65.51)
- TUnit.Core (>= 1.65.51)
-
net9.0
- Purview.SourceGeneratorFramework.Testing (>= 1.0.0-prerelease.35)
- TUnit.Assertions (>= 1.65.51)
- TUnit.Core (>= 1.65.51)
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 |
|---|---|---|
| 1.0.0-prerelease.44 | 41 | 9/18/2026 |
| 1.0.0-prerelease.43 | 29 | 9/17/2026 |
| 1.0.0-prerelease.42 | 111 | 9/14/2026 |
| 1.0.0-prerelease.41 | 50 | 9/14/2026 |
| 1.0.0-prerelease.40 | 53 | 9/13/2026 |
| 1.0.0-prerelease.39 | 61 | 9/12/2026 |
| 1.0.0-prerelease.38 | 51 | 9/12/2026 |
| 1.0.0-prerelease.37 | 83 | 9/8/2026 |
| 1.0.0-prerelease.36 | 79 | 9/6/2026 |
| 1.0.0-prerelease.35 | 73 | 9/5/2026 |
| 1.0.0-prerelease.34 | 63 | 9/5/2026 |
| 1.0.0-prerelease.33 | 73 | 9/4/2026 |
| 1.0.0-prerelease.32 | 69 | 9/3/2026 |
| 1.0.0-prerelease.31 | 69 | 9/3/2026 |
| 1.0.0-prerelease.30 | 81 | 9/3/2026 |
| 1.0.0-prerelease.29 | 74 | 9/3/2026 |
| 1.0.0-prerelease.28 | 68 | 9/2/2026 |
| 1.0.0-prerelease.27 | 76 | 9/1/2026 |
| 1.0.0-prerelease.26 | 107 | 8/29/2026 |
| 1.0.0-prerelease.25 | 83 | 8/27/2026 |