针对已编译的包运行测试

And*_*aro 6 javascript unit-testing jestjs

作为JS 库作者,我以以下格式编译和发布我的源代码:

  • 通用JS ( /lib/index.js)
  • ES ( /es/index.js)
  • UMD ( /dist/index.js)

我的单元测试涵盖了我的源代码,我相信我的捆绑/编译工具可以生成工作包。

然后我读到了React 团队这篇富有启发性的文章,他们解释说他们针对该库的捆绑版本运行了部分单元测试。

他们引入了一个使用特殊配置文件运行 Jest 的test-build-prod程序,该配置文件替换了测试中的原始导入声明,以使用 Jest 的选项指向捆绑文件。moduleNameMapper

这很酷,但在我的小型开源项目中复制有点难以承受。

在尝试之前,我是否应该考虑使用任何其他工具或更便携的解决方案来针对编译的包运行我在源代码上运行的相同测试?

And*_*aro 9

我将分享我最终采用的解决方案,该解决方案与 React 团队采用的解决方案相同,但规模较小。

我添加了一个特殊的npm 脚本来针对每个已编译的包运行单元测试,每个包都有不同的Jest 配置:

{
    "test:bundles": "jest --config ./jest/es.config.js && jest --config ./jest/lib.config.js && jest --config ./jest/dist.config.js"
}
Run Code Online (Sandbox Code Playgroud)

每个 Jest 配置文件都扩展默认的 Jest 配置并声明一个moduleNameMapper对象和一个rootDir属性,例如:

// jest/lib.config.js
const pkg = require('../package.json');

module.exports = Object.assign({}, pkg.jest, {
  rootDir: '../',
  moduleNameMapper: {
    '/src/index$': '<rootDir>/lib/index', // path of "CommonJS" bundle
  },
});
Run Code Online (Sandbox Code Playgroud)

moduleNameMapper将确保用于源代码的相同测试将针对导出的包运行,因为Jest 将在运行时转换导入语句,例如:

import myLibrary from './src/index';
// transformed into:
import myLibrary from '../lib/index';
Run Code Online (Sandbox Code Playgroud)

唯一需要注意的一点是使需要重新映射的测试导入语句可以很容易被moduleNameMapper正则表达式识别。

如果import from './index'在测试文件时不够唯一,它可能会被重写为import from '../src/index'.