【问题标题】:How to make empty placeholder tests intentionally fail in Mocha?如何在 Mocha 中故意使空占位符测试失败?
【发布时间】:2015-03-25 00:29:42
【问题描述】:

我正在用 NodeJS 编写 API,并使用 Mocha、Chai 和 SuperTest 进行测试。我正在使用一种典型的测试驱动方法,首先编写测试,然后用工作代码满足这些测试。然而,由于所有不同排列的测试数量,我已经开始编写空占位符测试,以便我拥有所有 it('should...') 描述,以提醒我在使用该功能时要测试什么。例如:

it 'should not retrieve documents without an authorized user', (done) ->
    done()

问题在于 done() 在没有任何断言的情况下被调用,因此测试被认为通过了,所以我添加了以下断言。

false.should.equal true # force failure

但这是一种 hack,Mocha 显示的失败原因似乎令人困惑,尤其是当其他完整测试可能失败时。

在 Mocha 中是否有任何官方方法可以故意使此类占位符测试失败?

【问题讨论】:

  • 我不知道任何官方方式,但对于这样的事情,我会考虑使用 should library 并做类似 should.fail('not yet implemented') 的事情。也许将其包装在您自己的模块/函数中并在整个测试中重用它。在 Chai 中,我唯一能想到的就是包装一些抛出的错误,但这可能看起来很丑。
  • @JustinMaat 遗憾的是,chai 的 should 实现没有 fail() 方法。也许我可以考虑切换断言库。
  • 我不知道我是否会切换实际的库。查看文档,我在 assert section 下看到了一个 fail() 函数。这实际上是一个非常好的问题,因为我也觉得这很有用 :) 我会尝试了解要点并尽快在此处提交实际答案
  • @JustinMaat assert.fail() 可能是一个合适的答案,因为它不需要更改任何模块。

标签: node.js unit-testing mocha.js chai


【解决方案1】:

截至 2018 年 5 月 19 日,这是官方方式:https://mochajs.org/#pending-tests

未实现的测试不应fail,应标记为pending

将 mocha 测试标记为 not yet implemented 的简洁方法是不将回调函数传递给 it 处理程序。

describe("Traverse", function(){
    describe("calls the visitor function", function(){
        it("at every element inside an array")
        it("at every level of a tree")
    })
})

运行 mocha test 会将您未实现的测试显示为待处理。

$ mocha test

  Traverse
    calls the visitor function
      - at every element inside an array
      - at every level of a tree


  0 passing (13ms)
  2 pending

【讨论】:

    【解决方案2】:

    将测试标记为尚未准备好进行测试的官方方法是使用skip,这是一种显示为describeit 字段的方法。这是一个例子:

    describe("not skipped", function () {
        it("bar", function () {
            throw new Error("fail");
        });
    
        it.skip("blah", function () {
            throw new Error("fail");
        });
    });
    
    describe.skip("skipped", function () {
        it("something", function () {
            throw new Error("fail");
        });
    });
    

    上述代码,当放入test.js 文件并使用$ mocha --reporter=spec test.js 运行时,会产生:

      not skipped
        1) bar
        - blah
    
      skipped
        - something
    
    
      0 passing (4ms)
      2 pending
      1 failing
    
      1) not skipped bar:
         Error: fail
          at Context.<anonymous> (/tmp/t33/test.js:3:15)
          at callFn (/home/ldd/local/lib/node_modules/mocha/lib/runnable.js:223:21)
          at Test.Runnable.run (/home/ldd/local/lib/node_modules/mocha/lib/runnable.js:216:7)
          at Runner.runTest (/home/ldd/local/lib/node_modules/mocha/lib/runner.js:374:10)
          at /home/ldd/local/lib/node_modules/mocha/lib/runner.js:452:12
          at next (/home/ldd/local/lib/node_modules/mocha/lib/runner.js:299:14)
          at /home/ldd/local/lib/node_modules/mocha/lib/runner.js:309:7
          at next (/home/ldd/local/lib/node_modules/mocha/lib/runner.js:247:23)
          at Object._onImmediate (/home/ldd/local/lib/node_modules/mocha/lib/runner.js:276:5)
          at processImmediate [as _immediateCallback] (timers.js:354:15)
    

    - 开头的测试名称将被跳过。此外,在支持颜色的终端中,跳过的测试显示为蓝色(与红色表示失败的测试和绿色表示通过)。跳过的测试被称为“待处理”,因此 Mocha 将跳过的测试数量报告为“2 待处理”。

    【讨论】:

    • 谢谢你,我不知道跳过。然而,在阅读了文档之后,这似乎只是一种“跳过”测试的方式。虽然有用,但我认为 OP 想要一种使其失败的规范方法,即您在此处拥有的代码 - throw new Error("fail"); 在这种情况下,我看不到框架本身有任何方法可以做到这一点。其他一些语言/框架具有此功能(例如:scala 有 ??? 占位符)
    • 赞成,因为经过考虑,这可能要好得多,因为它清楚地将测试标记为占位符。对于实际的实现代码,我可能会像上面那样实现一个尚未准备好的函数。
    • 是的,我已经改变了我选择的答案(对不起@JustinMaat),因为这在技术上是我想做的,而且更正式。
    • 我认为的最佳解决方案。待定仅在您不想实现测试时才有效,但在我的情况下,我想先编写测试,然后一个接一个地实现功能。这里唯一让我担心的是它没有写出为什么跳过这些测试,但我可以忍受。
    【解决方案3】:

    如果您将字符串或错误传递给done(),它将报告为错误。所以:

    it 'should not retrieve documents without an authorized user', (done) ->
        done('not implemented')
    

    会导致测试失败并输出:

    done() 以非错误调用:未实现


    我喜欢 @Canyon 的解决方案,即不传递回调以将测试标记为“待处理”,但在我的情况下,我希望这些占位符使我的 CI 构建失败,因此让它们像这样实际失败的测试更容易。

    【讨论】:

    • 更好:添加一个new Error( 'reason' ) 对象。
    • 这在使用 Promises 或 Rx Observables 时也很有帮助,它们会吞下使用 throw 抛出的任何错误。
    【解决方案4】:

    这实际上是一个很好的问题,因为我也觉得这非常有用。看完之后,我想创建自己的包装器“todo”或“fail”函数,您可以在整个代码库中重用它们。

    下面的示例使用了一个名为 todo 的函数,它将打印出“尚未实现”的文本。这可能作为一个单独的模块很有用,即使您可以导入并与所有测试一起使用。可能需要稍微修改一下代码...

    chai 断言中的示例

    var assert = require('chai').assert;
    
    function todo() {
        assert(false, "method not yet implemented"); 
    };
    
    describe("some code", function(){
        it("should fail something", function(){
            todo();
        });
    });
    

    使用 chai assert 的示例,带有失败选项(虽然它看起来没有必要)

    var assert = require('chai').assert;
    
    function todo() {
        assert.fail(true, true, "method not yet implemented");   //1st 2 args can be anything really
    };
    
    describe("some code", function(){
        it("should fail something", function(){
            todo();
        });
    });
    

    【讨论】:

    • 我已经提出了一个功能请求,要求将 .fail() 方法添加到 Chai 的所有样式中,因此希望将来会更新 github.com/chaijs/chai/issues/350
    • 只是为了节省人们的点击次数,看起来这个拉取请求不久前就被接受了,所以你现在可以使用 .fail() 了。
    • 没有多大意义。如果您先编写所有测试,然后再编写代码,那么您希望 mocha 跳过所有测试并保持绿色。否则,很难从所有失败的测试中找到您正在开发的功能。取决于你如何做这些事情,你将无法提交和推送失败的测试。
    猜你喜欢
    • 1970-01-01
    • 2013-01-30
    • 1970-01-01
    • 2019-03-22
    • 2015-08-04
    • 2017-07-11
    • 2017-03-23
    • 1970-01-01
    • 2017-09-30
    相关资源
    最近更新 更多