在Jasmine测试中使用条件语句

red*_*rum 10 javascript testing jasmine

我有两个我想测试的功能; 一个只在"现代浏览器"中运行的另一个只在"较旧"的浏览器中运行.

我使用Jasmine作为我的测试框架和Karma来运行我的测试.Karma将推出许多运行所有测试的浏览器.

我的问题是在所有浏览器中测试我的所有功能会导致一些测试失败.例如,在IE8中测试时,测试仅应在现代浏览器中运行的函数将失败.

要测试的代码:

function getStuffFromSmartBrowser() {
    return 'foo';
}

function getStuffFromNotSoSmartBrowser() {
    return 'bar';
}

if ('intelligence' in browser) {
    getStuffFromSmartBrowser();
} else {
    getStuffFromNotSoSmartBrowser();
}
Run Code Online (Sandbox Code Playgroud)

原始测试代码:

describe("A suite", function () {
    it("for smart browsers", function () {
        expect(getStuffFromSmartBrowser()).toEqual('foo');
    });
});

describe("A suite", function () {
    it("for not so smart browsers", function () {
        expect(getStuffFromNotSoSmartBrowser()).toEqual('bar');
    });
});
Run Code Online (Sandbox Code Playgroud)

在这些测试用例中,一种测试将在一种类型的浏览器中失败,而另一种测试在另一种类型的浏览器中将失败.

替代测试代码:

describe("A suite", function () {
    if ('intelligence' in browser) {
        it("for smart browsers", function () {
            expect(getStuffFromSmartBrowser()).toEqual('foo');
        });
    } else {
        it("for not so smart browsers", function () {
            expect(getStuffFromNotSoSmartBrowser()).toEqual('bar');
        });
    }
});
Run Code Online (Sandbox Code Playgroud)

替代测试代码在所有测试的浏览器中运行良好.

问题:

A - 在测试中使用条件语句是一种好习惯吗?

B - 如果没有,那会是更好的方法吗?

Eri*_*ric 10

它通常被认为是不好的做法,具有条件语句的测试代码.在测试代​​码之外稍微可以接受,并且在缺少通过浏览器选择测试规范的内置机制的情况下,您的解决方案可能是最简单的.但是,您将单元测试与特定于浏览器的实现相结合.

"更好"的方法是将浏览器特定的代码隐藏在单个函数后面,并使用特征检测来执行多个调度.

function getStuff() {
    if (browserIsSmart()) {
        return getStuffFromSmartBrowser();
    }
    else {
        return getStuffFromNotSoSmartBrowser();
    }
}

function browserIsSmart() {
    return ('intelligence' in browser);  // Or whatever
}
Run Code Online (Sandbox Code Playgroud)

这里是凌乱的地方.您的两个函数具有不同的返回值.理想情况下,您需要为所有相关函数提供相同的返回值,但这并不总是很简单.例如,IE8中的textarea选择使用与现代浏览器中的textarea选择完全不同的对象.有时您可以隐藏细节(​​例如使用策略模式),有时您不能.

如果你不能让它干净,那就明白吧.