83

Mocha 官方网站上的文档包含以下示例:

describe('User', function(){
  describe('#save()', function(){
    it('should save without error', function(done){
      var user = new User('Luna');
      user.save(function(err){
        if (err) throw err;
        done();
      });
    })
  })
})

我想知道什么时候应该将测试嵌套在describe函数中,以及它的基本目的describe是什么。我可以将传递给的第一个参数与describe编程语言中的注释进行比较吗?describe控制台的输出中没有显示任何内容。它只是出于可读性目的,还是此功能有其他用途?

如果我这样使用它有什么问题吗?

describe('User', function(){
    describe('#save()', function(){
        var user = new User('Luna');
        user.save(function(err){
            if (err) throw err;
            done();
        })
    })
})

如果我这样做,测试仍然通过。

4

5 回答 5

98

it调用标识了每个单独的测试,但它本身it并没有告诉 Mocha 您的测试套件的结构。您如何使用describe调用是为您的测试套件提供结构的原因。以下是describe用于构建测试套件的一些功能。这是一个测试套件的示例,为了讨论的目的而进行了简化:

function Foo() {
}

describe("Foo", function () {
    var foo;
    beforeEach(function () {
        foo = new Foo();
    });
    describe("#clone", function () {
        beforeEach(function () {
            // Some other hook
        });
        it("clones the object", function () {
        });
    });
    describe("#equals", function () {
        it("returns true when the object passed is the same", function () {
        });
        it("returns false, when...", function () {
        });
    });
    afterEach(function () {
        // Destroy the foo that was created.
        // foo.destroy();
    });
});

function Bar() {
}

describe("Bar", function () {
    describe("#clone", function () {
        it("clones the object", function () {
        });
    });
});

想象一下,这FooBar成熟的课程。Foocloneequals方法。Barclone。我上面的结构是为这些类构建测试的一种可能方法。

#(某些系统(例如,jsdoc)使用该符号来表示实例字段。因此,当与方法名称一起使用时,它表示在类的实例上调用的方法(而不是调用的类方法)类本身)。测试套件在不存在的情况下也可以运行#。)

提供横幅

describeMocha 的一些记者会在他们制作的报告中显示您给的名字。例如,spec记者(您可以通过运行使用$ mocha -R spec)将报告:

  Foo
    #clone
      ✓ clones the object 
    #equals
      ✓ returns true when the object passed is the same 
      ✓ returns false, when... 

  Bar
    #clone
      ✓ clones the object 


  4 passing (4ms)

帮助选择要运行的部件

如果您只想运行一些测试,您可以使用该--grep选项。所以如果你只关心Bar类,你可以做$ mocha -R spec --grep Bar,并得到输出:

  Bar
    #clone
      ✓ clones the object 


  1 passing (4ms)

或者,如果您只关心clone所有类的方法,那么$ mocha -R spec --grep '\bclone\b'并获取输出:

  Foo
    #clone
      ✓ clones the object 

  Bar
    #clone
      ✓ clones the object 


  2 passing (5ms)

给定的值--grep被解释为一个正则表达式,所以当我通过时,我\bclone\b只要求这个词clone,而不是像clonesor之类的东西cloned

提供挂钩

在上面的示例中,beforeEachandafterEach调用是钩子。每个钩子都会影响作为钩子父级的调用it内部的调用。describe各种钩子是:

  • beforeEachit它在describe通话中的每个人之前运行。

  • afterEachit它在describe通话中的每个人之后运行。

  • beforeitdescribe调用中的任何个人运行之前运行一次。

  • afteritdescribe调用中的所有个人都运行后运行一次。

这些钩子可用于获取资源或创建测试所需的数据结构,然后在测试完成后释放资源或销毁这些结构(如果需要)。

您在问题末尾显示的代码段不会产生错误,但它实际上不包含任何测试,因为测试由it.

于 2014-05-13T23:29:51.733 回答
8

很难补充路易斯的出色回答。describe 块有几个优点,他没有提到哪些是skiponly功能。

describe.skip(...) {
...
}

将跳过此描述及其所有嵌套描述,并且它在以下情况下起作用:

describe.only(...) {
...
}

只会执行该描述及其嵌套的描述及其功能。skip()andonly()修饰符也可以应用于 it() 函数。

于 2014-09-08T22:08:37.853 回答
8

据我所知,describe 确实只适用于人类......所以我们可以看到应用程序的不同区域。您可以嵌套描述 n 层深度。

describe('user',function(){
    describe('create',function(){}
});
于 2013-10-10T15:45:59.520 回答
4

描述只是为了理解测试的目的,它也用于对测试进行逻辑分组。假设您正在测试数据库 API,所有数据库测试都可以归入外部描述,因此外部描述在逻辑上对所有与数据库相关的数据库进行分组。假设有 10 个与数据库相关的 API 需要测试,每个内部描述函数都定义了这些测试是什么......

于 2014-05-10T07:56:38.070 回答
0

describe 的特殊作用是指示正在测试哪个组件以及该组件的哪个方法也在被测试。

例如,假设我们有一个用户原型

var User = function() {
    const self = this;

    function setName(name) {
        self.name = name
    }

    function getName(name) {
        return self.name;
    }


    return{setName, getName};
}

module.exports = User;

并且需要测试,所以创建了一个spec文件进行单元测试

var assert = require('assert');
var User = require("../controllers/user.controller");

describe("User", function() {
    describe('setName', function() {
        it("should set the name on user", function() {
            const pedro = new User();

            name = "Pedro"
            pedro.setName(name);
            assert(pedro.getName(), name);
        });
    });
});

很容易看出,describe 的目的是指示要测试的组件,嵌套的 describe 方法指示需要测试哪些方法

于 2019-07-02T19:55:34.123 回答