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
(在最后一行调用)应该在类似于以下的场景中工作:
- 第 1 次将分析器发现的问题与
expecteds
进行比较 - 它们应该相等
- 第二次对测试代码样本应用自动代码修复
- 最后比较代码,由 prev 生成。步骤,提供
fixedSource
(/*3*/
)
这就是我所期望的。
但是!如果您查看 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
...
}
}
在我的分析器的情况下,结果为:
- 如果我通过 not-empty
expected
,测试在第 B 行失败并显示消息:
Assert.AreEqual failed. Expected:<1>. Actual:<0>. Context:
Diagnostics of fixed state
'因为它看起来有点像将固定代码示例中发现的问题与 expected
进行比较(我认为这是一个错误,因为固定代码不应包含问题(根据定义))
#UPD: Roslyn 代码是正确的。这是我的错误 - 请参阅我发布的答案。
- 如果我通过empty
expected
,B行应该满足,但是在A[=行测试失败(这次是意料之中的) 79=] 消息:
Assert.AreEqual failed. Expected:<0>. Actual:<1>. Context:
Diagnostics of test state
所以我的问题是:为什么 Roslyn 代码修复测试将 expected
与两者进行比较(第一个是测试代码示例,正如我完全预期的那样),然后是固定代码示例,这使得测试永远不可能成功?
或者我遗漏了什么...
如有任何想法,我将不胜感激
我明白了。
这都是我的错。我错误地使用了 CSharpCodeFixVerifier
和另一个 AnalyzerCodeFixProvider
参数化(不是我应该在那里使用的那个)。
因此,VerifyDiagnostics
的第二次调用(使用固定代码样本作为 state
参数)是正确的。而且,我想,它会检查固定代码示例是否没有诊断出问题。
#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
(在最后一行调用)应该在类似于以下的场景中工作:
- 第 1 次将分析器发现的问题与
expecteds
进行比较 - 它们应该相等 - 第二次对测试代码样本应用自动代码修复
- 最后比较代码,由 prev 生成。步骤,提供
fixedSource
(/*3*/
)
这就是我所期望的。
但是!如果您查看 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
...
}
}
在我的分析器的情况下,结果为:
- 如果我通过 not-empty
expected
,测试在第 B 行失败并显示消息:
Assert.AreEqual failed. Expected:<1>. Actual:<0>. Context: Diagnostics of fixed state
'因为它看起来有点像将固定代码示例中发现的问题与 expected
进行比较(我认为这是一个错误,因为固定代码不应包含问题(根据定义))
#UPD: Roslyn 代码是正确的。这是我的错误 - 请参阅我发布的答案。
- 如果我通过empty
expected
,B行应该满足,但是在A[=行测试失败(这次是意料之中的) 79=] 消息:
Assert.AreEqual failed. Expected:<0>. Actual:<1>. Context: Diagnostics of test state
所以我的问题是:为什么 Roslyn 代码修复测试将 expected
与两者进行比较(第一个是测试代码示例,正如我完全预期的那样),然后是固定代码示例,这使得测试永远不可能成功?
或者我遗漏了什么...
如有任何想法,我将不胜感激
我明白了。
这都是我的错。我错误地使用了 CSharpCodeFixVerifier
和另一个 AnalyzerCodeFixProvider
参数化(不是我应该在那里使用的那个)。
因此,VerifyDiagnostics
的第二次调用(使用固定代码样本作为 state
参数)是正确的。而且,我想,它会检查固定代码示例是否没有诊断出问题。