【发布时间】:2019-01-25 13:12:07
【问题描述】:
我有一个非常典型的 switch-like 函数,它返回给定输入值的分类(在本例中为身体质量指数)。 (我正在使用这个函数,但它可以是任何其他相同性质的函数)
目前,情况差不多这样:
// ...
const TYPE_SEVERE_THINNESS = -3;
const TYPE_MODERATE_THINNESS = -2;
const TYPE_MILD_THINNESS = -1;
const TYPE_REGULAR = 0;
const TYPE_OVERWEIGHT = 1;
const TYPE_PRE_OBESE = 2;
const TYPE_OBESE_GRADE_I = 3;
const TYPE_OBESE_GRADE_II = 4;
const TYPE_OBESE_GRADE_III = 5;
// ...
public static function classification(float $bmi) : int
{
if ($bmi <= 16.00) {
return self::TYPE_SEVERE_THINNESS;
}
if ($bmi <= 16.99) {
return self::TYPE_MODERATE_THINNESS;
}
if ($bmi <= 18.49) {
return self::TYPE_MILD_THINNESS;
}
if ($bmi <= 24.99) {
return self::TYPE_REGULAR;
}
if ($bmi <= 27.49) {
return self::TYPE_OVERWEIGHT;
}
if ($bmi <= 29.99) {
return self::TYPE_PRE_OBESE;
}
if ($bmi <= 34.99) {
return self::TYPE_OBESE_GRADE_I;
}
if ($bmi <= 39.99) {
return self::TYPE_OBESE_GRADE_II;
}
if ($bmi >= 40) {
return self::TYPE_OBESE_GRADE_III;
}
}
我将进行一轮重构,我正在考虑对该功能进行所有可能的增强,特别是降低 C.R.A.P.索引(Change Risk Anti-Patterns),此时返回值110.00。
当然,可能有许多可能的增强功能。欢迎提出建议。
但我的问题具体是关于降低循环复杂度,
a) 是否有任何其他方式来构建此代码,以便 C.R.A.P.指数走低? b) 为了正确测试此功能,我应该生成一个断言每种情况的测试,还是执行许多测试来解决每种可能的情况? (我现在的答案可能是“由你决定”,但也许存在更好的方法来降低圈复杂度,从而让位于仍然涵盖所有或大多数可能场景的更少测试。)
如果我必须匹配相等的值,我只会使用 hashmap(键值数组),但由于我正在评估范围,因此方法可能会有所不同。
更新:在使用每个场景的示例构建测试用例后,CRAP 索引下降到 10.01。不过,我相信还有另一种方法来执行值查找。
/**
* Test it returns a valid WHO classification for BMI type
*
* @return void
*/
public function test_it_returns_a_valid_who_classification_for_bmi_type()
{
// Sample bmi => expected type
// Key must be a string later converted to float
$testMatrix = [
"15" => BMILevel::TYPE_SEVERE_THINNESS,
"16.5" => BMILevel::TYPE_MODERATE_THINNESS,
"18" => BMILevel::TYPE_MILD_THINNESS,
"24" => BMILevel::TYPE_REGULAR,
"27" => BMILevel::TYPE_OVERWEIGHT,
"29" => BMILevel::TYPE_PRE_OBESE,
"34" => BMILevel::TYPE_OBESE_GRADE_I,
"39" => BMILevel::TYPE_OBESE_GRADE_II,
"41" => BMILevel::TYPE_OBESE_GRADE_III,
];
foreach ($testMatrix as $bmi => $categoryCheck) {
$type = BMILevel::classification(floatval($bmi));
$this->assertEquals($type, $categoryCheck);
}
}
【问题讨论】:
标签: php unit-testing phpunit code-coverage cyclomatic-complexity