Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# foreach的分支机构覆盖率?_C#_Asp.net_Visual Studio 2010_Opencover - Fatal编程技术网

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个测试都会运行(没有警告/消息),也许您需要进一步阐述您认为的问题。