简体   繁体   English

NCover:从coverage中排除不可执行的代码行

[英]NCover: Exclude unexecutable line of code from coverage

The switch statement in following code has a default clause that is required by the compiler and a nice safeguard, but which is never executed. 以下代码中的switch语句具有编译器所需的default子句和一个很好的安全措施,但从未执行过。 After writing tests for everything else, there is no way I can (or should) test that one line. 在为其他一切编写测试之后,我无法(或应该)测试那一行。 I don't care that I haven't covered that line with tests, but my TestDriven.net NCover code coverage report does show the untested line and this causes the class coverage to drop to 86%. 我不在乎我没有用测试覆盖那一行,但是我的TestDriven.net NCover代码覆盖率报告确实显示了未经测试的行,这导致类覆盖率降至86%。 Is there a way to let NCover exclude just this one line? 有没有办法让NCover排除这一行?

public static class OperandTypeExtensions
{
    public static string ToShortName(this OperandType type)
    {
        #region Contract
        Contract.Requires<InvalidEnumArgumentException>(Enum.IsDefined(typeof(OperandType), type));
        #endregion

        switch (type)
        {
            case OperandType.None: return "<none>";
            case OperandType.Int32: return "i32";
            case OperandType.Int64: return "i64";
            default:
                throw new NotSupportedException();
        }
    }
}

My question is similar to this question , but none of the answers help in my specific situation. 我的问题类似于这个问题 ,但没有一个答案有助于我的具体情况。

You can exercise it by casting integer value, which is not exists in OperandType enumeration to OperandType: 您可以通过将OperandType枚举中不存在的整数值转换为OperandType来执行它:

Assert.Throws<InvalidEnumArgumentException>(delegate { ((OperandType)Int32.MaxValue).ToShortName(); } );

BTW I see nothing bad in 86% coverage 顺便说一句,我发现86%的报道并没有什么不好

UPDATE: There is no benefit of using Contract here. 更新:在此处使用Contract没有任何好处。 You will get exception anyway if value is not supported by your method. 如果您的方法不支持值,您将获得异常。

public static class OperandTypeExtensions
{
    public static string ToShortName(this OperandType type)
    {
        switch (type)
        {
            case OperandType.None: return "<none>";
            case OperandType.Int32: return "i32";
            case OperandType.Int64: return "i64";
            default:
                throw new NotSupportedException();
        }
    }
}

And you should have default option here, because if new value will be added to OperandType enum, your Contract will allow that value, but switch will not support new option. 你应该在这里有default选项,因为如果将新值添加到OperandType枚举,你的Contract将允许该值,但是switch不支持新选项。

UPDATE2: If you really need 100% coverage and Contract for this method, then use OperandType.None as default option: UPDATE2:如果您确实需要100%覆盖率和此方法的合同,则使用OperandType.None作为默认选项:

public static class OperandTypeExtensions
{
    public static string ToShortName(this OperandType type)
    {
        Contract.Requires<InvalidEnumArgumentException>(Enum.IsDefined(typeof(OperandType), type));

        switch (type)
        {
            case OperandType.Int32: return "i32";
            case OperandType.Int64: return "i64";
            default:
                return "<none>";
        }
    }
}

And add to your test assertion about enum: 并添加到关于枚举的测试断言:

CollectionAssert.AreEquivalent(Enum.GetValues(typeof(OperandType)), 
                               new OperandType[] { OperandType.Int32,
                                                   OperandType.Int64, 
                                                   OperandType.None });

I also wanted to reach 100% for all my source files, not for the % but to avoid double checking every class every time I run the Code Coverage tool for false positive. 我还希望我的所有源文件都达到100%,而不是%,但是为了避免每次运行代码覆盖率工具误报时对每个类进行双重检查。

In this case and IMO, if the function is public it means you shall test it with something similar : 在这种情况下和IMO,如果函数是公共的,这意味着你应该用类似的东西测试它

Assert.Throws<NotSupportedException>( OperandTypeExtensions.ToShortName() );

Other cases where it could occurs 可能发生的其他情况

Usually, a bigger problem occurs when the function in which the throws or the Debug.Assert is private. 通常,当throwsDebug.Assert为private的函数时会出现更大的问题。 In that case, sometimes the lines cannot be reached by tests. 在这种情况下,有时测试无法到达线条。 Or cannot be encapsulated in a Assert.Throws . 或者不能封装在Assert.Throws

The only way I found to ensure every line is executed. 我发现确保每一行都被执行的唯一方法。 Far from ideal and very ugly , I would have prefered a comment annotation like that to disable it. 远非理想和非常丑陋 ,我会喜欢这样的评论注释来禁用它。 Didn't work in C# though. 虽然没有在C#中工作。

private string ToShortName(this OperandType type)
{
    var result = "";
    switch (type)
    {
        case OperandType.Int32: result = "i32";
        case OperandType.Int64: result = "i64";
    }
    Debug.Assert(result != "", "Invalid type.");
    return result;
}

With this solution, in your source code it will break before returning the empty string (in Debug) and Code Coverage will see the Debug.Assert line as executed. 使用此解决方案,在源代码中,它将在返回空字符串之前中断(在Debug中),并且Code Coverage将看到Debug.Assert行已执行。

PS Although, I would like to know if there is a better solution, like annotation or something to disable specifically a code block. PS虽然,我想知道是否有更好的解决方案,如注释或某些东西来禁用特定的代码块。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM