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

问题描述


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


为什么 Roslyn 代码修复测试不仅为 test-source-code-sample 调用 VerifyDiagnostics,而且还为 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(在最后一行调用)应该在类似于以下场景的幕后工作:

  • 第一次将分析器发现的问题与 expecteds 进行比较 - 它们应该相等
  • 第二次将自动代码修复应用于测试代码示例
  • 最后比较上一个生成的代码。步骤,提供 fixedSource (/*3*/)

这就是我所期望的。

但是!如果您查看类 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
        ...
    }
}

如果我的分析仪:

  • 如果我通过了not-empty expected,则在行 B 处测试失败并显示消息:

Assert.AreEqual 失败。预期:1>。实际:0>。语境: 固定状态

的诊断

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


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


  • 如果我通过 empty expected,B 行应该得到满足,但在 A 行测试失败(这次很正常)并显示消息:立>

Assert.AreEqual 失败。预期:0>。实际:1>。语境: 测试状态

的诊断

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

也许我遗漏了什么......

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

解决方法

我想通了。 这都怪我。我错误地将 CSharpCodeFixVerifier 与另一个 AnalyzerCodeFixProvider 参数化(不是我应该在那里使用的那个)。

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

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...