Dev-ops

πŸš€ Testing Library 계열 μ›Œν¬ν”Œλ‘œμš° μ™„μ „ 정볡

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

πŸš€ Testing Library 계열 μ›Œν¬ν”Œλ‘œμš° μ™„μ „ 정볡

 

Testing Libraryλ₯Ό ν™œμš©ν•œ CI/CD μ΅œμ ν™” 방법, μ½”λ“œ ν’ˆμ§ˆ 보μž₯ μ „λž΅, 그리고 Codecov μ—°λ™κΉŒμ§€!

πŸ› οΈ CI μ‹œκ°„ 단좕 | 린트 & νƒ€μž… 체크 μžλ™ν™” | μœ λ‹› ν…ŒμŠ€νŠΈ 검증 | 크둜슀 ν”Œλž«νΌ ν…ŒμŠ€νŠΈ

πŸ“Œ Testing Library 계열 μ›Œν¬ν”Œλ‘œμš°λž€?

 

Testing LibraryλŠ” DOM ν…ŒμŠ€νŠΈλ₯Ό μ€‘μ‹¬μœΌλ‘œ ν•œ JavaScript ν…ŒμŠ€νŠΈ ν”„λ ˆμž„μ›Œν¬μ˜ˆμš”.

βœ… UI μ»΄ν¬λ„ŒνŠΈλ₯Ό 마치 μ‚¬μš©μžκ°€ μ‘°μž‘ν•˜λŠ” κ²ƒμ²˜λŸΌ ν…ŒμŠ€νŠΈ

βœ… Jest, React Testing Library, DOM Testing Library λ“±μ˜ 도ꡬ와 ν•¨κ»˜ μ‚¬μš©

βœ… λ Œλ”λ§λœ μš”μ†Œλ₯Ό 직접 κ²€μ¦ν•˜μ—¬ μ½”λ“œμ˜ 신뒰도λ₯Ό λ†’μ΄λŠ” 데 ν™œμš©

 

CI/CD ν™˜κ²½μ—μ„œλŠ” 이걸 ν™œμš©ν•΄μ„œ

βœ”οΈ μžλ™μœΌλ‘œ μ½”λ“œ ν’ˆμ§ˆμ„ κ²€μ¦ν•˜κ³ 

βœ”οΈ λ‹€μ–‘ν•œ ν”Œλž«νΌμ—μ„œ UIκ°€ 정상 μž‘λ™ν•˜λŠ”μ§€ 확인할 수 μžˆμ–΄μš”.

 

μ˜€λŠ˜μ€ Testing Library κ³„μ—΄μ˜ CI/CD μžλ™ν™” μ΅œμ ν™”μ™€ ν•¨κ»˜

βœ… 린트 & νƒ€μž… 체크

βœ… μœ λ‹› ν…ŒμŠ€νŠΈ μžλ™ν™”

βœ… 크둜슀 ν”Œλž«νΌ 검증

βœ… Codecov μ—°λ™μœΌλ‘œ 컀버리지 μΈ‘μ •

κΉŒμ§€ ν•œλ°©μ— ν•΄κ²°ν•΄λ³Όκ²Œμš”! πŸš€

πŸ”Ή Testing Library κ³„μ—΄μ˜ μ›Œν¬ν”Œλ‘œμš° μ΅œμ ν™”

 

1️⃣ CI μ‹œκ°„ 단좕: λ¦¬μ†ŒμŠ€ μ΅œμ ν™” πŸš€

 

CI/CDμ—μ„œ ν…ŒμŠ€νŠΈ 속도λ₯Ό λ†’μ΄λŠ” 건 μ•„μ£Ό μ€‘μš”ν•΄μš”.

ν…ŒμŠ€νŠΈκ°€ 였래 걸리면 개발 속도가 λ–¨μ–΄μ§€κ³ , λ°°ν¬κΉŒμ§€ μ§€μ—°λ˜λ‹ˆκΉŒμš”.

 

πŸ‘‰ CI μ‹œκ°„μ„ μ€„μ΄λŠ” 핡심 μ „λž΅!

βœ”οΈ μΊμ‹œ ν™œμš© (cache: npm)

βœ”οΈ 병렬 μ‹€ν–‰ (matrix μ„€μ •)

βœ”οΈ ν•„μš”ν•  λ•Œλ§Œ μ‹€ν–‰ (filtering by branch)

 

βœ”οΈ 예제: μΊμ‹œ & 병렬 μ‹€ν–‰μœΌλ‘œ CI 속도 μ΅œμ ν™”

name: CI Optimization with Testing Library

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

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [16, 18]  # 닀쀑 Node.js 버전 병렬 μ‹€ν–‰
    steps:
      - name: Checkout repository
        uses: actions/checkout@v3

      - name: Cache dependencies  # μΊμ‹œ ν™œμš©μœΌλ‘œ npm install 속도 ν–₯상
        uses: actions/cache@v3
        with:
          path: ~/.npm
          key: npm-${{ runner.os }}-${{ hashFiles('**/package-lock.json') }}
          restore-keys: npm-${{ runner.os }}-

      - name: Set up Node.js
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}

      - name: Install dependencies
        run: npm ci

      - name: Run Lint
        run: npm run lint

      - name: Run TypeScript Check
        run: npm run type-check

      - name: Run Tests
        run: npm test -- --coverage

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

βœ… cacheλ₯Ό ν™œμš©ν•΄μ„œ npm install 속도λ₯Ό 단좕

βœ… μ—¬λŸ¬ Node.js λ²„μ „μ—μ„œ ν…ŒμŠ€νŠΈ 병렬 μ‹€ν–‰ (16 & 18)

βœ… ν…ŒμŠ€νŠΈλ§Œ μ‹€ν–‰ν•˜λŠ” 게 μ•„λ‹ˆλΌ, 린트 & νƒ€μž…μ²΄ν¬λ„ 포함!

2️⃣ μ½”λ“œ ν’ˆμ§ˆ 보μž₯: 린트 & νƒ€μž… 체크 & μœ λ‹› ν…ŒμŠ€νŠΈ μžλ™ν™”

 

CI/CDμ—μ„œ μ½”λ“œ ν’ˆμ§ˆμ„ μœ μ§€ν•˜λ €λ©΄ μžλ™ 검증 ν”„λ‘œμ„ΈμŠ€κ°€ ν•„μš”ν•΄μš”.

βœ… ESLint → μ½”λ“œ μŠ€νƒ€μΌ & 버그 탐지

βœ… TypeScript 체크 → νƒ€μž… μ•ˆμ „μ„± 보μž₯

βœ… Jest & React Testing Library → μ»΄ν¬λ„ŒνŠΈ λ‹¨μœ„ ν…ŒμŠ€νŠΈ

 

βœ”οΈ νŒ¨ν‚€μ§€ μ„€μΉ˜

npm install --save-dev eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin
npm install --save-dev jest @testing-library/react @testing-library/jest-dom

βœ”οΈ ESLint μ„€μ • (.eslintrc.js)

module.exports = {
  parser: "@typescript-eslint/parser",
  extends: ["plugin:@typescript-eslint/recommended", "plugin:react/recommended"],
  rules: {
    "react/prop-types": "off"
  }
};

βœ”οΈ TypeScript μ„€μ • (tsconfig.json)

{
  "compilerOptions": {
    "strict": true,
    "noImplicitAny": true
  }
}

βœ”οΈ μœ λ‹› ν…ŒμŠ€νŠΈ 예제

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

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

πŸ‘† μœ„μ™€ 같은 μœ λ‹› ν…ŒμŠ€νŠΈλ₯Ό CIμ—μ„œ μžλ™μœΌλ‘œ μ‹€ν–‰ν•˜λ„λ‘ μ„€μ •ν•˜λ©΄,

❌ 버그가 μžˆλŠ” μ½”λ“œκ°€ main 브랜치둜 λ¨Έμ§€λ˜λŠ” κ±Έ 막을 수 μžˆμ–΄μš”! πŸš€

3️⃣ 크둜슀 ν”Œλž«νΌ 검증

 

ν…ŒμŠ€νŠΈκ°€ λ‘œμ»¬μ—μ„œλŠ” λ˜λŠ”λ° λ°°ν¬ν•˜λ©΄ κΉ¨μ§€λŠ” κ²½μš°κ°€ 많죠?

πŸ› οΈ λ‹€μ–‘ν•œ OS & λΈŒλΌμš°μ €μ—μ„œ ν…ŒμŠ€νŠΈλ₯Ό μ‹€ν–‰ν•΄μ•Ό ν•΄μš”!

 

βœ”οΈ λ‹€μ–‘ν•œ OSμ—μ„œ μ‹€ν–‰ν•˜κΈ°

strategy:
  matrix:
    os: [ubuntu-latest, windows-latest, macos-latest]

runs-on: ${{ matrix.os }}

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

βœ… λ¦¬λˆ…μŠ€, μœˆλ„μš°, λ§₯μ—μ„œ λ™μ‹œμ— ν…ŒμŠ€νŠΈ μ‹€ν–‰

βœ… OS에 따라 λ‹€λ₯΄κ²Œ λ™μž‘ν•˜λŠ” μ½”λ“œλ„ 검증 κ°€λŠ₯

4️⃣ Codecov μ—°λ™μœΌλ‘œ 컀버리지 μΈ‘μ •

 

ν…ŒμŠ€νŠΈλ₯Ό μ‹€ν–‰ν•  λ•Œ μ½”λ“œ 컀버리지λ₯Ό μžλ™μœΌλ‘œ μΈ‘μ •ν•˜λ©΄

πŸ“Œ ν…ŒμŠ€νŠΈκ°€ μ–Όλ§ˆλ‚˜ 잘 μ»€λ²„λ˜κ³  μžˆλŠ”μ§€ λ°”λ‘œ 확인할 수 μžˆμ–΄μš”!

 

βœ”οΈ Codecov μ„€μΉ˜

npm install --save-dev codecov

βœ”οΈ CI/CD에 Codecov μΆ”κ°€

- name: Upload coverage to Codecov
  uses: codecov/codecov-action@v3

βœ”οΈ Jest μ„€μ • (jest.config.js)

module.exports = {
  collectCoverage: true,
  coverageDirectory: "coverage",
  coverageReporters: ["json", "lcov", "text-summary"]
};

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

βœ… ν…ŒμŠ€νŠΈ μ‹€ν–‰ ν›„ Codecovμ—μ„œ 컀버리지 리포트 μžλ™ 생성!

βœ… λΆ€μ‘±ν•œ ν…ŒμŠ€νŠΈ μ˜μ—­μ„ λ°”λ‘œ νŒŒμ•… κ°€λŠ₯ πŸ”

🎯 κ²°λ‘ : Testing Library 계열 μ›Œν¬ν”Œλ‘œμš° μ΅œμ ν™”!

 

βœ”οΈ CI/CD μ‹œκ°„μ„ λ‹¨μΆ•ν•˜λ €λ©΄?

➑️ cache, matrix, 병렬 μ‹€ν–‰ ν™œμš©

 

βœ”οΈ μ½”λ“œ ν’ˆμ§ˆμ„ μœ μ§€ν•˜λ €λ©΄?

➑️ ESLint, TypeScript, Jest μžλ™ν™”

 

βœ”οΈ 운영 ν™˜κ²½μ—μ„œ κΉ¨μ§€λŠ” κ±Έ λ°©μ§€ν•˜λ €λ©΄?

➑️ λ‹€μ–‘ν•œ OS & Node.js λ²„μ „μ—μ„œ μ‹€ν–‰

 

βœ”οΈ ν…ŒμŠ€νŠΈ 컀버리지λ₯Ό μΈ‘μ •ν•˜λ €λ©΄?

➑️ Codecov μ—°λ™μœΌλ‘œ λΆ€μ‘±ν•œ ν…ŒμŠ€νŠΈ μ˜μ—­ νŒŒμ•…

 

πŸ’‘ 이제 Testing Libraryλ₯Ό ν™œμš©ν•œ CI/CD μžλ™ν™”λ₯Ό λ§ˆμŠ€ν„°ν•˜κ³ ,

νƒ„νƒ„ν•œ ν”„λ‘ νŠΈμ—”λ“œ ν…ŒμŠ€νŠΈ ν™˜κ²½μ„ κ΅¬μΆ•ν•΄λ³΄μž! πŸš€

 

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

728x90
λ°˜μ‘ν˜•