Closed fgimian closed 5 months ago
P.S.: I am using a Debug build and have also tried to execute cmdlet.Invoke().OfType<string>().ToList()
in the second test to be sure that the enumerator is fully exhausted, but sadly I see the same result.
Which version are you using?Can you try with nightly? https://github.com/coverlet-coverage/coverlet/blob/master/Documentation/ConsumeNightlyBuild.md
Which version are you using?Can you try with nightly? https://github.com/coverlet-coverage/coverlet/blob/master/Documentation/ConsumeNightlyBuild.md
Thanks so much for the reply Marco. I'm using the latest release available on nuget which is 3.0.3. I'll try the nightly as you recommended and let you know how I go. 😄
I just attempted this with the latest nightly 3.0.4-preview.32.gdc6edb1dd7 but sadly the problem persists. Would it assist you if I produced a complete minimal project / solution that demonstrated the problem so you can reproduce it?
P.S.: I'm not certain if this is relevant, but I am developing on .NET Core 3.1 as I am targeting PowerShell 7.0.x right now.
Here's a fully setup solution with related library and test projects.
I then invoke tests and Coverlet using:
dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=lcov /p:CoverletOutput='../lcov.info'
You will see that line 22 is not covered in the lcov output:
sls ",0$" .\lcov.info
I used the latest nightly build in this solution along with .NET 5.0 to rule out a specific issue with .NET Core 3.1.
Please let me know if I can provide any further info to help 😄
Thanks so much! Fotis
Thanks for the repro!
Hey there Marco, I've done a lot more digging and believe that I can explain what's going on a lot better. I also think I have a better solution for testing cmdlets which I'll post soon.
Ultimately, this is relatively vague territory as Microsoft don't provide a good guide for testing cmdlets written in C# using XUnit so one is left to dig deeper into the PowerShell source to figure out what's going on.
The summary is as follows:
As you'll see, the code that gets executed when calling WriteError is as follows:
public void WriteError(ErrorRecord errorRecord)
{
if (errorRecord.Exception != null)
throw errorRecord.Exception;
else
throw new InvalidOperationException(errorRecord.ToString());
}
I'll provide further information soon, but just thought I'd share an update with you in the meantime.
Huge thanks Fotis
Good news, as I suspected, I can reproduce the problem with a more succinct example which I've attached below:
The summary of the problem is that Coverlet will detect a closing brace if the method being called throws an exception. However, it will not detect the closing brace if the method calls another method, and the other method throws the exception.
e.g.
if (name == "BAD")
{
// PROBLEM HERE: If WriteError throws an exception, the closing brace below
// won't be counted by Coverlet.
_handler.WriteError();
}
else
{
// OK: Coverlet will cover the closing brace if the method directly throws the exception.
throw new ArgumentException("oh no");
}
I'm assuming this would be extremely hard to cater for, but perhaps you have an idea how to solve it?
Thanks again for all your help and time! Fotis
And one final update. I also tested this with OpenCover and it had the same problem as Coverlet.
Instructions for doing this via OpenCover (for your reference) are as follows:
# The following instructions assume you've installed OpenCover using the MSI installer
# provided at https://github.com/OpenCover/opencover/releases
# Create a directory for coverage reports
mkdir .coverage
# Run tests using OpenCover
~\AppData\Local\Apps\OpenCover\OpenCover.Console.exe `
-target:"dotnet.exe" `
-targetargs:"test" `
-output:".coverage\coverage.xml" `
-register:user -filter:"+[CoverletProblem]*"
# Install ReportGenerator globally
dotnet tool install -g dotnet-reportgenerator-globaltool
# Generate the coverage HTML report
ReportGenerator.exe -reports:".coverage\coverage.xml" -targetdir:".coverage"
# View in your browser
ii .coverage\index.html
Cheers Fotis
Thanks for all informations and for the repro!
In case it's useful to anyone, I've written a more detailed blog post on the approach I've used to overcome this while developing PowerShell cmdlets in C#.
This issue is stale because it has been open for 3 months with no activity.
This issue was closed because it has been inactive for 9 months since being marked as stale.
Hey there, firstly thank you so much for this incredible tool! 😄
When writing PowerShell cmdlets in C#, it is common to run the inherited
WriteError
to write non-terminating errors. Sadly it seems that Coverlet does not detect the closing brace in this scenario.Here's a simply demo example:
And here are the tests:
And as per the coverage report, the closing brace on line 22 is not covered:
Any ideas if there's a way to work through this?
Huge thanks! Fotis