A) 最“天真”(1 分钟完成)的解决方案,假设您使用的 linux/macOs 实际上工作得还不错(只是为了在本地重新运行回归),以使用 bash 脚本最后简单&
# to keep vid,pic could cause issue when trying to write and delete at the same time
export CYPRESS_trashAssetsBeforeRuns=false
XDG_CONFIG_HOME=/tmp/cyhome1 cypress run -spec cypress/integration/first.spec.js,cypress/integration/another1.spec.js &
XDG_CONFIG_HOME=/tmp/cyhome2 cypress run -spec cypress/integration/another2.spec.js,cypress/integration/another3.spec.js &
B) 但是,如果您想要更“复杂”的东西,请继续阅读:
但是,在我们的测试中,我们在 4 个数据中心(aws、gc)上运行相同的回归,并且在每个数据中心上运行多个品牌(有些是为了冗余,有些是特定于该 DC 位置),因此对于我们的需求,我们不需要规格平衡。而是平行于柏树进程。
到目前为止,这似乎运作良好,你需要几个先决条件,因为你可以read here。我们不得不解决一些问题。
- Xvfb 竞争条件
- 具有限制线程数量的能力
- 配置文件锁定问题
- 图片访问问题
- 在运行我们的并行运行脚本之前启动 Xvfb。
# Start x11 server to avoid race condition in threads
Xvfb :96 &
# Make all cypress instances connect to the spawned x11
export DISPLAY=:96
# Read 4)
export CYPRESS_trashAssetsBeforeRuns=false
# read below (that's where the parallelization happens node.js 10+)
node ./main.js
- 那里有更好更强大的解决方案,但这似乎对我们有用。上面的 bash 运行下面的
main.js。
每个品牌数组都是并行执行的,但awaited 会执行每个系列forEachSeries,没有它,您只需并行运行所有内容(而不是 2,您将拥有 4 个 threads)。
因此,只要您可以创建一个数组,第一级数组的数量就会定义并行线程的数量。您可以谷歌搜索平衡阵列功能并使用它来平衡阵列,如果您决定平衡规格而不是我们下面所做的“品牌”,您只需修改传递给awaitedSpawn() 的命令类似于XDG_CONFIG_HOME=/tmp/cyhome${cfg.id} cypress run --spec {cfg.spec} .
// main.js
// this part is synchronous
if (run.THREADS_NO >= 2) {
// 2 threads with 2 brands each
const threads = {[[brand: "brand1"],[brand: "brand2"],[[brand: "brand3"],[brand: "brand4"]]};
threads.forEach((threadBrandInfo) => {
asyncWrapper(threadBrandInfo);
});
}
// async_stuff.js
// courtesy of https://github.com/toniov/p-iteration
exports.forEachSeries = async (array, callback, thisArg) => {
for (let i = 0; i < array.length; i++) {
if (i in array) {
await callback.call(thisArg || this, await array[i], i, array);
}
}
};
const awaitedSpwan = async (cmd) => {
const child = await exec(cmd);
return new Promise((resolve, reject) => {
child.on('close', (code) => {
if (code === 0) {
resolve(child.stdout);
} else {
const err = new Error(child.stdout,child.stderr);
reject(err);
}
});
});
}
const asyncWrapper = async (brandsConfigs) => {
forEachSeries(brandsConfigs, async (cfg) => {
await awaitedSpawn(`XDG_CONFIG_HOME=/tmp/cyhome${cfg.brand} cypress run`)
.then((res) => {
console.log(res);
return res;
})
.catch((e) => {
console.error(e.stderr);
});
});
};
-
上面这部分代码解决了这个问题XDG_CONFIG_HOME=/tmp/cyhome1
-
只需设置 cypress env var trashAssetsBeforRuns=false
一种方法是使用 cypress.json 或 1) 中的 bash 脚本