diff --git a/src/Tests/SourceGeneratorTest/Helpers/CSharpSuppressorTest{TSuppressor}.cs b/src/Tests/SourceGeneratorTest/Helpers/CSharpSuppressorTest{TSuppressor}.cs
new file mode 100644
index 000000000..844faea85
--- /dev/null
+++ b/src/Tests/SourceGeneratorTest/Helpers/CSharpSuppressorTest{TSuppressor}.cs
@@ -0,0 +1,150 @@
+using System.Collections.Generic;
+using System;
+using System.Collections.Immutable;
+using System.ComponentModel;
+using System.Diagnostics.CodeAnalysis;
+using System.Linq;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp.Testing;
+using Microsoft.CodeAnalysis.Diagnostics;
+using Microsoft.CodeAnalysis.Testing;
+using WinRT;
+using Microsoft.CodeAnalysis.CSharp;
+
+namespace SourceGeneratorTest.Helpers;
+
+///
+/// A custom for testing diagnostic suppressors.
+///
+/// The type of the suppressor to test.
+// Adapted from https://github.com/ImmediatePlatform/Immediate.Validations
+public sealed class CSharpSuppressorTest : CSharpAnalyzerTest
+ where TSuppressor : DiagnosticSuppressor, new()
+{
+ ///
+ /// The list of analyzers to run on the input code.
+ ///
+ private readonly List _analyzers = [];
+
+ ///
+ /// Whether to enable unsafe blocks.
+ ///
+ private readonly bool _allowUnsafeBlocks;
+
+ ///
+ /// The C# language version to use to parse code.
+ ///
+ private readonly LanguageVersion _languageVersion;
+
+ ///
+ /// Creates a new instance with the specified parameters.
+ ///
+ /// The source code to analyze.
+ /// Whether to enable unsafe blocks.
+ /// The language version to use to run the test.
+ public CSharpSuppressorTest(
+ string source,
+ bool allowUnsafeBlocks = true,
+ LanguageVersion languageVersion = LanguageVersion.CSharp12)
+ {
+ _allowUnsafeBlocks = allowUnsafeBlocks;
+ _languageVersion = languageVersion;
+
+ TestCode = source;
+ TestState.ReferenceAssemblies = ReferenceAssemblies.Net.Net80;
+ TestState.AdditionalReferences.Add(MetadataReference.CreateFromFile(typeof(ComWrappersSupport).Assembly.Location));
+ }
+
+ ///
+ protected override IEnumerable GetDiagnosticAnalyzers()
+ {
+ return base.GetDiagnosticAnalyzers().Concat(_analyzers);
+ }
+
+ ///
+ protected override CompilationOptions CreateCompilationOptions()
+ {
+ return new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, allowUnsafe: _allowUnsafeBlocks);
+ }
+
+ ///
+ protected override ParseOptions CreateParseOptions()
+ {
+ return new CSharpParseOptions(_languageVersion, DocumentationMode.Diagnose);
+ }
+
+ ///
+ /// Adds a new analyzer to the set of analyzers to run on the input code.
+ ///
+ /// The type of analyzer to activate.
+ /// The current test instance.
+ public CSharpSuppressorTest WithAnalyzer(
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] string assemblyQualifiedTypeName)
+ {
+ _analyzers.Add((DiagnosticAnalyzer)Activator.CreateInstance(Type.GetType(assemblyQualifiedTypeName)));
+
+ return this;
+ }
+
+ ///
+ /// Specifies the diagnostics to enable.
+ ///
+ /// The set of diagnostics.
+ /// The current test instance.
+ public CSharpSuppressorTest WithSpecificDiagnostics(params DiagnosticResult[] diagnostics)
+ {
+ ImmutableDictionary diagnosticOptions = diagnostics.ToImmutableDictionary(
+ descriptor => descriptor.Id,
+ descriptor => descriptor.Severity.ToReportDiagnostic());
+
+ // Transform to enable the diagnostics
+ Solution EnableDiagnostics(Solution solution, ProjectId projectId)
+ {
+ CompilationOptions options =
+ solution.GetProject(projectId)?.CompilationOptions
+ ?? throw new InvalidOperationException("Compilation options missing.");
+
+ return solution.WithProjectCompilationOptions(
+ projectId,
+ options.WithSpecificDiagnosticOptions(diagnosticOptions));
+ }
+
+ SolutionTransforms.Clear();
+ SolutionTransforms.Add(EnableDiagnostics);
+
+ return this;
+ }
+
+ ///
+ /// Specifies the diagnostics that should be produced.
+ ///
+ /// The set of diagnostics.
+ /// The current test instance.
+ public CSharpSuppressorTest WithExpectedDiagnosticsResults(params DiagnosticResult[] diagnostics)
+ {
+ ExpectedDiagnostics.AddRange(diagnostics);
+
+ return this;
+ }
+}
+
+///
+/// Extensions for .
+///
+file static class DiagnosticSeverityExtensions
+{
+ ///
+ /// Converts a value into a one.
+ ///
+ public static ReportDiagnostic ToReportDiagnostic(this DiagnosticSeverity severity)
+ {
+ return severity switch
+ {
+ DiagnosticSeverity.Hidden => ReportDiagnostic.Hidden,
+ DiagnosticSeverity.Info => ReportDiagnostic.Info,
+ DiagnosticSeverity.Warning => ReportDiagnostic.Warn,
+ DiagnosticSeverity.Error => ReportDiagnostic.Error,
+ _ => throw new InvalidEnumArgumentException(nameof(severity), (int)severity, typeof(DiagnosticSeverity)),
+ };
+ }
+}
\ No newline at end of file