-
Notifications
You must be signed in to change notification settings - Fork 388
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Coverage percentage output value rounded down with max 2 decimal precision #397
Coverage percentage output value rounded down with max 2 decimal precision #397
Conversation
Codecov Report
@@ Coverage Diff @@
## master #397 +/- ##
==========================================
+ Coverage 86.66% 86.96% +0.29%
==========================================
Files 16 16
Lines 2130 2178 +48
==========================================
+ Hits 1846 1894 +48
Misses 284 284 |
src/coverlet.core/CoverageDetails.cs
Outdated
get => Math.Round(Total == 0 ? 1 : Covered / Total, 4); | ||
} | ||
|
||
public double GetCoveragePercentage() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use property CoveragePercentace { get }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I can do that. Will convert method into prop CoveragePercentage { get }
src/coverlet.core/CoverageDetails.cs
Outdated
return RoundDown(percentage); | ||
} | ||
|
||
private double RoundDown(double percentage) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you avoid RoundDown
helper and use inline directly on CoveragePercentace
prop, if I'm not mistaken this helper is private and used only in one method so it's not so useful extract it as helper.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, its used only in one place as of now.
I forget to ask this earlier, Average Coverage Percentage value could go more than 2 decimal precision since its calculated inline.
coverageTable.AddRow("Average", $"{totalLinePercent / numModules}%", $"{totalBranchPercent / numModules}%", $"{totalMethodPercent / numModules}%");
Should I Floor the value with 2 decimal precision there also? Should I create MathHelper
class under Helper folder, add this RoundDown
method in the class & refer it in CoveragePercentage
property and also during Average calculation? Is this fine?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@MarcoRossignoli I have done other changes and ready for check-in. Also before & after report formats output.
I am waiting to see your reply on what to do with "Average Percentage" calculation and then check-in code fully at once either way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did deeper review...and I think that we should change a bit the idea.
We should avoid to change CoverageDetail
object only to "round data", I don't like the idea to have members with same meaning but only different "formatting" seems a duplication to me, I mean GetCoveragePercentage
is Percent
formatted.
I like the idea of double MathHelper.RoundPercentage(double)
in a file MathHelper.cs under Helpers folder and apply this helper in every place we need, in this way we can also apply it on Average Coverage Percentage
.
For instance
var totalLinePercent = MathHelper.RoundPercentage(summary.CalculateLineCoverage(result.Modules).Percent * 100);
...
var method = MathHelper.RoundPercentage(summary.CalculateMethodCoverage(module.Value));
...
coverageTable.AddRow("Average", $"{MathHelper.RoundPercentage(totalLinePercent / numModules)}%",...
In this way we have also cetralized "percentage rounding" that we can apply in a uniform way in all codebase project.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could be cute to have an extension method
namespace Coverlet.Core.Helpers
{
public static MathHelper
{
public static double RoundPercentage(this double value)
{
...
}
}
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The idea of helper was for future possible use of rounding percentage everywhere in same way, btw I'm ok also with this with "fix" where we need like above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am planning to do both. Use Percent
property only but add extension method in new MathHelper.cs
class as public static double RoundPercentage(this double value)
.
So, it will be like Percent => { Total == 0? 1: ((Covered/Total)*100).RoundPercentage() }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sasivishnu avoid helper at all, less code to review and maintain, if in future we'll need to reuse we'll move to helper, put all round alg in prop getter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @sasivishnu, let me know when you'd done this so I can merge. The rest of the code seems good to me
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tonerdo Yep, I am done with my changes and pushed latest one.
@sasivishnu can you please run before/after coverage with all format and show result to PR(like comment or attaching files) we need to be sure that reports are ok. |
@MarcoRossignoli Yeah, I can do that. I will attach before and after reports for all five formats with console output too. |
@@ -17,13 +17,13 @@ public void TestReport() | |||
result.Identifier = Guid.NewGuid().ToString(); | |||
|
|||
result.Modules = new Modules(); | |||
result.Modules.Add("Coverlet.Core.Reporters.Tests", CreateFirstDocuments()); | |||
result.Modules.Add("Coverlet.Core.Reporters.Tests", CreateFirstDocuments()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
result.Modules.Add("Coverlet.Core.Reporters.Tests", CreateFirstDocuments()); | |
result.Modules.Add("Coverlet.Core.Reporters.Tests", CreateFirstDocuments()); |
src/coverlet.core/CoverageDetails.cs
Outdated
@@ -8,7 +8,18 @@ public class CoverageDetails | |||
public int Total { get; internal set; } | |||
public double Percent | |||
{ | |||
get => Math.Round(Total == 0 ? 1 : Covered / Total, 3); | |||
get => Math.Round(Total == 0 ? 1 : Covered / Total, 4); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All rounding down and decimal place code should go here
src/coverlet.console/Program.cs
Outdated
var totalLinePercent = summary.CalculateLineCoverage(result.Modules).Percent * 100; | ||
var totalBranchPercent = summary.CalculateBranchCoverage(result.Modules).Percent * 100; | ||
var totalMethodPercent = summary.CalculateMethodCoverage(result.Modules).Percent * 100; | ||
var totalLinePercent = summary.CalculateLineCoverage(result.Modules).GetCoveragePercentage(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can just be var totalLinePercent = summary.CalculateLineCoverage(result.Modules).Percent
if you update the Percent
property to contain the necessary calculations. Applies everywhere this new method is used
… percentage value with max two decimal precision.
@MarcoRossignoli I have attached before and after sample report in first comment |
src/coverlet.core/CoverageDetails.cs
Outdated
{ | ||
get => Math.Round(Total == 0 ? 1 : Covered / Total, 3); | ||
} | ||
public double Percent => Total == 0 ? 1D : Math.Floor((Covered / Total) * 10000) / 100; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should be 100D
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, good catch. Thanks. Will push the new commit with fix
Files compared and looks ok to me there is only expected extra decimal for cobertura |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM thank's a lot @sasivishnu!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
Reports-After_Change.zip
Reports-Before_Change.zip
Related to issue #382
Change Details:
0.1400D * 100 = 14.000000000000002
Before: 0.143
After: 0.1432
Before: 33.3
After: 33.33
Before: 33.3
After: 33.33
I also updated and added new test cases to cover for the changes. Previously, we are rounding with max 3 decimal points before multiplying with 100. This yields value like 81.5%. I had to increase that to max 4 decimal points to yield like 81.52% when multiplied with 100%. In large projects, two decimal point reporting is useful and allows for incremental valuation without too much data loss after rounding down. Also I think, 2 decimal precision is commonly accepted standard.
Let me know If I missed something. Thanks
Edit: I have attached output for reports before my change (Coverlet.Console version 1.5.0) and after my change in zip.
Sample console output in version 1.5.0:
Sample console output after my change: