danielpalme / ReportGenerator

ReportGenerator converts coverage reports generated by coverlet, OpenCover, dotCover, Visual Studio, NCover, Cobertura, JaCoCo, Clover, gcov or lcov into human readable reports in various formats.
https://reportgenerator.io
Apache License 2.0
2.56k stars 279 forks source link

Calculate C.R.A.P. Score from Cobertura file? #641

Closed rikrak closed 7 months ago

rikrak commented 7 months ago

Not so much a bug as a feature request/question.

When processing Cobertura files, would it be possible to also calculate the crap score? Corbertura itself doesn't provide a value for this metric, but it looks possible to calculate it from the Cyclomatic Complexity and Coverage values for each method using: CRAP(m) = CC(m)^2 * U(m)^3 + CC(m) Where CC(m) = Cyclomatic Complexity (e.g. 5) U(m) = Uncovered percentage (e.g. 30% = 0.3)

I've played about with the code locally and produced a report from cobertura that does this. Just wondering if this is worth working into a PR?

rikrak commented 7 months ago

For info, here's a snippet:

    // CoberturaParser.cs

        private static void SetMethodMetrics(CodeFile codeFile, IEnumerable<XElement> methodsOfFile)
        {
            foreach (var method in methodsOfFile)
            {
                string fullName = method.Attribute("name").Value + method.Attribute("signature").Value;
                fullName = ExtractMethodName(fullName, method.Parent.Parent.Attribute("name").Value);

               // ... abridged for clarity

                if (cyclomaticComplexity.HasValue && coveragePercent.HasValue)
                {
                    // https://testing.googleblog.com/2011/02/this-code-is-crap.html
                    // CRAP(m) = CC(m)^2 * U(m)^3 + CC(m)
                    // CC(m) <= Cyclomatic Complexity (e.g. 5)
                    // U(m) <= Uncovered percentage (e.g. 30% = 0.3)
                    var uncoveredPercent = (100f - (double)coveragePercent.Value) / 100.0;
                    var complexity = (double)cyclomaticComplexity.Value;
                    var crapScore = (Math.Pow(complexity, 3.0) * Math.Pow(uncoveredPercent, 2)) + complexity;

                    metrics.Insert(0, Metric.CrapScore((decimal)crapScore));
                }

               // ... abridged for clarity
            }
        }
danielpalme commented 7 months ago

@rikrak That sound great! If you like, you can create a PR, but I'm also able to use your snippet to add this metric. Just let me know how you would like to handle it.

rikrak commented 7 months ago

I'll put together a PR :-)

rikrak commented 7 months ago

I've submitted a PR. I'm quite new to contributing to OS projects, so let me know if the PR needs adjusting in any way :-)

danielpalme commented 7 months ago

Thank you!

danielpalme commented 6 months ago

Release 5.2.1 is now available containing the new metric!

rikrak commented 6 months ago

Terrific, I'll check it out tomorrow :-)