Github Actions 上的 Mocha 并行作业

如何解决Github Actions 上的 Mocha 并行作业

我刚刚切换到 Mocha 中的并行测试,这很好用,但是,当我在 github 上运行它时,它似乎没有并行运行。我需要配置什么才能让 Mocha 在 Github Actions 上并行运行?

.mocharc.json // 摩卡 9.x

{
  "timeout": 5000,"recursive": true,"ui": "mocha-cakes-2","parallel": true,"jobs": 4,"checkLeaks": true,"globals": [
    "browser","mocha-cakes-2","regeneratorRuntime"
  ],"exit": true,"require": ["./test/helpers/setup.js"]
}

node.js.yml

name: Node.js CI

on: [push]

jobs:
  build:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [14.x]

    steps:
      - uses: actions/checkout@v2

      - name: Cache node modules
        uses: actions/cache@v2
        env:
          cache-name: cache-node-modules
        with:
          # npm cache files are stored in `~/.npm` on Linux/macOS
          path: ~/.npm
          key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            ${{ runner.os }}-build-${{ env.cache-name }}-
            ${{ runner.os }}-build-
            ${{ runner.os }}-
      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v1
        with:
          node-version: ${{ matrix.node-version }}

      - run: npm ci
      - run: npm run build --if-present
      - run: npm test

解决方法

我设法让它工作:

  • 通过 findAllTests.js 获取所有测试文件
  • 然后我用 jq 将这个文件的输出分成 3 个相等的块。
  • 然后我存储来自 npm run build 的工件并准备在下一阶段使用它们。
  • 然后我连续启动 3 个测试运行程序(随着您的项目变大,可以轻松配置)
  • 最后,无论之前的任何步骤是否失败,我都会删除这些工件(我们不需要它们)

Parallel Tests in Mocha

findAllTests.js

"use strict";

const fs = require("fs");
const path = require("path");

const files = [];

function shuffleArray(unshuffledArray) {
  // Schwartzian transform. Will eventually help in evening out the test-time for each chunk.
  return unshuffledArray
    .map((a) => ({ sort: Math.random(),value: a }))
    .sort((a,b) => a.sort - b.sort)
    .map((a) => a.value);
}

/**
 * Traverses through all subdirectories of a given folder.
 * Used for Github Actions in order to aggregate and chunk all tests into even sizes.
 */

function findAllTests(directory) {
  fs.readdirSync(directory).forEach((file) => {
    const absolute = path.join(directory,file);
    if (fs.statSync(absolute).isDirectory()) {
      return findAllTests(absolute);
    }
    if (absolute.endsWith(".js") && !/(findAllTests|\/data\/|\/helpers\/)/.test(absolute)) {
      return files.push(absolute);
    }
  });
}

function isMocha(context) {
  return ["afterEach","after","beforeEach","before","describe","it"].every((functionName) => {
    return context[functionName] instanceof Function;
  });
}

if (!isMocha(global)) {
  findAllTests("./test/");
  console.log(JSON.stringify(shuffleArray(files),null,2)); // eslint-disable-line
}

node.yml.js

name: Node.js CI

on: [push]

jobs:
  setup:
    runs-on: ubuntu-latest
    name: Setup
    strategy:
      matrix:
        node-version: [14.x]
    outputs:
      test-chunks: ${{ steps['set-test-chunks'].outputs['test-chunks'] }}
      test-chunk-ids: ${{ steps['set-test-chunk-ids'].outputs['test-chunk-ids'] }}
    steps:
      - uses: actions/checkout@v2
      - name: Cache node modules
        uses: actions/cache@v2
        env:
          cache-name: cache-node-modules
        with:
          path: ~/.npm
          key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            ${{ runner.os }}-build-${{ env.cache-name }}-
            ${{ runner.os }}-build-
      - name: Install & Build
        run: |
          npm ci
          npm run build --if-present
      - name: ESLint
        run: npm run lint:js
      - name: Save build artifacts
        uses: actions/upload-artifact@v2
        with:
          name: public
          path: public
      - id: set-test-chunks
        name: Set Chunks
        run: echo "::set-output name=test-chunks::$(node ./test/findAllTests.js | jq -cM '[_nwise(length / 3 | ceil)]')"
      - id: set-test-chunk-ids
        name: Set Chunk IDs
        run: echo "::set-output name=test-chunk-ids::$(echo $CHUNKS | jq -cM 'to_entries | map(.key)')"
        env:
          CHUNKS: ${{ steps['set-test-chunks'].outputs['test-chunks'] }}
  mocha:
    runs-on: ubuntu-latest
    name: Test (chunk ${{ matrix.chunk }})
    needs: setup
    strategy:
      matrix:
        node-version: [14.x]
        chunk: ${{ fromJson(needs.setup.outputs['test-chunk-ids']) }}
    steps:
      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v1
        with:
          node-version: ${{ matrix.node-version }}
      - uses: actions/checkout@v2
      - run: npm ci
      - name: Download build artifacts
        uses: actions/download-artifact@v2
      - name: Mocha
        run: echo $CHUNKS | jq '.[${{ matrix.chunk }}] | .[] | @text' | xargs npm run mocha:ga
        env:
          CHUNKS: ${{ needs.setup.outputs['test-chunks'] }}
  cleanup:
    runs-on: ubuntu-latest
    name: Cleanup
    needs: [setup,mocha]
    if: always()
    steps:
      - uses: geekyeggo/delete-artifact@v1
        with:
          name: public
          failOnError: false

mocharc.json

{
  "timeout": 5000,"recursive": true,"ui": "mocha-cakes-2","checkLeaks": true,"globals": [
    "browser","document","mocha-cakes-2","regeneratorRuntime","WebSocket","window"
  ],"exit": true,"no-warnings": true,"require": ["./test/helpers/setup.js"]
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?