Skip to main content
ANcpLua.Roslyn.Utilities.Testing provides fluent base classes for testing Roslyn components:
These base classes work with xUnit v3’s ambient TestContext. Use TestContext.Current.TestOutputHelper for diagnostic output without constructor injection.

Installation

AnalyzerTest

Base class for testing diagnostic analyzers with pre-configured .NET 10 reference assemblies.

Basic Usage

Use diagnostic markup {|DIAGNOSTIC_ID:code|} to mark expected diagnostic locations.

Testing with Additional Files

For analyzers that inspect non-C# files (MSBuild props, JSON configs, etc.):

Target Framework Selection

CodeFixTest

Base class for testing code fix providers that transform diagnostic-marked code.
The test framework automatically runs the analyzer, triggers the code fix, and verifies the result matches fixedSource.

RefactoringTest

New in v1.14.0
Base class for testing code refactoring providers (lightbulb suggestions without diagnostics).

Basic Usage

Use span markup [|code|] to mark the refactoring trigger location.

Verifying No Refactoring Offered

GeneratorTest

Fluent API for testing Roslyn incremental source generators with built-in caching validation.

Basic Usage

The Test<TGenerator> static class automatically runs your generator twice to validate incremental caching behavior.

Custom Configuration

For complex scenarios, use the configuration overload:

GeneratorTestEngine Methods

GeneratorResult Assertions

The GeneratorResult class provides a fluent API for verifying generator output.

Output Verification

Compilation Verification

Diagnostic Assertions

Custom File Assertions

GeneratorResult implements IDisposable and calls Verify() on dispose. Use using var result = ... to automatically throw on assertion failures.

Caching Validation

Incremental generators must cache their outputs properly to avoid recomputation during IDE typing scenarios. The testing framework validates caching behavior automatically.

Basic Caching Check

Checking Specific Steps

Understanding the Caching Report

Forbidden Types

Certain Roslyn types must never be cached because they prevent proper incremental caching:
Caching forbidden types causes memory leaks and IDE performance degradation. Extract primitive data (strings, booleans, etc.) from Roslyn types before caching.

Step Tracking

Enable step tracking to analyze which pipeline steps were executed and their caching states.

How Step Tracking Works

  1. The test engine runs your generator twice with identical input
  2. The first run populates the cache
  3. The second run reveals caching behavior

Step States

A successfully cached step produces only Cached or Unchanged outputs.

Named Step Tracking

Use WithTrackingName in your generator to enable fine-grained analysis:
Then verify specific steps:

Method Reference

AnalyzerTest<TAnalyzer>

CodeFixTest<TAnalyzer, TCodeFix>

RefactoringTest<TRefactoring>

Test<TGenerator>

GeneratorResult

GeneratorCachingReport

GeneratorStepAnalysis

Test Project Patterns

Minimal Generator Test Project

A clean generator test project requires only essential packages:
The Analyzer item loads ANcpLua.Roslyn.Utilities as an analyzer dependency alongside your generator.

Shared Test Base Class

Create a base class to centralize test infrastructure:

Verify Module Initializer

Configure Verify for Roslyn types:

Test File Organization

Keep tests focused: one test class per concern. Avoid duplicate test infrastructure across files.

Dynamic Compilation

The Compile class provides a fluent API for dynamic compilation in tests, useful for testing code that needs to compile and execute user-provided source code.

Basic Usage

Compile Builder Methods

CompileResult Properties

CompileResult Query Methods

CompileResult Assertions

Log Testing

The LogAssert class provides fluent assertions for FakeLogCollector from Microsoft.Extensions.Logging.Testing.

Basic Usage

Count Assertions

Content Assertions

Level Assertions

Combined Assertions

Predicate Assertions

Async Waiting

For testing async logging scenarios, use polling assertions:
Async assertions poll every 25ms and timeout after 5 seconds by default. Pass a custom timeout parameter for longer operations.

Web Testing

ASP.NET Core integration test base classes with fake logging support. Available for xUnit, NUnit, TUnit, and bUnit.

IntegrationTestBase (xUnit)

Fast integration test base using in-memory TestServer for API tests that don’t require real network I/O.

IntegrationTestBase (NUnit)

NUnit version uses [OneTimeSetUp] for factory creation (shared across tests) and [SetUp]/[TearDown] for per-test client lifecycle.

IntegrationTestBase (TUnit)

TUnit version uses [Before(HookType.Test)] / [After(HookType.Test)] hooks. A fresh factory and client are created per test.

KestrelTestBase

Real Kestrel test base for HTTP/2, WebSockets, SSE, and Playwright testing with real network I/O. Available for xUnit, NUnit, and TUnit.

BunitTestBase

Base class for bUnit Blazor component tests with integrated fake logging.
BunitTestBase extends BunitContext and pre-configures FakeLogCollector. Works with any test framework (xUnit, NUnit, TUnit).

Web Testing Properties

Web Testing Namespaces

Analyzer Infrastructure

Base classes for building Roslyn analyzers and code fixes with common patterns.

DiagnosticAnalyzerBase

Base class for diagnostic analyzers with concurrent execution and registration helpers.

CodeFixProviderBase

Base class for code fix providers with batch fixing and equivalence key support.

SyntaxModifierExtensions

Helpers for syntax transformations in code fixes.

Integration Testing

For testing that requires real MSBuild execution (SDK features, package behavior, build-time code generation), see MSBuild Testing.

Handling Type Ambiguity

If you encounter ambiguous reference errors between Microsoft.CodeAnalysis.Testing.AnalyzerTest and ANcpLua.Roslyn.Utilities.Testing.AnalyzerTest, use a type alias: