【问题标题】:How Mocha knows which file to load first in the test suiteMocha 如何知道在测试套件中首先加载哪个文件
【发布时间】:2017-04-05 10:59:06
【问题描述】:

我正在尝试使用 MongodB 学习测试驱动方法。文件夹结构

一个user.js在src文件夹中测试

const mongoose = require('mongoose');
mongoose.Promise = require('bluebird');
const Schema = mongoose.Schema;

const UserSchema = new Schema ({
    name: String
});

const User = mongoose.model('user', UserSchema);

module.exports = User;

test_helper.js的内容

const mongoose = require('mongoose');;

mongoose.connect('mongodb://localhost/users_test');

    mongoose.connection
    .once('open', () => {
        console.log('Connected to Mongo!');
        done()}) 
    .on('error', (error) => { 
        console.warn('Warning', error);
    });

create_test.js内容

const assert = require('assert');
const User = require('../src/user');

describe('Creating records', () => {

    it('Saves a user', (done) => {
        const user = new User({ name: 'Ankur' });
        user.save()
                .then(() => {
                    assert(!user.isNew);
                    done();
                });

现在当我运行npm test 时,测试通过了。

Connected to Mongo!
  Creating records
    √ Saves a user (779ms)

但我怀疑Mocha 是如何知道每次都先运行test_helper.js 文件的。 (将此文件命名为任何其他名称也不会改变行为)。

另外,我没有使用任何根级挂钩。

我知道 mocha 在每个目录中递归加载文件,从根目录开始,因为这里的所有内容都只是一个目录,所以在这里没有任何区别。

有人可以建议或帮助,Mocha 是如何确切知道应该首先运行test_helper.js(或任何具有相同内容的文件名)。

【问题讨论】:

    标签: javascript node.js mongodb testing mocha.js


    【解决方案1】:

    Mocha 加载测试文件的方式没有默认设置顺序。

    当 Mocha scans a directory 找到它的文件时,它使用fs.readdirSync。这个调用是对readdir(3) 的包装,它本身并不能保证顺序。现在,由于implementation quirkfs.readdirfs.readdirSync 的输出在 Linux(一般可能是 POSIX 系统)上排序,但不是在 Windows 上。此外,Linux 上的排序行为最终可能会被删除,因为文档说 fs.readdir 只是 readdir(3) 并且后者不保证顺序。有一个很好的论据可以证明在 Linux 上观察到的行为是一个错误(请参阅我上面链接到的问题)。

    请注意,有一个--sort 选项可以在 Mocha 找到文件后对其进行排序。但默认情况下这是关闭的。

    您观察到的行为不仅可以通过加载顺序来解释,还可以通过执行顺序来解释。这是发生了什么:

    1. Mocha 加载测试文件并执行它们。因此,您文件顶层的任何内容都会立即执行。这意味着test_helper.js 中的代码会立即执行。对describe 的每次调用都会立即执行其回调。 但是,调用 it 会记录测试以供以后执行。 Mocha 在执行此操作时发现您的测试,但不会立即执行它们。

    2. 执行完所有文件后,Mocha 开始运行测试。此时,test_helper.js 中的代码已经运行,您的测试将从它创建的连接中受益。

    严重警告 连接到数据库是一个异步操作,目前无法保证test_helper.js 中的异步操作会在测试开始之前完成。它现在运行良好只是运气。

    如果是我,我要么将连接创建放在全局异步 before 挂钩中。 (出现在任何测试文件中的 global before 钩子将在任何测试之前执行,甚至是出现在其他文件中的测试。)或者我会 use --delay并在保证建立连接后显式调用run() 启动套件。

    【讨论】:

    • 感谢您提供如此详细的答复。我已经把它放在钩子之前了。只是没有 before hook 测试条件也显示出这种行为.. 让我感到惊讶
    • 啊,是的,如果它在全局 before 钩子中,那么您就可以避免我描述的问题。它也符合我解释的行为。 before 钩子必须在任何测试之前执行。它不依赖于加载顺序。
    • fs.readdir 和 fs.readdirSync 在 Linux 上排序。如果我可以投票两次就可以了。教我这个 .. 因为在你回答 Peter Müller (github.com/Munter) Mocha 贡献者之前 .. 回答了这个问题,我还在阅读文档,看看它是如何按字母顺序加载文件的”,你的回答也一样
    • Peter 回复 --- "Mocha 按字母顺序加载并评估文件夹中的所有文件。包含测试的文件将排队等待 mocha 稍后运行。test_helper.js 的内容不包含测试并立即执行。这就是为什么您在测试开始运行之前获得数据库连接的原因这是偶然的,您不能依赖时间和数据库连接在测试之前准备好如果您想在任何测试之前保证数据库连接开始运行你需要把建立连接的代码放在一个 before 钩子中,并在它启动并运行时回调”
    • 是的,我做了一些测试,看到了排序的顺序,然后“呃……什么?”因为我知道这一切最终都取决于readdir(3),它不能保证订单。然后我发现了问题报告,其中解释了意外行为。
    【解决方案2】:

    没有

    测试不应该有特定的顺序。 所有测试套件都应该独立于其他套件运行。在套件中,您可以使用“before”和“beforeEach”(或“after”、“afterEach”)来创建设置和拆卸步骤。

    但如果测试的顺序很重要,那么设计中就有问题了。

    【讨论】:

    • 在 mocha 的配置文件中,您可以指定在所有测试开始之前应该加载哪些 javascript 文件,这是您放置帮助文件的地方。
    • 没有做其他配置。除了在 package.json 中安装和 scripts": { "test": "mocha" }, 之外。 create_test.js 需要 mongodb 连接才能通过,这与 test suites.standalone 不可知行为无关
    • @AnkurAnand 这个答案是正确的,mocha知道先加载哪个文件,纯属巧合。
    • @Creynders .. create_test.js 需要 mongoose 连接来验证 .. 如果它先执行,那么在不连接 mongodb 的情况下如何进行验证?
    • @AnkurAnand 我的意思是:你很幸运。这些文件需要按 some 顺序加载,显然在您的情况下它确实 按您需要的顺序加载它们,但这只是巧合。 Mocha 不知道它必须按那个顺序加载它们。
    【解决方案3】:

    有一种非常简单的方法可以按顺序加载测试。

    第 1 步:在 package.json 中设置测试脚本: 例如

    "scripts": {
        "test": "mocha ./tests.js"
      }
    

    让我们假设 tests.js 是一个定义执行测试顺序的文件。

    require("./test/general/test_login.js");
    require("./test/Company/addCompany.js");
    ...
    ...
    

    所以这里 test_login 会先运行,然后其他的一个接一个。

    第 2 步:然后运行测试:

    $ npm test
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-27
      • 1970-01-01
      • 1970-01-01
      • 2011-10-05
      • 1970-01-01
      • 2013-01-16
      相关资源
      最近更新 更多