GiitHub Actions에서 동시에 테스트 및 고속화(parallelism)
15137 단어 GitHub ActionsCItech
직렬로 실행하면 총 5+10+3이 18분 걸린다.
이를 테스트 A와 C만 수행하는 잡과 테스트 B만 수행하는 잡 두 부분으로 나누는데, A+C의 8분과 B의 10분이기 때문에 전체적으로 긴 10분만 기다리면 된다.
졸작 도구인 split-test를 사용하면 JUnit Formt XML에 기록된 실행 시간을 기반으로 간단하게 그룹을 나눌 수 있습니다.
split-test --junit-xml-report-dir <xml があるディレクトリ> --node-index {{ matrix.node_index }} --node-total 2 --tests-glob 'spec/**/*_spec.rb'
처럼 실행하면 nodeindex0spec/a_spec.rb
spec/c_spec.rb
node_index1spec/b_spec.rb
와 같이 그룹 결과를 표준 출력으로 되돌려줍니다.이 결과를 테스트 명령(예를 들어 rspec)에 전달하여 분할합니다.
예:
bin/rspec --format progress --format RspecJunitFormatter --out report/rspec-${{ matrix.node_index }}.xml $(./split-test --junit-xml-report-dir report-tmp --node-index ${{ matrix.node_index }} --node-total 2 --tests-glob 'spec/**/*_spec.rb' --debug)
- debug 옵션을 추가하여 시간 데이터의 분할, 실행 누락을 확인할 수 있습니다.이것은 표준 오류로 출력됩니다.예제https://github.com/mtsmfm/split-test-example/runs/1667231492
[2021-01-08T07:12:09Z WARN split_test] Timing data not found: /home/runner/work/split-test-example/split-test-example/spec/1_spec.rb
...
[2021-01-08T07:12:09Z DEBUG split_test] node 0: recorded_total_time: 16.439781
[2021-01-08T07:12:09Z DEBUG split_test] /home/runner/work/split-test-example/split-test-example/spec/87_spec.rb
[2021-01-08T07:12:09Z DEBUG split_test] /home/runner/work/split-test-example/split-test-example/spec/62_spec.rb
[2021-01-08T07:12:09Z DEBUG split_test] /home/runner/work/split-test-example/split-test-example/spec/53_spec.rb
...
[2021-01-08T07:12:09Z DEBUG split_test] node 1: recorded_total_time: 16.440659
[2021-01-08T07:12:09Z DEBUG split_test] /home/runner/work/split-test-example/split-test-example/spec/97_spec.rb
[2021-01-08T07:12:09Z DEBUG split_test] /home/runner/work/split-test-example/split-test-example/spec/59_spec.rb
[2021-01-08T07:12:09Z DEBUG split_test] /home/runner/work/split-test-example/split-test-example/spec/50_spec.rb
...
[2021-01-08T07:12:09Z DEBUG split_test] node 2: recorded_total_time: 16.450345999999996
[2021-01-08T07:12:09Z DEBUG split_test] /home/runner/work/split-test-example/split-test-example/spec/80_spec.rb
[2021-01-08T07:12:09Z DEBUG split_test] /home/runner/work/split-test-example/split-test-example/spec/64_spec.rb
[2021-01-08T07:12:09Z DEBUG split_test] /home/runner/work/split-test-example/split-test-example/spec/56_spec.rb
...
GiitHub Action에 직접 의존하는 것이 아니라 실행 결과를 저장하고 펼치면 어떤 CI 서비스든 사용할 수 있다.GiitHub Action 프로세스
설정 예는 다음과 같습니다.
on: push
jobs:
# Download test-report and save as test-report-tmp to use the exactly same test report across parallel jobs.
download-test-report:
runs-on: ubuntu-latest
steps:
# Use dawidd6/action-download-artifact to download JUnit Format XML test report from another branch
# https://github.com/actions/download-artifact/issues/3
- uses: dawidd6/action-download-artifact@v2
with:
branch: main
name: test-report
workflow: ci.yml
path: report
# Use continue-on-error to run tests even if test-report is not uploaded
continue-on-error: true
- uses: actions/upload-artifact@v2
with:
name: test-report-tmp
path: report
test:
needs: download-test-report
runs-on: ubuntu-latest
strategy:
matrix:
node_index: [0, 1, 2]
steps:
- uses: actions/checkout@v2
- uses: ruby/setup-ruby@v1
with:
bundler-cache: true
ruby-version: 3.0.0
- uses: actions/download-artifact@v2
with:
name: test-report-tmp
path: report-tmp
# Use continue-on-error to run tests even if test-report is not uploaded
continue-on-error: true
- run: |
curl -L --out split-test https://github.com/mtsmfm/split-test/releases/download/v0.3.0/split-test-x86_64-unknown-linux-gnu
chmod +x split-test
- run: bin/rspec --format progress --format RspecJunitFormatter --out report/rspec-${{ matrix.node_index }}.xml $(./split-test --junit-xml-report-dir report-tmp --node-index ${{ matrix.node_index }} --node-total 3 --tests-glob 'spec/**/*_spec.rb' --debug)
- uses: actions/upload-artifact@v2
with:
name: test-report
path: report
if-no-files-found: error
# Upload test-report on main branch only to avoid conflicting test report
if: github.ref == 'refs/heads/main'
분할 수법
내부는 탐욕법로 분할한다.
구체적으로 말하면 모든 파일에 실행 시간을 더하고 실행 시간이 많은 순서대로 배열하며 그룹의 총 실행 시간이 가장 적다.
엄밀히 말하면 가장 적합한 분할이 아닐 수도 있지만 대부분의 경우 queue의 시간 등이 수초~10초 엇갈리기 때문에 여기가 가장 적합하지 않아도 오차의 범주가 되어야 한다.
실제 사용하다가 심각한 상황이 발견되면issue로 보고.
잡담: JunIt Format XML 사투리
JunIt Format XML이라는 표현이 있지만 여러 사투리가 있는 것 같습니다.
그리고 split-test에 있어서 가장 중요한 테스트 파일 이름의 정보는 사실 사투리와 같다. 어디가 공식 정보인지 모르겠지만 위에 나타난 IBM Knowledge Center의 정의에는 없다.
업무상 사용하는 것이 기본적으로 루비이기 때문에 나는 그들에게 Rspec과 Minitest를 먹게 하려고 시도했지만 이 두 가지만 다음과 같다.
rspec_junit_formatter:
<testsuite>
<testcase file="foo_spec.rb">
<testcase>
</testsuite>
minitest-reporters:<testsuites>
<testsuite filepath="foo_spec.rb">
<testcase>
<testcase>
</testsuite>
</testsuites>
Coverage 정보 등을 고려할 때 사용하기 쉬운 일관된 서식이 필요할 수 있습니다.
Reference
이 문제에 관하여(GiitHub Actions에서 동시에 테스트 및 고속화(parallelism)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/mtsmfm/articles/49dfc631f75ccc텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)