reactjs - testRegex 掩码选择错误的文件来运行测试

标签 reactjs configuration jestjs

2018/07/13更新:

在四处寻找之后,我弄明白了为什么 testRegex 不起作用。请参阅下面发布的我自己的答案。


原始问题:

我正在为我的 React.js 项目编写测试代码。我正在使用 react-scriptsenzyme(我相信这也意味着 jest)来运行和管理测试。这是 package.json 文件:

{
  "name": "front",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "react": "~15.5.4",
    "react-dom": "~15.5.4",
    "react-scripts": "0.9.5",
    "redux": "~3.6.0",
    "react-redux": "~5.0.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  },
  "devDependencies": {
    "enzyme": "^3.3.0",
    "enzyme-adapter-react-15": "^1.0.6",
    "react-test-renderer": "~15.5.4"
  },
  "jest": {
    "testRegex": "(/abc/.*|(\\.|/)(defg|spec))\\.jsx?$"
  }
}

npm install 之后,我检查了版本:

  • react-scripts@0.9.5
  • enzyme @3.3.0
  • 开 Jest @18.1.0

(是的,我知道我使用的是旧版本的 React.js,但这是我现在无法更改的,因为它不是我的个人项目。)

我不明白的是 jesttestRegex 没有像我预期的那样工作。目前,我将所有测试文件放在 __tests__ 文件夹下,并将它们命名为“something.test.js”。但是,如果您查看上面的 testRegex,首先,它不会查找 __tests__,而是查找 abc 作为文件夹名称,其次,它不会查找 test,而是查找 defg 作为文件名。

由于上面的配置,我预计我的测试文件根本不会被执行。然而,当我运行 npm test 时,测试文件仍然被执行。

我做错了什么?

我的一些想法:

  • jest@18.1.0 可能不支持 testRegex
  • 我可能需要通过 react-scripts 配置 jest 但它的用户指南似乎表明我可以按照我正在做的方式配置 jest(放置一个“package.json 中的 Jest ”部分)。
  • 我也试过使用最新的jest v23.3,但还是没有达到预期效果。
  • 我知道 testMatch,但文档说 "note that you cannot specify both options" ,所以我假设如果我在 package.json 中指定了 testRegex,则忽略 testMatch。这是真的吗?

最佳答案

在四处寻找之后,我意识到这是因为如果使用 react-scripts 则无法覆盖 testRegex (注意它是指向标签 v0.9.5 的链接)以在旧版本或最新版本中运行测试(在我发布此答案时,最新版本的 react -scripts1.1.4)。

这里有更多详细信息。

在我上面的原始问题中,我使用的是 react-scripts v0.9.5 .当我运行 CI=true npm test 来运行测试时,它是 react-scripts/scripts/test.js那实际上是运行的。这是一个包装脚本,最终仍然调用 jest。在 this line ,它创建 Jest 配置并作为其 --config 选项传递到 jest 中:

argv.push('--config', JSON.stringify(createJestConfig(
  relativePath => path.resolve(__dirname, '..', relativePath),
  path.resolve(paths.appSrc, '..'),
  false
)));

追踪 this file 中的 createJestConfig 函数,您会看到它创建了一些 Jest 配置项并将它们作为 JavaScript 对象返回。

因此,jest(我使用的是 18.1.0)最终使用具有字符串化 JSON 的 --config 选项运行字符串。

如果你追踪 jest.run,它最终会出现 this runCli function (这是指向 v18.1.0 的链接)读取配置 here , 这个 readConfig 函数是 imported from jest-config module .

然后我们来看jest-config模块。上述readConfig定义在this file中.

readConfig 函数调用 readRawConfig,然后通过调用 setFromArgv 包含从 argv 设置的配置:

const readConfig = (argv: any, packageRoot: string) =>
  readRawConfig(argv, packageRoot)
    .then(config => Object.freeze(setFromArgv(config, argv)));

