3Do*_*Dos 9 node.js es6-promise jestjs frisby.js
我测试的内容:快速服务器端点
我的目标:在单个脚本中自动化 API 测试
我做什么:我在 NodeJS 子进程中启动 express 服务器,并希望在运行测试套件之前等待它启动(frisby.js 端点测试)
什么没有按预期工作:在 Promise 解决之前启动测试套件
wait-on一旦资源可用,我依赖于服务器轮询和解析的包。
const awaitServer = async () => {
await waitOn({
resources: [`http://localhost:${PORT}`],
interval: 1000,
}).then(() => {
console.log('Server is running, launching test suite now!');
});
};
Run Code Online (Sandbox Code Playgroud)
这个函数用在startServer函数中:
const startServer = async () => {
console.log(`Launching server http://localhost:${PORT} ...`);
// npmRunScripts is a thin wrapper around child_process.exec to easily access node_modules/.bin like in package.json scripts
await npmRunScripts(
`cross-env PORT=${PORT} node -r ts-node/register -r dotenv/config src/index.ts dotenv_config_path=.env-tests`
);
await awaitServer();
}
Run Code Online (Sandbox Code Playgroud)
最后,我在类似的东西中使用它
describe('Endpoints' () => {
beforeAll(startTestServer);
// describes and tests here ...
});
Run Code Online (Sandbox Code Playgroud)
无论如何,当我启动 jest 时,'Server is running, launching test suite now!'console.log 永远不会出现并且测试套件失败(因为服务器尚未运行)。为什么 jest 开始测试,因为awaitServer显然还没有解决?
该npmRunScripts功能运行良好,因为测试服务器在测试失败后不久就会启动并运行。对于这个问题,以下是 npmRunScripts 的解决方法:
// From https://humanwhocodes.com/blog/2016/03/mimicking-npm-script-in-node-js/
const { exec } = require('child_process');
const { delimiter, join } = require('path');
const env = { ...process.env };
const binPath = join(__dirname, '../..', 'node_modules', '.bin');
env.PATH = `${binPath}${delimiter}${env.PATH}`;
/**
* Executes a CLI command with `./node_modules/.bin` in the scope like you
* would use in the `scripts` sections of a `package.json`
* @param cmd The actual command
*/
const npmRunScripts = (cmd, resolveProcess = false) =>
new Promise((resolve, reject) => {
if (typeof cmd !== 'string') {
reject(
new TypeError(
`npmRunScripts Error: cmd is a "${typeof cmd}", "string" expected.`
)
);
return;
}
if (cmd === '') {
reject(
new Error(`npmRunScripts Error: No command provided (cmd is empty).`)
);
return;
}
const subProcess = exec(
cmd,
{ cwd: process.cwd(), env }
);
if (resolveProcess) {
resolve(subProcess);
} else {
const cleanUp = () => {
subProcess.stdout.removeAllListeners();
subProcess.stderr.removeAllListeners();
};
subProcess.stdout.on('data', (data) => {
resolve(data);
cleanUp();
});
subProcess.stderr.on('data', (data) => {
reject(data);
cleanUp();
});
}
});
module.exports = npmRunScripts;
Run Code Online (Sandbox Code Playgroud)
3Do*_*Dos 10
我找到了解决方案。在尝试了几乎所有事情之后,我没有意识到 jest 有一个默认为 5 秒的超时设置。所以我增加了这个超时时间,现在测试等待服务器承诺解决。
我只是jest.setTimeout(3 * 60 * 1000);在测试套件之前添加。
就我而言,它是由beforeAll零件缺陷引起的。确保beforeAll不包含任何未捕获的异常,否则它将表现为测试开始而不等待beforeAll解析。
beforeAll经过多次挖掘,我找到了为什么我的测试在测试之前似乎没有运行的原因。这对某些人来说可能是显而易见的,但对我来说却不是。
如果您的外部有代码describean itor other beforeXor afterY,并且该代码依赖于 any beforeX,您将遇到此问题。
问题是您中的代码describe在任何beforeX. 因此,该代码将无法访问任何beforeX.
例如:
describe('Outer describe', () => {
let server;
beforeAll(async () => {
// Set up the server before all tests...
server = await setupServer();
});
describe('Inner describe', () => {
// The below line is run before the above beforeAll, so server doesn't exist here yet!
const queue = server.getQueue(); // Error! server.getQueue is not a function
it('Should use the queue', () => {
queue.getMessage(); // Test fails due to error above
});
});
});
Run Code Online (Sandbox Code Playgroud)
对我来说,这似乎出乎意料,考虑到代码是在describe回调中运行的,所以我的印象是该回调最终会beforeX在当前describe.
这种行为似乎不会很快改变:https ://github.com/facebook/jest/issues/4097
| 归档时间: |
|
| 查看次数: |
4796 次 |
| 最近记录: |