C# foreach的分支机构覆盖率?
我有一个简单的方法来计算一个集合的总数C# foreach的分支机构覆盖率?,c#,asp.net,visual-studio-2010,opencover,C#,Asp.net,Visual Studio 2010,Opencover,我有一个简单的方法来计算一个集合的总数 public void MethodToTest(Collection<int> collection) { int sum = 0; foreach (int value in collection) { sum += value; } } public void方法测试(集合) { 整数和=0; foreach(集合中的int值) { 总和+=数值; } } 目标是使用在命令行中运行的op
public void MethodToTest(Collection<int> collection)
{
int sum = 0;
foreach (int value in collection)
{
sum += value;
}
}
public void方法测试(集合)
{
整数和=0;
foreach(集合中的int值)
{
总和+=数值;
}
}
目标是使用在命令行中运行的opencoverage工具获得100%的分支覆盖率。我还得到了一个调用MethodToTest方法的单元测试:
[TestMethod]
public void TestMethodToTest()
{
BomProviderMock mock = new BomProviderMock();
BomManager bomManager = new BomManager(mock);
List<int> list = new List<int>();
for (int i = 0; i <= Int16.MaxValue; i++)
{
list.Add(i);
}
// Firts attempt with a non empty collection
bomManager.MethodToTest(new Collection<int>(list));
// Second attempt with an empty collection
bomManager.MethodToTest(new Collection<int>());
}
[TestMethod]
公共void TestMethodToTest()
{
BomProviderMock=新的BomProviderMock();
BomManager BomManager=新BomManager(模拟);
列表=新列表();
对于(int i=0;i我已经更新了您的问题,使用了一些linq而不是foreach循环。它需要一个随机数(虽然大小相同),因此编译器不会“拂袖而去”而不得不计算它
我建议对方法中的总和做些什么,或者返回它,这可能会改变您的结果
最后,但并非最不重要的一点是,不要痴迷于100%。这永远不会发生在现实生活中的大型项目中。只要确保您测试可能会中断的事情,并在构建软件时考虑到测试,这样做会很容易
void Main()
{
Random r = new Random();
List<int> list = Enumerable.Range(1,Int16.MaxValue)
.Select (e => r.Next(0,Int16.MaxValue))
.ToList();
// Firts attempt with a non empty collection
MethodToTest(new Collection<int>(list));
// Second attempt with an empty collection
MethodToTest(new Collection<int>());
}
// Define other methods and classes here
public void MethodToTest(Collection<int> collection)
{
var sum = collection.Sum (i => i);
// do something with it. If you're just voiding it and it doesn't get
// used, it might be removed by compiler.
}
void Main()
{
随机r=新随机();
列表=可枚举的.Range(1,Int16.MaxValue)
.Select(e=>r.Next(0,Int16.MaxValue))
.ToList();
//首次尝试使用非空集合
MethodToTest(新集合(列表));
//第二次尝试使用空集合
MethodToTest(新集合());
}
//在此处定义其他方法和类
公共无效方法测试(集合集合)
{
var sum=collection.sum(i=>i);
//用它做点什么。如果你只是在排尿,但它没有得到
//使用时,编译器可能会将其删除。
}
正如[原始]公认的答案所指出的,您的实际场景减少为collection.Sum()
,但是您不能每次都逃脱这个惩罚
如果我们使用TDD来开发此功能(我同意,但很容易解释),我们将[可能]执行以下操作(出于偏好,我在本例中也使用NUnit)
为了满足这些测试,我需要修改我的代码
public int MethodToTest(Collection<int> collection)
{
var sum = 0;
foreach (var value in collection)
{
sum += value;
}
return sum;
}
public int MethodToTest(Collection<int> collection)
{
var sum = 0;
if (collection != null)
{
foreach (var value in collection)
{
sum += value;
}
}
return sum;
}
public int MethodToTest(IEnumerable<int> collection)
{
return (collection ?? new int[0]).Sum();
}
测试失败了,所以我们需要更新我们的代码
public int MethodToTest(Collection<int> collection)
{
var sum = 0;
foreach (var value in collection)
{
sum += value;
}
return sum;
}
public int MethodToTest(Collection<int> collection)
{
var sum = 0;
if (collection != null)
{
foreach (var value in collection)
{
sum += value;
}
}
return sum;
}
public int MethodToTest(IEnumerable<int> collection)
{
return (collection ?? new int[0]).Sum();
}
public int MethodToTest(集合)
{
var总和=0;
if(集合!=null)
{
foreach(集合中的var值)
{
总和+=数值;
}
}
回报金额;
}
现在我们有了支持代码的测试,而不是测试代码的测试,也就是说,我们的测试并不关心我们如何编写代码
现在我们有了一套好的测试,这样我们就可以安全地重构代码了
public int MethodToTest(Collection<int> collection)
{
var sum = 0;
foreach (var value in collection)
{
sum += value;
}
return sum;
}
public int MethodToTest(Collection<int> collection)
{
var sum = 0;
if (collection != null)
{
foreach (var value in collection)
{
sum += value;
}
}
return sum;
}
public int MethodToTest(IEnumerable<int> collection)
{
return (collection ?? new int[0]).Sum();
}
public int MethodToTest(IEnumerable集合)
{
返回(集合??新整数[0]).Sum();
}
我这样做并没有影响任何现有的测试
我希望这能有所帮助。您可以不使用集合的扩展方法foreach
并创建委托,而不是编写foreach吗?我使用其他代码覆盖工具(DotCover)运行代码示例我得到了100%的代码覆盖率。可能是因为代码得到了优化并且没有被覆盖工具计算在内,所以没有包括sum+=value;
?添加语句Debug.WriteLine(sum);
在这种情况下可能会有所帮助。OpenCover查看通过编译代码生成的IL,有时编译器添加的分支IL语句超过了您可以映射到代码的数量,因此很难使用OpenCover获得100%的分支覆盖率。有时团队会考虑优化一些分支,但并不经常(我将把这一点添加到候选人名单中)。我同意——编写测试以获得覆盖率是错误的,在现实生活中,100%的分支覆盖率通常是不可能的(如果你沉迷于此,你也会发疯)。注意编写正确的测试和/或使用TDD实践并遵循坚实的原则,开始看起来很难,但从长远来看会带来好处。你应该+1'ed它,以表示你的感激:)(尽管如此,在你的统计数据上看到整数总是很好…比如…100%)我不是通过foreach循环获得100%的分支覆盖率,而是通过Collection.Sum()获得我能够…最后,问题是OpenCover的版本。我正在使用v.4.5.2506并更新到v.4.5.3207,通过foreach循环实现100%的分支覆盖率。尽管如此,这些响应非常有用。谢谢。TTD为+1,这是一个很好的示例。当您使用TestCase
时,您不需要用NUnit返回测试吗?嗯…这是我写的一篇文章。如果您有一个带有TestCase(…)
标题的void
方法,我会得到一个:Test-ignored:Test方法有一个void返回类型,但预期结果是(使用nunit)@Noctis你可能正在使用Resharper吗?如果是这样,你需要升级,因为这是一个老问题,是的,我是。虽然是最新和最伟大的(8.2.2)。你发布的链接是另一种方式(有一个应该是无效的东西返回)。我的评论是关于它需要一个结果,但您的签名是无效的。在命令行和VS with ReSharper中对我来说效果很好-所有5个测试都会运行(没有警告/消息),也许您需要进一步阐述您认为的问题。