我有这个验证密码的方法:
/**
* Checks if the given password is valid.
*
* @param password The password to validate.
* @return {@code true} if the password is valid, {@code false} otherwise.
*/
public static boolean validatePassword(String password) {
int len = password.length();
if (len < 8 || len > 20)
return false;
boolean hasLetters = false;
boolean hasDigits = false;
for (int i=0; i<len; i++) {
if (!Character.isLetterOrDigit(password.charAt(i)))
return false;
hasDigits = hasDigits || Character.isDigit(password.charAt(i));
hasLetters = hasLetters || Character.isLetter(password.charAt(i));
}
return hasDigits && hasLetters;
}
让我们关注圈复杂度数:它的价值是什么?
Metrics 1.3.6说这是7,但我找不到七条独立路径:我只找到5条! Wikipedia并没有多大帮助 - 我想如何使用这个公式π - s + 2
?
我有2个if
,1个for
和3个退出点,但我被困住了:我是否需要计算入口点?我应该计算第一个if
的两倍,因为它有两个条件吗?
修改
好的,现在我发现Cyclomatic Number是7.这意味着有7个独立的路径,所以如果我要覆盖100%的代码,我应该能找到7个不同的测试用例,对吗? / p> 嗯,我还是找不到最后一个! 我找到了这些:
答案 0 :(得分:3)
我认为诀窍在于计算逻辑运算符。
根据McCabe Cyclomatic Complexity部分下的指标链接(http://metrics.sourceforge.net/):
1初始流程
3个决策点(if,for,if)
3个条件逻辑运算符(||,||,||)
总计:7
答案 1 :(得分:2)
我认为这里最重要的是条件做短路,这是控制流的一种形式。有用的是重新编写代码以使其明确。在进行程序分析时,这种标准化很常见。一些特殊的规范化(不是正式的,机器不能生成这个,但它得到了重点)会使你的代码如下所示:
public static boolean validatePassword(String password) {
int len = password.length();
//evaluate 'len < 8 || len > 20'
bool cond1 = len < 8;
if (!cond1) cond1 = len > 20;
//do the if test
if (cond1)
return false;
boolean hasLetters = false;
boolean hasDigits = false;
//for loops are equivalent to while loops
int i = 0;
while(i < len) {
if (!Character.isLetterOrDigit(password.charAt(i)))
return false;
//evaluate 'hasDigits || Character.isDigit(password.charAt(i))'
bool hasDigitsVal = hasDigits;
if (!hasDigitsVal) hasDigitsVal = Character.isDigit(password.charAt(i));
//hasDigits = ...
hasDigits = hasDigitsVal
//evaluate 'hasLetters || Character.isLetter(password.charAt(i))'
bool hasLettersVal = hasLetters;
if (!hasLettersVal) hasLettersVal = Character.isLetter(password.charAt(i));
//hasLetters = ...
hasLetters = hasLettersVal;
i++;
}
//evaluate 'hasDigits && hasLetters'
bool cond2 = hasDigits;
if (cond2) cond2 = hasLetters;
//return ...
return cond2;
}
请注意||
和&&
运算符实际上只是将if
语句添加到代码中。另请注意,您现在有6个if
语句和一个while
循环!也许这就是你要找的7个?
关于多个出口点,这是一个红鲱鱼。将每个函数视为具有一个退出节点,即函数的结尾。如果您有多个return
语句,则每个return
语句都会为该出口节点绘制一条边。
void foo() {
if (cond1) return a;
if (cond2) return b;
return c;
}
图表看起来像这样,其中-----val----> EXIT
表示退出函数的值为val
:
START -> cond1 ------------------------a------------> EXIT
| |
cond2 ------------------------b----------------+
| |
return -----------------------c----------------|
如果您重新编写代码,那么您基本上只需添加另一个&#34;预返回&#34;然后转到出口节点的节点:
void foo() {
int val;
if (cond1) {
val= a;
}
else {
if (cond2) {
val= b;
}
else {
val= c;
}
}
return val;
}
现在看起来像这样:
START -> cond1 ---> val=a --------------------------> return ----val----> EXIT
| |
cond2 ---> val=b ------------------------------+
| |
+ -----> val=c ------------------------------+
它仍然很复杂,而且代码更加丑陋。
答案 2 :(得分:0)
很好地解释here:
Cyclomatic Complexity =(2 + ifs + loops + cases - return)where:
* ifs is the number of IF operators in the function, * loops is the number of loops in the function, * cases is the number of switch branches in the function (without default), and * return is the number of return operators in the function.
如前所述,还计算了逻辑条件。
例如if (len < 8 || len > 20)
计为3个条件:
if
len<8
len > 20
这意味着,您的代码的复杂性为2 + 8 - 3 = 7
,其中: