Roslyn 代码修复测试也为固定代码样本调用“VerifyDiagnostics”,这使得测试永远不会成功

Roslyn code-fix test calls `VerifyDiagnostics` also for fixed-code-sample, which makes test could never be successfull


#UPD: 这完全是我的错误。我在回答中发布的一些细节


为什么 Roslyn 代码修复测试调用 VerifyDiagnostics 不仅针对 test-source-code-sample,而且还针对 fixed-code-sample?

Visual Studio 模板项目“Analyzer with Code Fix”的单元测试依赖于这样的方法:

public static async Task VerifyCodeFixAsync(
    /*1*/ string source, 
    /*2*/ DiagnosticResult[] expected, 
    /*3*/ string fixedSource)
{
    var test = new Test
    {
        TestCode = source,
        FixedCode = fixedSource,
    };

    test.ExpectedDiagnostics.AddRange(expected);
    await test.RunAsync(CancellationToken.None);
}

我是这样理解争论的:

/*1*/ - 测试代码示例,有意的问题测试分析器可以找到它们

/*2*/ - 预期 - 关于这些故意问题的特殊数据(包括每个问题的位置)

/*3*/ - 固定代码示例 - 这是测试代码示例在某些地方应用自动代码修复后应该看起来的样子,分析器已经找到

所以,我希望 test.RunAsync(在最后一行调用)应该在类似于以下的场景中工作:

这就是我所期望的。

但是!如果您查看 class Microsoft.CodeAnalysis.Testing.CodeFixTest<> 的源代码,您可以找到 RunAsync 方法的此类实现:

public override async Task RunAsync(CancellationToken cancellationToken = default)
{
    ...
    await VerifyDiagnosticsAsync(new EvaluatedProjectState(testState, ...);  // <--- Line A

    if (CodeFixExpected())
    {
        await VerifyDiagnosticsAsync(new EvaluatedProjectState(fixedState, ...);  // <--- Line B
        ...
    }
}

在我的分析器的情况下,结果为:

Assert.AreEqual failed. Expected:<1>. Actual:<0>. Context: Diagnostics of fixed state

'因为它看起来有点像将固定代码示例中发现的问题与 expected 进行比较(我认为这是一个错误,因为固定代码不应包含问题(根据定义))


#UPD: Roslyn 代码是正确的。这是我的错误 - 请参阅我发布的答案。


Assert.AreEqual failed. Expected:<0>. Actual:<1>. Context: Diagnostics of test state

所以我的问题是:为什么 Roslyn 代码修复测试将 expected 与两者进行比较(第一个是测试代码示例,正如我完全预期的那样),然后是固定代码示例,这使得测试永远不可能成功?

或者我遗漏了什么...

如有任何想法,我将不胜感激

我明白了。 这都是我的错。我错误地使用了 CSharpCodeFixVerifier 和另一个 AnalyzerCodeFixProvider 参数化(不是我应该在那里使用的那个)。

因此,VerifyDiagnostics 的第二次调用(使用固定代码样本作为 state 参数)是正确的。而且,我想,它会检查固定代码示例是否没有诊断出问题。