I won’t lie. As I thought about writing this post, I took special glee in contemplating the title. How should I talk about the CRAP metric? *Snicker*
I guess that just goes to show you that some people, like me, never truly grow up. Of course, I’m in good company with this, since the original authors of the metric had the same thought. They wanted to put some quantification behind the common, subjective declaration, “This code is crap!”
To understand that quantification, let’s first consider that CRAP is actually an acronym: C.R.A.P. It stands for change risk anti-patterns, so it addresses the risk of changing a bit of code. In other words, methods with high CRAP scores are risky to change. So the CRAP metric is all about assessing risk.
When you get a firm grasp on this metric, you get a nice way to assess risk in your codebase.
The CRAP Metric: Getting Specific
Okay, so how does one quantify risk of change? After all, there are a lot of ways that one could do this. Well, let’s take a look at the formula first. The CRAP score is a function of methods, so we’ll call it CRAP(m), mathematically speaking. (And yes, typing CRAP(m) made me snicker all over again.)
Let CC(m) = cyclomatic complexity of a method and U(m) = the percentage of a method not covered by unit tests.
CRAP(m) = CC(m)^2 * U(m)^3 + CC(m).
Alright, let’s unpack this a bit. To arrive at a CRAP score, we need a method’s cyclomatic complexity and its code coverage (or really lack thereof). With those figures, we multiply the square of a method’s complexity by the cube of its rate of uncovered code. We then add its cyclomatic complexity to that. I’ll discuss the why of that a little later, but first let’s look at some examples.
First, consider the simplest, least CRAP-y method imaginable: a method completely covered by tests and with no control flow logic. That method has a cyclomatic complexity of 1 and uncovered percentage of 0. That means that CRAP(m) = 1^2 * 0^3 + 1 = 1. So the minimum CRAP metric score is 1. What about a gnarly method with no test coverage and cyclomatic complexity of 6? CRAP(m) = 6^2 * 1^3 + 1 = 37.
The authors of this metric define a CRAP-y method as one with a CRAP score greater than 30, so that last method would qualify.