SonarSource / sonar-dotnet

Code analyzer for C# and VB.NET projects
https://redirect.sonarsource.com/plugins/csharp.html
GNU Lesser General Public License v3.0
772 stars 226 forks source link

[ExcludeFromCodeCoverage] ignored when using top level statements and partial Program #9562

Open im-aIex opened 1 month ago

im-aIex commented 1 month ago

Description

Similar to #5660, when using [ExcludeFromCodeCoverage] on a partial Program class with top level statements the code is not excluded from Code Coverage, even though the coverage report itself does not contain the class/lines.

Repro steps

Console.Write("Hello World");

[ExcludeFromCodeCoverage]
public partial class Program { }

Expected behavior

Lines are excluded from code coverage metrics.

Actual behavior

Lines are included in code coverage metrics.

Known workarounds

Remove top level statements

[ExcludeFromCodeCoverage]
public class Program 
{
    public static void Main(string[] args)
    {
        Console.Write("Hello World");
    }
}

Related information

im-aIex commented 1 month ago

In doing further workaround troubleshooting, removing [ExcludeFromCodeCoverage] and including <ExcludeByFile>**/Program.cs</ExcludeByFile> within the .runsettings is also ignored.

All the documentation points to SonarQube just using the reports generated for coverage, which seems to be the case when using the CLI scanner, but the MSBuild scanner appears to be calculating its own "lines to cover" that does not appear to follow many conventions used to control dotnet coverage.

sebastien-marichal commented 1 month ago

Hello @im-aIex,

Thank you for reporting this issue.

I was able to reproduce this issue. I will add it to our backlog so we can fix it in the future. When calculating the executable line of code, we don't consider that global statements could be part of a class with the ExcludeFromCodeCoverage attribute.

... the MSBuild scanner appears to be calculating its own "lines to cover" that does not appear to follow many conventions used to control dotnet coverage.

Could you point out which conventions you are talking about?

Thank you,

im-aIex commented 1 month ago

Both [ExcludeFromCodeCoverage] and utilizing .runsettings are common ways of controlling coverage analysis within dotnet. These are accounted for in the report that is generated and sent to SonarQube, so - based on the documentation - the expectation is that SonarQube would also account for it. Instead, it appears the MSBuild scanner is calculating its own "lines to cover" that is prone to differ from the report.

.runsettings seems like a larger issue in that we can have complex rules configured that would need to be mirrored in the sonar properties.