
How it works...
The analyzer unit test project allows us to write unit tests for the execution of our analyzer on different code samples. Each unit test is marked with a TestMethod attribute and defines sample test code, expected diagnostic(s) reported by the analyzer on that code (if any), and invocation of test helper method(s), here VerifyCSharpDiagnostic, to verify diagnostics.
//No diagnostics expected to show up
[TestMethod]
public void TestMethod1()
{
var test = @"";
VerifyCSharpDiagnostic(test);
}
Unit tests can define expected diagnostics using the DiagnosticResult type, which must specify the diagnostic Id, Message, Severity and Locations for the diagnostic:
var expected = new DiagnosticResult
{
Id = "CSharpAnalyzers",
Message = String.Format("Type name '{0}' contains lowercase letters", "Class1"),
Severity = DiagnosticSeverity.Warning,
Locations = new[] { new DiagnosticResultLocation("Test0.cs", 11, 15) }
};
VerifyCSharpDiagnostic(test, expected);
UnitTest type containing all the unit tests also overrides the following methods to return the DiagnosticAnalyzer (and optionally a CodeFixProvider) to be tested:
protected override CodeFixProvider GetCSharpCodeFixProvider()
{
return new CSharpAnalyzersCodeFixProvider();
}
protected override DiagnosticAnalyzer GetCSharpDiagnosticAnalyzer()
{
return new CSharpAnalyzersAnalyzer();
}
Now, let us expand a bit more on the test framework helpers for the unit tests. The analyzer unit test project contains two primary helper abstract types to write unit tests for analyzers and code fixes:
- DiagnosticVerifier: Contains helper methods to run DiagnosticAnalyzer unit tests that verify the analyzer diagnostics for a given set of test sources.
- CodeFixVerifier: Contains helper methods to run DiagnosticAnalyzer and CodeFixProvider unit tests that verify the analyzer diagnostics for a given set of test sources before and after applying a code fix. This type derives from DiagnosticVerifier.
In the default analyzer project, UnitTest type derives from CodeFixVerifier, but could also be changed to derive from DiagnosticVerifier, if you are only interested in writing analyzer unit tests. We will just focus on the DiagnosticVerifier here; CodeFixVerifier is covered later in chapter.
DiagnosticVerifier type is split into 2 source files DiagnosticVerifier.cs and DiagnosticVerifier.Helper.cs.

- DiagnosticVerifier.Helper.cs contains the following core functionality:
- Helper methods to create a compilation with source files based on given C# or VisualBasic source code (Set up compilation and documents region in the preceding screenshot).
- Helper methods to invoke the preceding functionality to create a compilation with the given C# or VisualBasic source code, and execute the given DiagnosticAnalyzer on the compilation to produce analyzer diagnostics and return sorted diagnostics for verification (Get Diagnostics region in the preceding screenshot).
- DiagnosticVerifier.cs contains the following core functionality:
- Method(s) to get the DiagnosticAnalyzer type to be tested (To be implemented by Test classes region in the preceding screenshot).
- Private helpers to perform actual diagnostic comparison and verification and formatting of diagnostics to get a string representation of actual/expected diagnostics when a unit test fails (Actual comparisons and verifications region and Formatting Diagnostics region in the preceding screenshot).
- Diagnostic verification methods VerifyCSharpDiagnostic and VerifyBasicDiagnostic that can be invoked by the unit tests to verify analyzer diagnostics generated on the given C# or Visual Basic source code (Verifier wrappers section in the preceding screenshot). These methods invoke the Get Diagnostics helpers to create a compilation and get sorted analyzer diagnostics and then invoke the preceding private helpers to compare and verify diagnostics.