没有赛普拉斯仪表板的赛普拉斯并行化

Joh*_*hnD 7 continuous-integration dependencies offline node.js cypress

有没有办法在不访问 cypress 仪表板的情况下运行并行 cypress 执行程序?

我正在尝试让 cypress 并行运行我的测试,但似乎您必须具有互联网连接才能访问 cypress 仪表板以记录测试。

任何人都知道我如何解决这个问题并在不依赖 Cypress Dashboard 或特定 CI 工具(如 Circle CI)的情况下并行运行测试?

提前致谢!

Flo*_*ose 8

看看这个免费的解决方案https://github.com/agoldis/sorry-cypress 我只使用docker-compose中的director服务来使测试并行运行,作为一个简单的例子:

version: '3.7'
networks:
  default:
    external:
      name: bridge

services:
  cypress:
    container_name: cypress
    build:
      context: ../
      dockerfile: ./docker/cy.Dockerfile
    links:
      - director
    ports:
      - '5555:5555'
    network_mode: bridge

  cypress2:
    container_name: cypress2
    build:
      context: ../
      dockerfile: ./docker/cy.Dockerfile
    links:
      - director
    ports:
      - '5556:5556'
    network_mode: bridge

  mongo:
    image: mongo:4.0
    network_mode: bridge
    ports:
      - 27017:27017

  director:
    image: agoldis/sorry-cypress-director:latest
    environment:
      MONGODB_URI: "mongodb://mongo:27017"
    network_mode: bridge
    ports:
      - 1234:1234
    depends_on:
      - mongo
Run Code Online (Sandbox Code Playgroud)

  • @floydrose 可以解释为什么你使用两个 cypress 服务吗? (2认同)

jlh*_*jlh 5

所有这些答案看起来都很好,但我想要一些非常简单的东西可以与 GitLab 一起使用,不需要额外的外部服务。我想出了这个非常简单的 Cypress 包装:

const path = require('path');
const fs = require('fs');
const childProcess = require('child_process');
const glob = require('glob-promise');

async function getIntegrationDirectory() {
    let integrationFolder = 'cypress/integration';
    let cypressJson = path.join(process.cwd(), 'cypress.json');
    try {
        await fs.promises.access(cypressJson, fs.constants.F_OK);
        let cypressConfig = require(cypressJson);
        integrationFolder = cypressConfig.integrationFolder ?? integrationFolder;
    }
    catch (err) {
        // Ignore if file does not exist
    }
    return integrationFolder;
}

async function main() {
    let nodeIndex = parseInt(process.env.CI_NODE_INDEX ?? 1, 10);
    let totalNodes = parseInt(process.env.CI_NODE_TOTAL ?? 1, 10);
    let integrationFolder = await getIntegrationDirectory();
    let specs = await glob(integrationFolder + '/**/*.js');
    let start = (nodeIndex - 1) * specs.length / totalNodes | 0;
    let end = nodeIndex * specs.length / totalNodes | 0;
    let specsToRun = specs.slice(start, end);
    let prefix = `Parallel Cypress: Worker ${nodeIndex} of ${totalNodes}`;
    if (!specsToRun.length) {
        console.log(`${prefix}, no specs to run, ${specs.length} total`);
        return;
    }
    console.log(`${prefix}, running specs ${start + 1} to ${end} of ${specs.length} total`);
    let args = process.argv.slice(2)
        .concat(['--spec', specsToRun.join(',')]);
    let child = childProcess.spawn('cypress', args, {stdio: 'inherit', shell: true});
    await new Promise((resolve, reject) => {
        child.on('exit', exitCode => {
            if (exitCode) {
                reject(new Error(`Child process exited with code ${exitCode}`));
            }
            resolve();
        });
    });
}

main().catch(err => {
    console.error(err);
    process.exit(1);
});
Run Code Online (Sandbox Code Playgroud)

它需要glob-promiseglob安装。

它与 GitLab 的并行关键字很好地集成,并且只需最少的修改即可与其他 CI 运行程序一起使用。

要使用它,只需添加parallel: 4到 GitLab CI 作业,然后调用node parallelCypress.js <some options>. 然后,它将扫描测试并将其拆分为可用的并行作业,然后使用该--spec选项调用 cypress,以便每个作业仅运行一部分测试。

不过,还有很大的改进空间,特别是因为并非所有规范文件都包含相同数量的测试,并且并非所有测试都具有相似的运行时。