You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在非并行模式下循环重复运行Mocha测试?

非并行模式下循环运行Mocha测试的问题及解决方法

我想要在非并行模式下循环重复运行Mocha测试,但发现仅第一次迭代会加载测试,后续日志显示0个测试被运行。

主文件代码(需安装Mocha)

const fs = require('fs')
const path = require('path');
const Mocha = require('mocha');

getFiles = dir => { // returns tests files as an array
    const files = []
    let resolvedPath = path.resolve(dir);
    
    for (const file of fs.readdirSync(dir)) {
        const fullPath = resolvedPath + '/' + file
        if (fs.lstatSync(fullPath).isDirectory())
            getFiles(fullPath).forEach(x => files.push(file + '/' + x))
        else if (file.endsWith('.js')) {
            files.push(fullPath)
        }
    }
    return files
}

function delay(time) { // used for sleep within the start function
  return new Promise(resolve => setTimeout(resolve, time));
} 

async function start(testsPath) {
    
    let testFiles = getFiles(testsPath);
    let failedTestsCount = -1;
    
   while(true) {
        console.log("starting a new iteration")
        let mocha = await new Mocha();
        for (let i = 0; i < testFiles.length; i++) {
            mocha.addFile(testFiles[i]);
        }
        
        mocha.parallelMode(false);

        await mocha.run(failed => {
            failedTestsCount = failed;
        });
        console.log("Failed tests: " + failedTestsCount)
        await delay(1000*60) // 1 minute   
    }      
}

start('./tests');

测试文件代码(存储在tests子目录,需安装chai)

let expect = require("chai").expect;

describe("Very Simple Tests", async function() {  

    it("passing", async function() {
        expect(true).to.equal(false);
    });

    it("failing", async function() {
        expect(true).to.equal(true);
    });  
});

运行输出(仅第一次迭代加载测试)

Very Simple Tests
    1) passing
    ✔ failing


  1 passing (3ms)
  1 failing

  1) Very Simple Tests
       passing:

      AssertionError: expected true to equal false
      + expected - actual

      -true
      +false
      
      at Context.<anonymous> (tests/tests.js:6:25)
      at process.processImmediate (node:internal/timers:476:21)



starting a new iteration
Failed tests: 1


  0 passing (0ms)

补充说明:并行模式下运行正常,但某些场景我需要串行模式,尝试过多种配置无效。且无法通过shell脚本和Mocha命令行选项运行,因为需要通过Express端点展示测试结果。


问题原因

Mocha在串行模式下,第一次运行后会将已加载的测试文件标记为已执行,后续重复添加同一文件时会跳过加载;而并行模式下每次都会重新加载文件,因此不存在该问题。

解决方案

要实现非并行模式下的循环运行,需在每次迭代时清除测试文件的模块缓存,并正确封装Mocha的运行逻辑为Promise。修改后的主文件代码如下:

const fs = require('fs')
const path = require('path');
const Mocha = require('mocha');

function getFiles(dir) { // 返回测试文件数组
    const files = []
    const resolvedPath = path.resolve(dir);
    
    for (const file of fs.readdirSync(dir)) {
        const fullPath = path.join(resolvedPath, file); // 用path.join避免路径拼接问题
        if (fs.lstatSync(fullPath).isDirectory()) {
            getFiles(fullPath).forEach(subFile => files.push(subFile));
        } else if (file.endsWith('.js')) {
            files.push(fullPath);
        }
    }
    return files
}

function delay(time) { // 用于循环中的延迟
  return new Promise(resolve => setTimeout(resolve, time));
} 

async function start(testsPath) {
    const testFiles = getFiles(testsPath);
    
    while(true) {
        console.log("starting a new iteration");
        
        // 清除测试文件的模块缓存,确保每次重新加载
        testFiles.forEach(file => {
            delete require.cache[require.resolve(file)];
        });
        
        const mocha = new Mocha();
        mocha.parallelMode(false);
        
        // 重新添加测试文件
        testFiles.forEach(file => mocha.addFile(file));
        
        // 正确封装mocha.run为Promise,等待测试完成
        const failedTestsCount = await new Promise(resolve => {
            mocha.run(failed => resolve(failed));
        });
        
        console.log("Failed tests: " + failedTestsCount);
        await delay(1000*60); // 1分钟延迟
    }      
}

start('./tests');

关键修改点

  • 清除模块缓存:通过delete require.cache[require.resolve(file)]删除已加载的测试文件缓存,确保Node.js每次都重新读取并执行测试代码
  • 修正Promise封装:原代码直接await mocha.run()无效,因为mocha.run()不返回Promise,需手动封装以正确等待测试结束
  • 路径优化:用path.join替代字符串拼接,避免跨平台路径兼容性问题

修改后,串行模式下每次循环都会重新加载并执行所有测试用例,与第一次运行结果一致。

内容的提问来源于stack exchange,提问作者npocmaka

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 18:35:28