有什么方法可以在本地计算机上运行并行cypress测试,例如5个流

时间:2019-08-09 04:32:04

标签: continuous-integration cypress

我正在尝试在本地计算机上设置cypress并运行并行测试。但是我找不到一些信息。

5 个答案:

答案 0 :(得分:5)

从技术上讲,这是可能的。赛普拉斯不建议这样做,因为在同一台计算机上运行多个赛普拉斯实例会消耗大量资源(全部CPU),并且会降低整个计算机的性能,并导致无用的结果。

无论如何,如果资源有限并且不能使用官方仪表板,或者没有多个CI服务器可用,则可以在一台启动cypress的计算机上运行测试多次,将测试套件划分为多个文件夹

我创建了一个名为cypress-parallelhttps://github.com/tnicola/cypress-parallel)的npm库,该库(在第一次运行后)根据测试运行历史记录以及每个测试库,将测试套件平衡并分为多个子集子集,它将启动Cypress命令。它还从所有规格文件中收集结果,并在执行结束时记录它们。在性能方面,似乎通过2个流程,您可以将总体测试执行时间缩短40%。

答案 1 :(得分:1)

好吧,我有点在本地并行运行它们。使用一些想法:

  1. 我有一台MacBook,因此已在iOS上实现。
  2. 我的应用程序在Docker容器中运行,我只需要一个实例即可同时运行多个测试。通过我的终端,我创建了多个文件,将规范拆分成单独的.command文件,如下所示: echo "cd <PROJECT_DIRECTORY> && npx cypress run --spec cypress/integration/<SPECS_DIRECTORY>/*" > cypress.command; chmod +x cypress.command 您可以在--spec后面堆叠多个目录/文件,因此--spec cypress/integration/<SPECS_DIRECTORY>/* cypress/integration/<SPECS_DIRECTORY2>/*也是有效的。
  3. 可以说我有2个.command文件。我可以使用以下命令启动它们: open cypress-01.command cypress-02.command
  4. 这将启动两个单独的终端,两个终端都运行每个文件中提到的规范。

这将本地测试的运行时间从1.5小时减少到15分钟。

答案 2 :(得分:0)

Bazel+rules_nodejs 能够在同一台机器上并行运行多个 cypress 测试。但是,在 bazel 中编写 cypress 测试的体验将与您习惯的完全不同。

https://github.com/bazelbuild/rules_nodejs/tree/2.0.0-rc.3/examples/cypress

答案 3 :(得分:0)

我创建了一个名为 orchestrator (https://github.com/0xIslamTaha/orchestrator) 的 npm 工具,以便能够在一台机器上运行您的所有规范。它在底层使用 docker,并将所有规范拆分到多台 docker 机器上。

特点:

  • 开源。
  • 自动拆分所有规格。
  • 支持多种浏览器。
  • 生成漂亮的 HTML 报告。
  • 易于配置。
  • 与 docker 合作得很好。
  • 完整记录。
  • 有一个开源用例存储库(准备就绪)。

文章

展示案例

答案 4 :(得分:0)

最“天真”的解决方案,假设您在 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 &

然而,在我们的测试中,我们在 4 个数据中心 (aws,gc) 上运行相同的回归,并且在每个数据中心上运行多个品牌(有些用于冗余,有些特定于该 DC 位置),因此对于我们的需求,我们不需要规格平衡。与柏树工艺平行。

到目前为止,这似乎运行良好,您需要尽可能read here 的几个先决条件。我们必须解决几个问题。

  1. Xvfb 竞争条件
  2. 具有限制线程数量的能力
  3. 个人资料锁定问题
  4. 图片访问问题

  1. 在运行我们的并行运行脚本之前启动 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
  1. 有更好更强大的解决方案,但这似乎对我们有用。上面的 bash 运行下面的 main.js。 每个品牌数组都是并行执行的,但每个系列的await执行forEachSeries,如果没有它,您将只是并行运行所有内容(而不是 2,您将有 4 个 threads )。 因此,只要您可以创建一个数组,第一级数组的数量就会定义并行线程的数量。您可以谷歌搜索平衡数组函数并使用它来平衡数组,如果您决定平衡规格而不是我们下面所做的“品牌”,您只需要修改传递给 awaitedSpawn() 的命令,例如 { {1}}。
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);
  });
}
  1. 上面这部分代码解决了这个问题// 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); }); }); };

  2. 只需设置 cypress env var XDG_CONFIG_HOME=/tmp/cyhome1 一种方法是使用 cypress.json 或在 trashAssetsBeforRuns=false

    中的 bash 脚本中使用