一段丑陋代码的诞生记

话说某年某月某日我在用PHP为我的服务器程序写测试代码,为了方便判断服务器的输出返回,我写下了下面的代码。

function assert_rpc_call($cmd, $input, $logid, $expected_err_code = 0) {
    $ret = rpc_call($cmd, $input, $logid);
    return $ret['result'] === $expected_err_code;
}

在这里,rpc_call()是我测试用的一个函数,可以用来访问我的服务器,它的返回值是一个数组,其中一定有’result’域存放一个整型的返回值。
这个函数实在是太好用了,以至于我的测试函数每个地方都用这个函数而不用rpc_call()。我非常满意,觉得已经万事OK了。
世界上唯一不变的是变化。
后来,我发现学xUnit那样每个测试用例打个点表示成功实在是无趣,而且如果真出了什么错就完全没法调试,于是我增强了这个函数。

function assert_rpc_call($cmd, $input, $logid, $expected_err_code = 0) {
    $ret = rpc_call($cmd, $input, $logid);
这样一来,默认情况下我的assert_rpc_call每次都会把返回的信息打印出来,成功输出绿色的PASS,失败返回红色的FAIL,煞是好看。我非常满意。
    $output = “”;
    if ($ret['result'] === $expected_err_code) {
        $output .= “\033[1;32mPASS\033[m\n";
    } else {
        $output .= "\033[1;31mFAIL\033[m\n";
    }
    $output .= print_r($ret, true);
    echo $output;
    return $ret;
}
工具如果太好用了,它一般会被滥用。
可是需求还在变化。不久,我发现有时候我为了初始化一个用于自动测试的环境需要调用很多肯定不会失败的接口,每次把它们的返回打印出来实在是扰乱视听,我需要有一个开关切换回原来的assert_rpc_call()行为。于是我加了一个参数和一些丑陋的代码实现这个功能。再接着,我又想在某些情况下获得返回的数组,在另外一些情况下返回bool值,而且还要在某些情况下打印输入的参数……我知道把这些矛盾的功能全部加到一个函数里面是非常丑陋的,也许应该拆成几个函数更为合适,但因为这个函数已经在很多地方调用,我实在懒得把每个地方都改好。
最终,代码变成了这样。

function [...]