有这样一段代码:

var O = {
    data: 1,
    fn: function(callback) {
        setTimeout(function() {
            O.data++;
            callback();
        }, 100);
    },
    fn2: function() {
        O.data--;
    }
};

现在要测试 O 的两个方法是否正常工作。我们采用自主开发的测试框架 STF:

/* STF - stupid test framework v0.1 */
function test(desc, fn) {
    console.log('START test ' + desc);
    fn && fn();
    console.log('END test ' + desc);
}
function equals(actual, expected) {
    console.log(actual === expected ? '  passed' : '  failed');
}

有了以上方法,很容易写出测试用例:

test('fn', function() {
    O.data = 1;
    O.fn(function() {
        equals(O.data, 2);
    });
});
test('fn2', function() {
    O.data = 1;
    O.fn2();
    equals(O.data, 0);
});

一运行,输出的 log 顺序很乱,有个用例还失败了:

START test fn
END test fn
START test fn2
  passed
END test fn2
  failed

都是异步惹的祸

对上面的结果稍加分析可以看出,一切都是 setTimeout 惹的祸。
只要被测试的代码里有异步操作,就有可能引起上面的问题。作为一个非常有前景的 STF 测试框架,究竟怎样才能支持异步测试呢?

思路很简单,如果没有异步,都是同步运行,那就很好测试了。因此立刻推出 STF v0.2:

// STF 里增加 sleep 方法
function sleep(ms) {
    var t = (new Date()).getTime();
    while((new Date()).getTime() - t < ms);
}

将 O.fn 的测试用例修改为:

test('fn', function() {
    O.data = 1;
    O.fn(function() {
        equals(O.data, 2);
    });
    sleep(200);
});

满怀期望一运行,杯具,log 还是乱的,依旧失败,