于2018/07/13更新:
到处乱搞之后,我弄清楚了testRegex
为何不起作用。请参阅下面发布的我自己的答案。
原始问题:
我正在为我的React.js项目编写测试代码。我正在使用react-scripts
和enzyme
(我相信也暗示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.js,但这是我现在不能更改的内容,因为它不是我的个人项目。)
我不了解的是,testRegex
中的jest
无法正常工作。目前,我将所有测试文件放在__tests__
文件夹下,并将其命名为“ something.test.js”。但是,如果您查看上面的testRegex
,首先,它不会查找__tests__
,而是将abc
作为文件夹名称,其次,它不会查找{{1 }},但以test
作为文件名。
由于上述配置,我期望测试文件根本不会被执行。但是,当我运行defg
时,测试文件仍然被执行。
我做错了什么?
我的一些想法:
npm test
可能不支持jest@18.1.0
。testRegex
配置jest
,但是它的用户指南似乎表明我可以按照自己的方式配置玩笑(在package.json中放入“玩笑”部分) 。react-scripts
v23.3,但仍然无法按预期工作。jest
,但是文档中显示"note that you cannot specify both options",所以我假设如果在testMatch
中指定了testRegex
,则package.json
是忽略了。这是真的吗?答案 0 :(得分:1)
乱搞之后,我意识到这是因为如果您使用react-scripts
(请注意,这是指向标记testRegex
的链接)来运行测试,则v0.9.5
不能被覆盖较旧的或最新的版本(在我发布此答案时,react-scripts
的最新版本为1.1.4
)。
这里有更多详细信息。
在上面的原始问题中,我使用的是react-scripts v0.9.5
。当我运行CI=true npm test
进行测试时,实际运行的是react-scripts/scripts/test.js
。这是一个包装脚本,最终仍会调用jest
。在this line中,它创建Jest配置并作为其jest
选项传递到--config
中:
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和该{{1} }函数是imported from jest-config
module。
然后让我们看一下readConfig
模块。上述jest-config
在this file中定义。
readConfig
函数调用readConfig
,然后通过调用readRawConfig
包括从argv
设置的配置:
setFromArgv
这是const readConfig = (argv: any, packageRoot: string) =>
readRawConfig(argv, packageRoot)
.then(config => Object.freeze(setFromArgv(config, argv)));
实现,其中包含有关行的内容的评论(以“ ywen”开头)
readRawConfig
setFromArgv
用argv上提供的配置覆盖了配置,但是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)
});
};
是其中的一个。
如果您在命令行上提供自己的testRegex
,例如--config
,则将两个CI=true npm test -- --config ./jest.config.js /path/to/your/test/file.js
项添加到传递给jest的--config
中:提供了一个另一个是由您(由秘密)由react-scripts的argv
创建的。它们在createJestConfig
中分组为列表:
argv.config
当 config:
[ './jest.config.js',
'{"collectCoverageFrom":["src/**/*.{js,jsx}"],...'
],
调用parseConfig
时,readRawConfig
测试失败,因为传入的值是一个列表,而不是字符串。结果,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}"], ...
}'
或0
不是有效的Jest配置,最终将在this line失败。
结果,在使用1
时,其react-scripts v0.9.5
脚本不支持test
的自定义。
testRegex
仍然是这种情况,这是撰写本文时的最新版本。 createJestConfig.js
:它允许some of the keys to be overridden,但react-scripts v1.1.4
仍然不是其中之一。
答案 1 :(得分:1)
为什么不尝试仅使用testMatch
选项?
如果您有jest.config.js
文件,只需编写以下代码:
const path = required('path)
module.exports = {
rootDir: path.join(__dirname, './'),
roots: [path.join(__dirname, './abc')],
projects: [
{
displayName: 'Functional',
testMatch: [ '**/__tests__/**/*test.js?(x)' ]
},
{
displayName: 'Integration API ',
testMatch: [ '**/__tests__/**/*spec.js?(x)' ]
},
]
}
您的测试文件看起来像
├── abc/
│ │__tests__/
│ ├── login.spec.js # test
│ └── anything.txt # not test
│ └── method.test.js # test
│
├── package.json # not test
├── server.js # not test
└── jest.config.js # not test (this your jest config)
答案 2 :(得分:0)
尝试: 创建一个名为jest.config.js的单独文件
module.exports = {
coverageDirectory: "coverage",
moduleFileExtensions: [
"ts",
"tsx",
"js"
],
testEnvironment: "node",
testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",
};