【问题标题】:How to convert nodejs based unit tests to native browser based unit tests?如何将基于 nodejs 的单元测试转换为基于本机浏览器的单元测试?
【发布时间】:2016-04-12 03:42:51
【问题描述】:

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


例如,promises-tests 可以在promises-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()?

【问题讨论】:

  • 完全不满意的答案是:手工:P
  • @JaredSmith 是的。好的,这种方法。对node.js 没有太多经验。如何在window处选择合适的对应方法?比如describe()和specify()有什么区别?
  • 您需要使用 Jasmine 或 Qunit 等客户端测试库。然后你应该几乎可以 grep 你的代码并替换等效的成语。例如,对于 Jasmine,它将是描述而不是指定。 IIRC qunit 的语法与上述几乎相同。
  • 您根本不需要控制台输出,这些库将以图形方式显示 HTML 中的结果。没有库的唯一方法是写你自己的。
  • @JaredSmith 能够运行 QUnit。如何将上面链接的测试转换为 QUnit?或者甚至简单地使用console.assert()?视觉显示不是必需的,只有结果。与 describe() 和 specify() 等效的原生 window 方法是什么?

标签: javascript node.js unit-testing


【解决方案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)、typeof、instanceof、其他类型(内置、构造)、NaN 和 null 等有问题的值。

注意:console.assert

console.assert 存在一些问题。首先,它是非标准的,并且跨平台的行为可能不同。其次,AFAIK 没有很好的抽象方法:除非您使用 eval 和字符串参数,否则您最终会使用 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 意味着使用解析器然后我们马上回到图书馆。

说真的,当你沿着这条路走下去时,你会想到越来越多的东西(见我上面的列表),你会意识到你正在编写一个本来可以使用的库。

更新

根据您在下面 cmets 中的问题,许多测试库(例如 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();
       });
   });
});
 

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

QUnit 的 API 稍微简单一些,但也不算太远。

更新 2

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

【讨论】:

  • 提问时jsdescribe() 和specify() 有什么区别?
  • 两者都不是原生的,一个是一个库处理它的方式,另一个是另一个库的语法。请注意,这些库非常接近相同,但有很多共同点。
  • 您的答案中的assert() 是否等同于specify()?
  • 您能否描述js 中使用的describe()、specify()、assert() 之间的区别? adapter 是什么以及adpater 在此过程中的作用?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-06
  • 1970-01-01
  • 2013-10-23
  • 2021-07-13
  • 2020-06-30
相关资源
最近更新 更多