Dev-ops

πŸš€ CI/CDμ—μ„œ React Testing Library μ›Œν¬ν”Œλ‘œμš° μ‚΄νŽ΄λ³΄κΈ°

xeunnie 2025. 3. 17. 01:00
728x90
λ°˜μ‘ν˜•

πŸš€ CI/CDμ—μ„œ React Testing Library μ›Œν¬ν”Œλ‘œμš° μ‚΄νŽ΄λ³΄κΈ°

 

ν…ŒμŠ€νŠΈ μžλ™ν™”λ₯Ό μ μš©ν•œ CI/CD νŒŒμ΄ν”„λΌμΈμ΄ μ–΄λ–»κ²Œ λŒμ•„κ°€λŠ”μ§€, React Testing Libraryμ—μ„œ 이λ₯Ό μ–΄λ–»κ²Œ ν™œμš©ν•˜λŠ”μ§€ μ œλŒ€λ‘œ νŒŒν—€μ³λ³΄μž! 🎯

πŸ“Œ CI/CDμ—μ„œ μ›Œν¬ν”Œλ‘œμš°λž€?

 

CI/CDμ—μ„œ μ›Œν¬ν”Œλ‘œμš°(Workflow) λŠ” ν…ŒμŠ€νŠΈ, λΉŒλ“œ, 배포 λ“± μžλ™ν™”λœ μž‘μ—…μ˜ 흐름을 μ˜λ―Έν•΄μš”.

βœ”οΈ CI(Continuous Integration, 지속적 톡합): μ½”λ“œ λ³€κ²½ μ‹œ μžλ™μœΌλ‘œ ν…ŒμŠ€νŠΈ 및 λΉŒλ“œλ₯Ό μˆ˜ν–‰

βœ”οΈ CD(Continuous Delivery/Deployment, 지속적 배포): CI 단계λ₯Ό ν†΅κ³Όν•œ μ½”λ“œλ₯Ό 운영 ν™˜κ²½μ— 배포

 

즉, μ›Œν¬ν”Œλ‘œμš°λ₯Ό μ„€μ •ν•˜λ©΄, μ½”λ“œκ°€ 변경될 λ•Œλ§ˆλ‹€ μžλ™μœΌλ‘œ ν…ŒμŠ€νŠΈλ₯Ό μ‹€ν–‰ν•˜κ³ , λ¬Έμ œκ°€ μ—†λ‹€λ©΄ λ°°ν¬κΉŒμ§€ μ§„ν–‰ν•˜λŠ” 과정이 μžλ™ν™”λ˜λŠ” κ±°μ˜ˆμš”! πŸŽ‰

🌱 CI/CDμ—μ„œ μ›Œν¬ν”Œλ‘œμš°μ˜ κΈ°λ³Έ ꡬ쑰

 

μ›Œν¬ν”Œλ‘œμš°λ₯Ό μ„€μ •ν•˜λŠ” κ°€μž₯ λŒ€ν‘œμ μΈ λ„κ΅¬λŠ” GitHub Actionsμ—μš”.

GitHub Actionsμ—μ„œ CI/CD νŒŒμ΄ν”„λΌμΈμ„ μ„€μ •ν•˜λ €λ©΄ .github/workflows/ci.yml 같은 YAML νŒŒμΌμ„ μž‘μ„±ν•˜λ©΄ λΌμš”.

 

βœ”οΈ μ›Œν¬ν”Œλ‘œμš°μ˜ κΈ°λ³Έ ꡬ쑰

name: React CI

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v3

      - name: Set up Node.js
        uses: actions/setup-node@v3
        with:
          node-version: 18

      - name: Install dependencies
        run: npm install

      - name: Run tests
        run: npm test

μœ„ μ½”λ“œλ₯Ό 보면 ν…ŒμŠ€νŠΈ μžλ™ν™”λ₯Ό μœ„ν•œ CI μ›Œν¬ν”Œλ‘œμš°κ°€ μ„€μ •λ˜μ–΄ μžˆμ–΄μš”.

ν•˜λ‚˜μ”© λœ―μ–΄λ³΄λ©΄μ„œ μ΄ν•΄ν•΄λ³ΌκΉŒμš”? πŸ”Ž

πŸ“Œ μ£Όμš” ꡬ성 μš”μ†Œμ™€ 문법 μ‚΄νŽ΄λ³΄κΈ°

 

πŸ”Ή on: - μ–Έμ œ 싀행될 것인가?

 

μ›Œν¬ν”Œλ‘œμš°κ°€ 트리거(trigger) λ˜λŠ” 쑰건을 μ„€μ •ν•΄μš”.

βœ”οΈ push: → νŠΉμ • λΈŒλžœμΉ˜μ— μ½”λ“œκ°€ ν‘Έμ‹œλ  λ•Œ μ‹€ν–‰

βœ”οΈ pull_request: → PR이 생성될 λ•Œ μ‹€ν–‰

βœ”οΈ schedule: → νŠΉμ • μ‹œκ°„λ§ˆλ‹€ μ‹€ν–‰

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main
  schedule:
    - cron: "0 0 * * *" # 맀일 μžμ • μ‹€ν–‰

πŸ”Ή jobs: - μ–΄λ–€ μž‘μ—…μ„ μˆ˜ν–‰ν•  것인가?

 

jobs:λŠ” μ›Œν¬ν”Œλ‘œμš°μ—μ„œ μ‹€ν–‰ν•  μ—¬λŸ¬ 개의 μž‘μ—…μ„ μ •μ˜ν•˜λŠ” λΆ€λΆ„μ΄μ—μš”.

μ—¬λŸ¬ 개의 job을 λ³‘λ ¬λ‘œ μ‹€ν–‰ν•˜κ±°λ‚˜, 순차적으둜 μ‹€ν–‰ν•  μˆ˜λ„ μžˆμ–΄μš”.

jobs:
  test:   # "test"λΌλŠ” μž‘μ—…μ„ μ •μ˜
    runs-on: ubuntu-latest  # μ‹€ν–‰ν•  ν™˜κ²½ (OS)
    steps: 
      - name: Checkout repository  # GitHub μ €μž₯μ†Œ μ½”λ“œλ₯Ό κ°€μ Έμ˜€κΈ°
      - name: Set up Node.js        # Node.js μ„€μ •
      - name: Install dependencies  # μ˜μ‘΄μ„± μ„€μΉ˜
      - name: Run tests             # ν…ŒμŠ€νŠΈ μ‹€ν–‰

πŸ”Ή steps: - Job λ‚΄λΆ€μ—μ„œ 싀행될 단계

 

각 job μ•ˆμ—λŠ” μ—¬λŸ¬ 개의 stepsκ°€ λ“€μ–΄κ°€μš”.

βœ”οΈ name: → 각 λ‹¨κ³„μ˜ 이름을 μ •μ˜

βœ”οΈ run: → μ‹€ν–‰ν•  λͺ…λ Ήμ–΄

βœ”οΈ uses: → GitHub Actionsμ—μ„œ μ œκ³΅ν•˜λŠ” ν”ŒλŸ¬κ·ΈμΈ ν™œμš©

steps:
  - name: Checkout repository
    uses: actions/checkout@v3

  - name: Set up Node.js
    uses: actions/setup-node@v3
    with:
      node-version: 18

  - name: Install dependencies
    run: npm install

  - name: Run tests
    run: npm test

πŸ‘† μœ„ μ˜ˆμ œμ—μ„œλŠ” npm install둜 νŒ¨ν‚€μ§€λ₯Ό μ„€μΉ˜ν•˜κ³ , npm test둜 React Testing Library ν…ŒμŠ€νŠΈλ₯Ό μ‹€ν–‰ν•΄μš”.

πŸ”Ή runs-on: - μ–΄λ””μ„œ μ‹€ν–‰ν•  것인가?

 

ν…ŒμŠ€νŠΈλ₯Ό μ‹€ν–‰ν•  ν™˜κ²½(운영체제, OS) 을 μ„ νƒν•˜λŠ” λΆ€λΆ„μ΄μ—μš”.

runs-on: ubuntu-latest  # μ΅œμ‹  Ubuntu ν™˜κ²½μ—μ„œ μ‹€ν–‰

ubuntu-latest: μ΅œμ‹  μš°λΆ„νˆ¬ λ²„μ „μ—μ„œ μ‹€ν–‰

windows-latest: μ΅œμ‹  μœˆλ„μš° ν™˜κ²½μ—μ„œ μ‹€ν–‰

macos-latest: μ΅œμ‹  λ§₯OSμ—μ„œ μ‹€ν–‰

πŸ”Ή release: - λ°°ν¬κΉŒμ§€ μžλ™ν™”ν•  경우

 

λ§Œμ•½ CI/CDμ—μ„œ ν…ŒμŠ€νŠΈλ₯Ό ν†΅κ³Όν•œ μ½”λ“œκ°€ μžλ™ λ°°ν¬λ˜λ„λ‘ ν•˜λ €λ©΄, release 단계λ₯Ό μΆ”κ°€ν•  수 μžˆμ–΄μš”.

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Deploy application
        run: npm run deploy

πŸ“Œ μ΄λ ‡κ²Œ ν•˜λ©΄?

βœ… main λΈŒλžœμΉ˜μ— μ½”λ“œκ°€ 머지될 λ•Œ μžλ™μœΌλ‘œ ν…ŒμŠ€νŠΈ μ‹€ν–‰

βœ… ν…ŒμŠ€νŠΈκ°€ ν†΅κ³Όλ˜λ©΄ npm run deploy λͺ…λ Ήμ–΄λ‘œ 배포 μžλ™ν™”! πŸš€

πŸ“Œ React Testing Library μ›Œν¬ν”Œλ‘œμš° μ μš©ν•˜κΈ° 🎯

 

이제 CI/CDμ—μ„œ React Testing Libraryλ₯Ό ν™œμš©ν•˜μ—¬ ν…ŒμŠ€νŠΈ μ‹€ν–‰ν•˜λŠ” 방법을 μ‚΄νŽ΄λ³΄μž!

 

1️⃣ React Testing Library μ„€μ •

 

ν”„λ‘œμ νŠΈμ— React Testing Libraryλ₯Ό μ„€μΉ˜ν•΄μ•Ό ν•΄μš”.

npm install --save-dev @testing-library/react @testing-library/jest-dom jest

2️⃣ ν…ŒμŠ€νŠΈ μ½”λ“œ μž‘μ„± (예제)

 

μ•„λž˜λŠ” React Testing Library둜 μž‘μ„±λœ κ°„λ‹¨ν•œ ν…ŒμŠ€νŠΈ μ˜ˆμ œμ˜ˆμš”.

import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import App from "./App";

test("λ²„νŠΌ 클릭 μ‹œ ν…μŠ€νŠΈ λ³€κ²½", async () => {
  render(<App />);
  
  const button = screen.getByRole("button", { name: "ν΄λ¦­ν•˜μ„Έμš”" });
  userEvent.click(button);
  
  expect(screen.getByText("클릭됨!")).toBeInTheDocument();
});

πŸ‘† userEvent.click(button)으둜 클릭 이벀트λ₯Ό λ°œμƒμ‹œν‚€κ³ , 화면이 μ—…λ°μ΄νŠΈλ˜μ—ˆλŠ”μ§€ ν™•μΈν•˜λŠ” ν…ŒμŠ€νŠΈμ—μš”.

3️⃣ CI/CDμ—μ„œ React Testing Library μ‹€ν–‰ν•˜κΈ°

 

이제 CI/CDμ—μ„œ ν…ŒμŠ€νŠΈκ°€ μžλ™ μ‹€ν–‰λ˜λ„λ‘ μ„€μ •ν•΄λ³Όκ²Œμš”.

name: React CI with Testing Library

on:
  pull_request:
    branches:
      - main

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v3

      - name: Set up Node.js
        uses: actions/setup-node@v3
        with:
          node-version: 18

      - name: Install dependencies
        run: npm install

      - name: Run React Testing Library tests
        run: npm test -- --coverage

βœ… CI/CD μ‹€ν–‰ μ‹œ μžλ™μœΌλ‘œ npm test -- --coverageλ₯Ό μ‹€ν–‰ν•˜μ—¬ ν…ŒμŠ€νŠΈ μ½”λ“œ μ»€λ²„λ¦¬μ§€κΉŒμ§€ μΈ‘μ •ν•  수 μžˆμ–΄μš”.

πŸ“Œ 였λ₯˜ λ°œμƒ μ‹œ μ–΄λ–»κ²Œ ν•΄κ²°ν• κΉŒ?

 

CI/CDμ—μ„œ ν…ŒμŠ€νŠΈκ°€ μ‹€νŒ¨ν•˜λ©΄ GitHub Actions 둜그λ₯Ό 확인해야 ν•΄μš”.

 

1️⃣ ν„°λ―Έλ„μ—μ„œ 둜그 확인

 

ν…ŒμŠ€νŠΈκ°€ μ‹€νŒ¨ν•˜λ©΄ GitHub Actions의 Actions νƒ­μ—μ„œ 둜그λ₯Ό 확인할 수 μžˆμ–΄μš”.

FAIL  src/App.test.js
  ● λ²„νŠΌ 클릭 μ‹œ ν…μŠ€νŠΈ λ³€κ²½

    Unable to find an element with the text: 클릭됨!

➑️ ν•΄κ²° 방법:

βœ… screen.debug()λ₯Ό μΆ”κ°€ν•΄μ„œ ν˜„μž¬ μƒνƒœ 확인

βœ… waitFor()λ₯Ό μ‚¬μš©ν•˜μ—¬ 비동기 ν…ŒμŠ€νŠΈ 처리

import { waitFor } from "@testing-library/react";

await waitFor(() => expect(screen.getByText("클릭됨!")).toBeInTheDocument());

🎯 κ²°λ‘ : CI/CDμ—μ„œ React Testing Library μžλ™ν™”ν•˜κΈ°!

 

βœ”οΈ μ›Œν¬ν”Œλ‘œμš°λŠ” CI/CDμ—μ„œ μžλ™ν™”λœ μž‘μ—…μ˜ 흐름을 의미

βœ”οΈ GitHub Actions둜 CI/CD μ„€μ •ν•˜κ³ , pushλ‚˜ PR이 λ°œμƒν•˜λ©΄ μžλ™μœΌλ‘œ μ‹€ν–‰

βœ”οΈ on:, jobs:, steps:, runs-on: 같은 μš”μ†Œλ‘œ ꡬ성

βœ”οΈ React Testing Libraryλ₯Ό ν™œμš©ν•œ ν…ŒμŠ€νŠΈ μžλ™ν™” κ°€λŠ₯

βœ”οΈ ν…ŒμŠ€νŠΈκ°€ μ‹€νŒ¨ν•˜λ©΄ GitHub Actions λ‘œκ·Έμ—μ„œ 문제 확인 κ°€λŠ₯

 

이제 ν…ŒμŠ€νŠΈ μžλ™ν™”λ‘œ 버그 μ—†λŠ” ν”„λ‘ νŠΈμ—”λ“œλ₯Ό λ§Œλ“€μ–΄ 보자! πŸš€

 

🌷 μ „μ„€μ˜ κ°œλ°œμžκ°€ λ˜μ–΄λ΄…μ‹œλ‹Ή! 🌷

728x90
λ°˜μ‘ν˜•