포스트

[GitHub 100일 챌린지] Day 88 - Matrix 전략으로 병렬 테스트

[GitHub 100일 챌린지] Day 88 - Matrix 전략으로 병렬 테스트

100일 챌린지 Day 88 - Matrix 전략으로 여러 환경을 동시에 테스트합니다.

배울 내용

  1. Matrix 전략 개념
  2. 고급 Matrix 설정
  3. 병렬 실행 최적화

Matrix 전략이란?

개념

하나의 Job을 여러 조합으로 실행

1
2
3
4
strategy:
  matrix:
    os: [ubuntu-latest, windows-latest, macos-latest]
    node-version: [16, 18, 20]

결과: 9개 Job 실행 (3 OS × 3 Node 버전)

1
2
3
4
5
6
7
8
9
✅ Ubuntu + Node 16
✅ Ubuntu + Node 18
✅ Ubuntu + Node 20
✅ Windows + Node 16
✅ Windows + Node 18
✅ Windows + Node 20
✅ macOS + Node 16
✅ macOS + Node 18
✅ macOS + Node 20

기본 Matrix 사용

단일 차원

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [16, 18, 20]
    
    steps:
      - uses: actions/checkout@v4
      
      - uses: actions/setup-node@v4
        with:
          node-version: $
      
      - run: npm test

다중 차원

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
jobs:
  test:
    runs-on: $
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest]
        node-version: [18, 20]
        # 2 × 2 = 4개 Job
    
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: $
      - run: npm test

고급 Matrix 설정

include로 조합 추가

1
2
3
4
5
6
7
8
9
10
11
12
13
strategy:
  matrix:
    os: [ubuntu-latest, windows-latest]
    node-version: [18, 20]
    include:
      # 추가 조합
      - os: macos-latest
        node-version: 20
      
      # 특정 조합에 변수 추가
      - os: ubuntu-latest
        node-version: 20
        experimental: true

exclude로 조합 제외

1
2
3
4
5
6
7
8
9
10
11
12
strategy:
  matrix:
    os: [ubuntu-latest, windows-latest, macos-latest]
    node-version: [16, 18, 20]
    exclude:
      # Windows + Node 16 제외
      - os: windows-latest
        node-version: 16
      
      # macOS + Node 16 제외
      - os: macos-latest
        node-version: 16

결과: 9개 - 2개 = 7개 Job


실패 처리 전략

fail-fast (기본: true)

1
2
3
4
strategy:
  fail-fast: true  # 하나 실패 시 모두 취소
  matrix:
    os: [ubuntu-latest, windows-latest, macos-latest]
1
2
3
4
strategy:
  fail-fast: false  # 실패해도 나머지 계속 실행
  matrix:
    os: [ubuntu-latest, windows-latest, macos-latest]

continue-on-error

1
2
3
4
5
6
7
8
9
10
11
12
13
jobs:
  test:
    runs-on: $
    continue-on-error: $
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest]
        node-version: [18, 20]
        experimental: [false]
        include:
          - os: ubuntu-latest
            node-version: 21
            experimental: true  # 실패해도 Workflow는 성공

Matrix 변수 활용

커스텀 변수

1
2
3
4
5
6
7
8
9
10
11
12
13
14
strategy:
  matrix:
    config:
      - { os: ubuntu-latest, node: 18, name: 'Ubuntu LTS' }
      - { os: windows-latest, node: 20, name: 'Windows Latest' }
      - { os: macos-latest, node: 20, name: 'macOS Latest' }

steps:
  - name: 테스트 ($)
    run: echo "Running on $"
  
  - uses: actions/setup-node@v4
    with:
      node-version: $

조건부 Step

1
2
3
4
5
6
7
8
9
10
11
12
steps:
  - name: Windows 전용 설정
    if: matrix.os == 'windows-latest'
    run: choco install something
  
  - name: Linux 전용 설정
    if: matrix.os == 'ubuntu-latest'
    run: sudo apt-get install something
  
  - name: macOS 전용 설정
    if: matrix.os == 'macos-latest'
    run: brew install something

병렬 실행 제어

max-parallel

1
2
3
4
5
strategy:
  max-parallel: 2  # 동시 실행 최대 2개
  matrix:
    os: [ubuntu-latest, windows-latest, macos-latest]
    node-version: [16, 18, 20]

효과:

1
2
3
기본: 9개 Job 동시 실행
max-parallel: 2
→ 2개씩 실행 (총 5번에 걸쳐 완료)

실전 예제

크로스 플랫폼 테스트

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
name: Cross-Platform Test

on: [push, pull_request]

jobs:
  test:
    name: Test on ${{ matrix.os }} with Node ${{ matrix.node }}
    runs-on: ${{ matrix.os }}

    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
        node: [18, 20]
        include:
          # 최신 Node.js도 테스트 (실패 허용)
          - os: ubuntu-latest
            node: 21
            experimental: true
        exclude:
          # Windows + Node 18 제외 (알려진 이슈)
          - os: windows-latest
            node: 18

    continue-on-error: ${{ matrix.experimental || false }}

    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js ${{ matrix.node }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node }}
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Run linter
        run: npm run lint

      - name: Run tests
        run: npm test

      - name: Upload coverage
        if: matrix.os == 'ubuntu-latest' && matrix.node == 20
        uses: codecov/codecov-action@v3

브라우저 테스트

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
jobs:
  e2e:
    runs-on: ubuntu-latest
    
    strategy:
      matrix:
        browser: [chrome, firefox, edge]
        viewport: [desktop, mobile]
    
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup
        run: npm ci
      
      - name: E2E Test
        run: |
          npm run test:e2e -- \
            --browser=$ \
            --viewport=$
      
      - name: Upload screenshots
        if: failure()
        uses: actions/upload-artifact@v3
        with:
          name: screenshots-$-$
          path: screenshots/

데이터베이스 테스트

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
jobs:
  test:
    runs-on: ubuntu-latest
    
    strategy:
      matrix:
        database:
          - { type: postgres, version: '14' }
          - { type: postgres, version: '15' }
          - { type: mysql, version: '8.0' }
          - { type: mariadb, version: '10.11' }
    
    services:
      database:
        image: $:$
        env:
          POSTGRES_PASSWORD: test
          MYSQL_ROOT_PASSWORD: test
        options: >-
          --health-cmd "pg_isready || mysqladmin ping"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
    
    steps:
      - uses: actions/checkout@v4
      
      - name: Run tests
        env:
          DATABASE_URL: $://root:test@localhost:5432/test
        run: npm test

Matrix JSON 동적 생성

외부 파일에서 읽기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
jobs:
  setup:
    runs-on: ubuntu-latest
    outputs:
      matrix: ${{ steps.set-matrix.outputs.matrix }}
    steps:
      - uses: actions/checkout@v4

      - id: set-matrix
        run: |
          # JSON 파일에서 Matrix 읽기
          echo "matrix=$(cat .github/test-matrix.json)" >> $GITHUB_OUTPUT

  test:
    needs: setup
    runs-on: ${{ matrix.os }}
    strategy:
      matrix: ${{ fromJson(needs.setup.outputs.matrix) }}
    steps:
      - run: npm test

.github/test-matrix.json:

1
2
3
4
{
  "os": ["ubuntu-latest", "windows-latest"],
  "node": [18, 20]
}

정리

완료 체크:

  • Matrix 전략 이해
  • include/exclude 활용
  • 병렬 실행 최적화

핵심 요약:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Matrix 기본:
- strategy.matrix 정의
- 여러 조합 자동 테스트
- 병렬 실행

고급 기능:
- include: 조합 추가
- exclude: 조합 제외
- fail-fast: 실패 처리
- max-parallel: 동시 실행 수 제한

활용:
- 크로스 플랫폼 테스트
- 여러 버전 테스트
- 브라우저/DB 테스트

다음: Day 89 - 재사용 가능한 Workflows →


← Day 88 | 전체 커리큘럼 | Day 89 →

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.