【发布时间】:2014-06-08 02:03:34
【问题描述】:
我怀疑答案是否定的,但我还是会问...
TL;DR
我知道我可以使用[ExcludeFromCodeCoverage] 属性从覆盖分析中排除一个类或方法,但是有没有办法只排除方法的部分?
具体例子
我有一个懒惰地生成int.MaxValue元素序列的方法:
private static IEnumerable<TElement> GenerateIterator<TElement>(Func<int, TElement> generator)
{
for (int i = 0; i < int.MaxValue; i++)
{
yield return generator(i);
}
}
在实践中,它永远不会完全枚举,因此永远不会到达方法的末尾。因此,DotCover 认为该方法的 20% 未被覆盖,并将右大括号突出显示为未覆盖(对应于生成的 MoveNext 方法中的 return false)。
我可以编写一个消耗整个序列的测试,但是运行需要很长时间,尤其是在启用覆盖的情况下。
所以我想找到一种方法告诉 DotCover 最后一条指令不需要被覆盖。
注意:我知道我真的不需要所有单元测试涵盖的代码;有些代码不能或不需要测试,我通常排除那些具有[ExcludeFromCodeCoverage] 属性的代码。但是我喜欢对我测试的代码有 100% 的报告覆盖率,因为这样可以更容易地发现代码中未测试的部分。当你知道没有什么要测试的时候,拥有一个覆盖率为 80% 的方法是很烦人的......
【问题讨论】:
-
好吧,这个方法是静态的,但我会考虑找到一种方法来替换
int.MaxValue,当你用可管理的东西进行测试时,除非这个值实际上是相关的。 -
@AnthonyPegram,这是个好主意;该值并不真正相关,我只想要一个几乎无限的序列。
-
另一方面,为了避免未覆盖的右大括号而使代码更复杂并不合适......
-
当然,我反对过度设计的论点。尽管如此,具有默认值 MaxValue 的内部静态最大计数器属性可能会有所帮助,并且不会增加任何真正显着的复杂性。然后,您的测试可以通过设置一个可行的值然后在适用时重置它来设置和拆除。 (这也需要将内部结构暴露给您的单元测试项目,如果您还没有这样做的话。)无论如何,只是一个想法。
-
如果你用延迟的 LINQ 查询替换它,这对代码覆盖也有用吗?即:
return Enumerable.Range(0, int.MaxValue).Select(generator);?编辑:本质上,您会将迭代/产生自身的“责任”转嫁给不计入代码覆盖率的 LINQ 代码。
标签: c# unit-testing code-coverage dotcover