这是 readRawConfig 实现,其中包含我对这些行的作用的评论(前面是“ywen”):

const parseConfig = argv => {
  if (argv.config && typeof argv.config === 'string') {
    // If the passed in value looks like JSON, treat it as an object.
    if (argv.config[0] === '{' && argv.config[argv.config.length - 1] === '}') {
      return JSON.parse(argv.config);
    }
  }
  return argv.config;
};

const readRawConfig = (argv, root) => {
  // [ywen]
  // Calls the `parseConfig` above. Remember that react-scripts's
  // test.js passes in the configuration as a stringified JSON
  // string, so the "If the passed in value looks like JSON..."
  // test is met. The stringified JSON string is read and parsed
  // back to a JavaScript object, returned, and stored in the
  // rawConfig variable.
  const rawConfig = parseConfig(argv);

  if (typeof rawConfig === 'string') {
    return loadFromFile(path.resolve(process.cwd(), rawConfig));
  }

  if (typeof rawConfig === 'object') {
    // [ywen]
    // Because `rawConfig` is a JS object, this if branch is
    // executed. The function returns with the normalized
    // configuration, so the `loadFromPackage` function, which
    // reads the `jest` configuration from the `package.json`,
    // is **NOT** called.
    const config = Object.assign({}, rawConfig);
    config.rootDir = config.rootDir || root;
    return Promise.resolve(normalize(config, argv));
  }

  return loadFromPackage(path.join(root, 'package.json'), argv).
  then(config => {
    console.log('package.json config: ', config);
    config || normalize({ rootDir: root }, argv)
  });
};

setFromArgv使用 argv 上提供的配置覆盖配置,但 testRegex不是其中之一。

如果您在命令行上提供自己的 --config 例如 CI=true npm test -- --config ./jest.config.js/path/to/your/test/file.js,传递给jest的argv中会添加两个--config项:一个是你提供的,另一个是( secret 地)由 react-scripts 的 createJestConfig 创建。它们在 argv.config 中被分组为一个列表:

  config: 
   [ './jest.config.js',
     '{"collectCoverageFrom":["src/**/*.{js,jsx}"],...'
   ],

parseConfigreadRawConfig 调用时,if (argv.config && typeof argv.config === 'string') { 测试失败,因为传入的值是列表,而不是字符串。结果,parseConfig 按原样返回此列表。此列表随后存储在 rawConfig 中。 rawConfig 的类型仍然是object。但是在 const config = Object.assign({}, rawConfig); 行中,它被转换为如下内容:

{ '0': './jest.config.js',
  '1': '{"collectCoverageFrom":["src/**/*.{js,jsx}"], ...
}'

最终会在 this line 处失败因为 01 不是有效的 Jest 配置。

因此,在使用react-scripts v0.9.5时,其test脚本不支持自定义testRegex

react-scripts v1.1.4 中仍然如此,这是撰写本文时的最新版本。 createJestConfig.js : 它允许 some of the keys to be overridden , 但 testRegex 仍然不是其中之一。

关于reactjs - testRegex 掩码选择错误的文件来运行测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51294574/

相关文章:

reactjs - 使用 Jest 和 enzyme 测试 React Typescript 组件的副作用

reactjs - Material 样式未加载到生产构建中

c# - .Net 6函数应用程序无法从Azure应用程序设置获取值

javascript - 如何使用Jest和Axios进行功能覆盖?

reactjs - 如果使用另一个可选 Prop ,我可以将 Typescript 必需的 Prop 更改为不需要吗?

reactjs - 如何使用 Typescript 和 styled-components 创建 ref

java - 如何管理客户端特定配置

java - org.springframework.beans.factory.annotation.InjectionMetadata.needsRefresh

reactjs - 类型错误 : Cannot read property 'forEach' of undefined jest

reactjs - 如何测试解决 promise 然后在 React 中更改状态的方法?