C# 9/10 top-level statements and ExcludeFromCodeCoverage-Attribute?
Asked Answered
S

2

12

I usually set the attribute [ExcludeFromCodeCoverage] to my Program class, as there are no unit tests for this class possible anyways (or don't make sense either), so it doesn't show up as "missing" in the coverage report:

[ExcludeFromCodeCoverage]
public static class Program
{
    public static void Main(string[] args)
    {
       // do something awesome
    }
}

But with top-level statements I don't know how to handle this. It seems not to be possible to set attributes, as I found here: https://mcmap.net/q/910716/-attributes-on-c-9-top-level-statements-file

So far, I stick to the classic Class declaration, but maybe they thought about something else, when it comes to unit test code coverage?

Sales answered 26/4, 2022 at 8:24 Comment(0)
L
25

Since C# 10 the top-level statement generation was changed and now you can add partial Program class to the end of top-level statement (or in separate file) and add attribute to it:

[ExcludeFromCodeCoverage]
public partial class Program { }

Note that in initial feature specification (for C# 9) states that the actual names used by compiler are implementation dependent but since C# 10 and NET 6 using partial class is one of the recommended approaches for unit testing ASP.NET Core apps which use top-level statements.

But personally I would say that if you need such "advanced" scenarios you should switch back to the "plain old" Program classes.

Lycurgus answered 26/4, 2022 at 11:18 Comment(8)
That feels awful. What do you do with the other part of the partial that is implied by the use of the partial keyword?Melitamelitopol
@RobertHarvey what "other part"? The one generated by the compiler which contains all the stuff defined in the top-level statement?Lycurgus
Well, maybe I'm just too old, but when I used partial on a class, there was always another class in your source code with the same name having the partial moniker on it. Otherwise, why bother with partial, unless this is just some hacky thing to get around the problem at hand?Melitamelitopol
@RobertHarvey If you will not add patial to the Program class this will not compile due to conflict between Program class generated by the compiler and the one which was declared by programmer.Lycurgus
The last sentence in your post is good advice. This is a good use case for just using the traditional class declaration.Melitamelitopol
Is it possible to add it in a separate file instead of the end of Program.cs ? After all the only purpose of "partial" is to allow splitting the declaration of a class in several files. Declaring it in the same file is awkward.Quamash
@Quamash yes, totally. Just declare partial Program class.Lycurgus
This is hysterical. For what its worth, if someone on the C# team ever reads this I think supporting [class:AtributeName] would be a decent syntax for this. In the case where a transparent class is generated the keyword class: as opposed to assembly: seems like a consistent possible syntax.Upbraid
H
3

This is what worked for me (.NET 7):

[ExcludeFromCodeCoverage]
public static partial class Program { }

Looks like the generated Program class is static, so putting [ExcludeFromCodeCoverage] on non-static partial Program class doesn't apply to top-level code. Not sure why that is, can't find documentation stating that generated Program is static.

Highkey answered 11/10, 2023 at 23:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.