如何使用NodeJS原生测试运行器递归匹配TypeScript测试文件
解决Node.js原生测试运行器无法递归查找TypeScript测试文件的问题
Node.js新增了原生测试运行器,可以通过ts-node或tsx运行TypeScript测试,比如执行以下命令:
node --loader ts-node/esm --test **/*.test.tsnode --loader tsx --test **/*.test.ts
但目前存在一个问题:glob模式**/*.test.ts无法递归匹配嵌套目录下的测试文件,只能找到一级目录(如src/bar.test.ts),而像src/foo/bar.test.ts这类深层文件无法被识别——原因是测试运行器依赖的glob库不支持**的递归语法。
你的项目目录结构如下:
. ├── package.json ├── src │ ├── app │ │ ├── dir │ │ │ └── more-nested.test.ts │ │ └── nested-example.test.ts │ └── example.test.ts └── tsconfig.json
以下是几种可行的解决方法:
方法1:使用第三方glob工具批量执行
安装glob包作为开发依赖:
npm install --save-dev glob
在package.json的scripts中添加测试命令:
"scripts": { "test": "glob -c 'node --loader tsx --test' '**/*.test.ts'" }
执行npm test即可,glob工具会先递归找到所有*.test.ts文件,再逐个传给Node.js测试命令。
方法2:用shell命令递归查找文件(适用于类Unix环境)
直接使用find命令定位所有测试文件并执行:
find . -name "*.test.ts" -type f -exec node --loader tsx --test {} +
这个命令会递归遍历当前目录下所有*.test.ts文件,批量传给测试运行器。
方法3:使用测试运行器的编程式API自定义查找逻辑
创建一个测试入口文件(如run-tests.ts),手动递归查找并加载测试文件:
import fs from 'node:fs/promises'; import path from 'node:path'; // 递归查找所有测试文件 async function findTestFiles(dir: string): Promise<string[]> { const entries = await fs.readdir(dir, { withFileTypes: true }); let testFiles: string[] = []; for (const entry of entries) { const fullPath = path.resolve(dir, entry.name); if (entry.isDirectory()) { testFiles = [...testFiles, ...await findTestFiles(fullPath)]; } else if (entry.isFile() && entry.name.endsWith('.test.ts')) { testFiles.push(fullPath); } } return testFiles; } // 加载并运行所有测试 async function runAllTests() { const testFiles = await findTestFiles('./src'); for (const file of testFiles) { // 动态导入测试文件 await import(`file://${file}`); } } runAllTests().catch(err => { console.error('测试执行失败:', err); process.exit(1); });
然后执行tsx run-tests.ts即可,这种方式灵活性最高,还能根据需求自定义过滤规则。
内容的提问来源于stack exchange,提问作者Zach Lysobey
相关产品推荐
相关产品推荐

