2

I have found the following problem, while working with switch cases. R# showed me a simplification of the switch statement, which basically binds a delegate to the case label when you assign a variable.

var shape = shapeType switch
{
    ShapeType.Ellipse => new Ellipse(),
    ShapeType.Polygon => new Polygon(),
    _ => new Rectangle()
};

The benefit of this is readability for huge switch cases, because you basically save two thirds of the lines, for assigning switches.

My problem: I really like this type of switches, since it improves the readability, but this is not considered in the Code Coverage Tool of Visual Studio (VS Enterprise 2019 - 16.4.4). Since our policy strives towards a ~90% Code Coverage, each percent is valuable.

Is there a possibility to include these Switches in the Code Coverage?

Kate Orlova
  • 3,225
  • 5
  • 11
  • 35
  • Use the attribute `[ExcludeFromCodeCoverage]` ? – Cid Feb 27 '20 at 13:00
  • 1
    We are not allowed to use [ExcludeFromCodeCoverage] in such circumstances. Otherwise people would spam it, which reduces the value of the Code Coverage. We are allowed to modify the "CodeCoverage.runsettings", but only to exclude entire functions, classes or namespaces. –  Feb 27 '20 at 13:31
  • It's actually called a [`switch expression`](https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8#switch-expressions) – Matthew Watson Feb 27 '20 at 13:50
  • If you have a good repro for this, you should file a bug/issue against the tool. This is likely the result of the language features and compiler team getting ahead of the code coverage team. Make sure to describe the impact it has on you dev processes – Flydog57 Feb 27 '20 at 15:00

1 Answers1

1

Kate has a point here. My projects have a code coverage threshold of a hard 100%, and switch expressions are never completely covered, even if the equivalent switch statement is.

Here is an example:

The following switch statement provides 100% of code coverage in my project:

switch (values[3])
{
    case "F": return new string(Convert.ToString(value, 2).Reverse().ToArray()).PadRight(max, '0');
    case "G": return $"{value} of {max}";
    case "R" when value == 0: return $"none of {max}";
    case "R" when value == 1: return $"1st of {max}";
    case "R" when value == 2: return $"2nd of {max}";
    case "R" when value == 3: return $"3rd of {max}";
    default: return $"{value}th of {max}";
}

The equivalent switch expression gives only 99.91%, and the build on Jenkins fails:

return values[3] switch
{
    "F" => new string(Convert.ToString(value, 2).Reverse().ToArray()).PadRight(max, '0'),
    "G" => $"{value} of {max}",
    "R" when value == 0 => $"none of {max}",
    "R" when value == 1 => $"1st of {max}",
    "R" when value == 2 => $"2nd of {max}",
    "R" when value == 3 => $"3rd of {max}",
    _ => $"{value}th of {max}"
};

And the code coverage coloring does not indicate what branch is not being covered since it marks the whole statement.

I think this is a problem with how the compiler produces the final IL of the expression. It should be addressed as a C# bug and submitted to Microsoft to be fixed.

Andre Vianna
  • 1,713
  • 2
  • 15
  • 29
  • ok this answers my question - having the same issue w/ new C# 8.0 switch feature and it slightly lowering code coverage – Poat Sep 04 '20 at 20:49