简体   繁体   English

Mocha如何知道在测试套件中首先加载哪个文件

[英]How Mocha knows which file to load first in the test suite

I'm trying to learn the A Test Driven Approach with MongodB. 我正在尝试用MongodB学习A测试驱动方法。 The folder structure 文件夹结构

在此输入图像描述

A user.js to test in the src folder 要在src文件夹中测试的user.js

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;

Content of test_helper.js 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 content 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();
                });

Now when i run npm test the test are getting passed. 现在,当我运行npm test ,测试正在通过。

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

But My doubt is how does Mocha knows to run the test_helper.js file first, Everytime. 但我怀疑Mocha是如何知道首先运行test_helper.js文件的。 (Also naming this file to any other name doesn't change the behavior). (同样将此文件命名为任何其他名称不会更改行为)。

Also i'm not using any root-level hook. 我也没有使用任何根级钩子。

i know mocha loads files recursively in each directory, starting with the root directory, and since everything here is one directory only so its not making any difference here. 我知道mocha在每个目录中递归加载文件,从根目录开始,因为这里的所有内容都只是一个目录所以它在这里没有任何区别。

Can someone please suggest or help, how does Mocha exactly know that test_helper.js (or any filename with the same content) should be running first. 有人可以建议或帮助,Mocha如何确切地知道test_helper.js (或任何具有相同内容的文件名)应该先运行。

There is no default set order to how Mocha loads the test files. Mocha加载测试文件的方式没有默认的设置顺序。

When Mocha scans a directory to find files it it, it uses fs.readdirSync . 当Mocha 扫描目录以查找文件时,它使用fs.readdirSync This call is a wrapper around readdir(3) , which itself does not guarantee order. 这个调用是readdir(3)的包装,它本身不保证顺序。 Now, due to an implementation quirk the output of fs.readdir and fs.readdirSync is sorted on Linux (and probably POSIX systems in general) but not on Windows . 现在,由于实现怪癖fs.readdirfs.readdirSync的输出在Linux(通常可能是POSIX系统) 排序,但在Windows上排序。 Moreover, it is possible that the sorted behavior on Linux could eventually be removed because the documentation says fs.readdir is just readdir(3) and the latter does not guarantee order. 此外,最终可能会删除Linux上的排序行为,因为文档说fs.readdir只是readdir(3)而后者不保证顺序。 There's a good argument to be made that the behavior observed on Linux is a bug (see the issue I linked to above). 有一个很好的论据可以证明在Linux上观察到的行为是一个错误(请参阅我上面链接的问题)。

Note that there is a --sort option that will sort files after Mocha finds them. 请注意,有一个--sort选项可以在Mocha找到它们之后对文件进行排序。 But this is off by default. 但默认情况下这是关闭的。

The behavior you observe is explainable not merely by loading order but by execution order . 您观察到的行为不仅可以通过加载顺序而且可以通过执行顺序来解释 Here is what happens: 这是发生的事情:

  1. Mocha loads the test files and executes them. Mocha加载测试文件并执行它们。 So anything that is at the top level of your file executes right away . 因此,任何在你的文件的顶层执行的时候了 This means that the code in test_helper.js executes right away. 这意味着test_helper.js中的代码会立即执行。 Every call to describe immediately executes its callback. 每次调用describe立即执行它的回调。 However, calls to it record the test for later execution. 但是,调用it记录测试以便以后执行。 Mocha is discovering your tests while doing this but not executing them right away. Mocha在执行此操作时会发现您的测试,但不会立即执行它们。

  2. Once all files are executed, Mocha starts running the tests. 一旦执行完所有文件,Mocha就会开始运行测试。 By this time, the code in test_helper.js has already run and your test benefits from the connection it has created. 到目前为止, test_helper.js的代码已经运行,并且您的测试会从它创建的连接中受益。

Major warning Connecting to a database is an asynchronous operation, and currently there is nothing that guarantees that the asynchronous operation in test_helper.js will have completed before the tests starts. 主要警告连接到数据库是一种异步操作,目前没有什么能保证test_helper.js中的异步操作在测试开始之前就已完成。 That it works fine right now is just luck. 它现在工作正常只是运气。

If this were me, I'd either put the connection creation in a global asynchronous before hook. 如果这是我,我要么before挂钩before将连接创建放在全局异步中。 (A global before hook appearing in any test file will be executed before any test whatsoever, even tests that appear in other files. ) Or I'd use --delay and explicitly call run() to start the suite after the connection is guaranteed to be made. (A 全球 before出现在任何测试文件钩子将任何测试无论如何, 出现在其他文件之前, 即使测试执行)。或者我会--delay和显式调用run()来启动套件的连接工作后,被制造。

It doesn't 它没有

Tests should not have a specific order. 测试不应该有特定的顺序。 All test suites should be working as standalone agnostic to other suites. 所有测试套件应与其他套件独立无关。 Inside the suite you can use "before" and "beforeEach" (or "after", "afterEach") in-order to create setup and teardown steps. 在套件内部,您可以使用“before”和“beforeEach”(或“after”,“afterEach”)来创建设置和拆卸步骤。

But if the order of the tests matters, something is broken in the design. 但是如果测试顺序很重要,那么设计中就会出现问题。

There is a very easy way to load tests sequentially. 有一种非常简单的方法可以顺序加载测试。

Step 1 : Set up a test script in package.json: eg 第1步:在package.json中设置测试脚本:例如

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

Let us assume that tests.js is a file which defines the order to execute tests. 我们假设tests.js是一个定义执行测试顺序的文件。

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

So here test_login will run first and then others one by one. 所以这里test_login将首先运行,然后逐个运行。

Step 2: Then run tests with: 第2步:然后运行测试:

$ npm test

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM