如何将基于nodejs的单元测试转换为基于本机浏览器的单元测试?

时间:2016-04-11 18:22:59

标签: javascript node.js unit-testing

注意,相关的How to test if jQuery 3.0 beta is Promises/A+ compatible in browser?

例如,在promises-testspromises-tests/lib/tests/2.1.2.js

找到了其中一项测试
"use strict";

var assert = require("assert");
var testFulfilled = require("./helpers/testThreeCases").testFulfilled;

var adapter = global.adapter;
var deferred = adapter.deferred;

var dummy = { dummy: "dummy" }; // we fulfill or reject with this when we don't intend to test against it

describe("2.1.2.1: When fulfilled, a promise: must not transition to any other state.", function () {
    testFulfilled(dummy, function (promise, done) {
        var onFulfilledCalled = false;

        promise.then(function onFulfilled() {
            onFulfilledCalled = true;
        }, function onRejected() {
            assert.strictEqual(onFulfilledCalled, false);
            done();
        });

        setTimeout(done, 100);
    });

    specify("trying to fulfill then immediately reject", function (done) {
        var d = deferred();
        var onFulfilledCalled = false;

        d.promise.then(function onFulfilled() {
            onFulfilledCalled = true;
        }, function onRejected() {
            assert.strictEqual(onFulfilledCalled, false);
            done();
        });

        d.resolve(dummy);
        d.reject(dummy);
        setTimeout(done, 100);
    });

    specify("trying to fulfill then reject, delayed", function (done) {
        var d = deferred();
        var onFulfilledCalled = false;

        d.promise.then(function onFulfilled() {
            onFulfilledCalled = true;
        }, function onRejected() {
            assert.strictEqual(onFulfilledCalled, false);
            done();
        });

        setTimeout(function () {
            d.resolve(dummy);
            d.reject(dummy);
        }, 50);
        setTimeout(done, 100);
    });

    specify("trying to fulfill immediately then reject delayed", function (done) {
        var d = deferred();
        var onFulfilledCalled = false;

        d.promise.then(function onFulfilled() {
            onFulfilledCalled = true;
        }, function onRejected() {
            assert.strictEqual(onFulfilledCalled, false);
            done();
        });

        d.resolve(dummy);
        setTimeout(function () {
            d.reject(dummy);
        }, 50);
        setTimeout(done, 100);
    });
});

要求:

能否在浏览器中运行测试而不依赖node.js,服务器或安装库?

问题:

如何使用浏览器提供的本机方法将此测试转换为版本,例如Console方法;也就是说,将console.assert()或其他原生方法替换为window describe()specify()

1 个答案:

答案 0 :(得分:1)

我仍然认为这是一个可怕的想法,但这是一个(微不足道的)例子:

var assert = {};
assert.equals = function(expected, value, msg) {
    var message = msg || "Test ";
    try {
        expected == value;
        console.log(message, "passed");
    catch (e) {
        console.log(message, "failed", e);
    }
};

现在重复>, <, ===,范围,预期异常,特定异常(例如TypeError,SyntaxError),typeofinstanceof,其他类型(内置,构建),有问题的值,如NaNnull等。

注意:console.assert

console.assert存在一些问题。首先,它是非标准的,并且可能不会在不同平台上表现相同。其次,AFAIK没有很好的方法来抽象它:除非你使用eval和string参数,否则你最终会使用console.log做上述解决方案所做的工作:

function assert(str, msg) {
  try {
     console.assert(eval(str), msg);
  catch (e) {
     console.log(msg, " failed:", e);
  }
}

assert("3 === 4", "Three equals four"); // logs the assertion failure.

毋庸置疑,我不建议这样做,因为手动构建字符串容易出错,eval(即使在这种情况下是安全的)是一个臭名昭着的杀手杀手,而不是eval意味着使用解析器和bam我们就回到了库位。

说真的,当你沿着这条路走下去时,你会想到你想要的东西越来越多(参见上面的清单),你会发现当你使用它时你正在写一个图书馆。

更新

根据您在下面的评论中的问题,许多测试库(例如mocha,jasmine)使用如下格式:

wrapper('name of the thing being tested', function(done) {
   innerWrapper('description of the test', function(done) {
       assert(someAssertion);
   });

   innerWrapper('some other test for that function', function(done) {
       assert(somethingElse);
       someAsyncFunction().then(function(value) {
           assert(somethingAboutValue);
           done();
       });
   });
});

通过在代码中包含测试库或运行命令(对于cli),即'mocha tests.js'而不是'node tests.js'来添加'wrapper','innerWrapper'和'assert'。设置可能会也可能不会使用内部函数来指定子测试。 'Done'是回调的参数,可用于表示异步测试的结束。

QUnit的API有点简单,但距离不太远。

更新2

大部分内容都是相同的名称:包含测试条件的函数,以确保记录正确的消息,捕获异常,或异步有机会完成。断言测试要评估的实际条件。适配器引用意味着包装jQuery延迟构造函数以匹配规范中的API。