jtwjs Dev Wiki
  • DEV_ROAD
    • 💪🏻 생존하기
    • Week 1
      • 개발 환경 세팅
      • 타입스크립트
      • 리엑트
      • Testing Library
      • Parcel & ESLint
    • Week 2
      • JSX
      • Virtual DOM
    • Week 3
      • React Component
      • React State
    • Week 4
      • Express
      • Fetch API & CORS
      • React Hook
      • useRef & Custom Hook
    • Week 5
      • TDD
      • React Testing Library
      • MSW
      • Playwrite
      • Snapshot
    • Week 6
      • Separtion of Concerns
      • Principle
      • DI, (Dependency Injection)
      • Reflect-metadata
      • TSyringe
      • External Store
      • Follow Redux
      • usestore-ts
      • useSyncExternalStore
    • Week 7
      • Routing
      • Routes
      • Router
      • Navigation
    • Week 8
      • Design System
      • Style Basics
      • CSS-in-JS
      • Styled-Components
      • Global Style & Theme
    • Week 9
      • 개발하기 전 준비
      • 상품 목록 페이지
      • 상품 상세 페이지
      • 장바구니 페이지
    • Week 10
      • 로그인
      • 로그아웃
      • 회원가입
      • 주문 목록 & 주문 상세
    • Week 11
      • 배송 정보 입력
      • 포트원 결제 요청
      • 배송 및 결제 정보 전달
    • Week 12
      • 관리자 웹사이트개발시작
  • DEV_NOTE
    • TypeScript
      • 기본적 문법
        • Enum
        • 다형성
          • Untitled
        • 구조적 타이핑
        • 제너릭 타입
        • 컨디셔널 타입
        • 함수 메서드 타이핑
        • infer로 타입스크립트의 추론 직접 활용
        • 재귀 타입
        • 템플릿 리터럴 타입
        • 추가적인 타입 검사 satisfies 연산자
        • 타입스크립트 건망증
        • 원시 자료형에도 브랜딩 기법 사용 가능
        • 타입 좁히기
        • 유용한 타입 만들기
        • 데코레이터 함수
        • 앰비언트 선언도 선언 병합이 된다.
        • 앰비언트 선언도 선언병합이 된다.
    • Testing
      • Unit Testing
      • 단위 테스트의 두 분파
      • 좋은 단위 테스트를 구성하는 4대 요소
      • 테스트 대역과 식별할 수 있는 동작
      • 단위 테스트 스타일
      • 가치 있는 단위 테스트를 위한 리팩토링
      • 통합 테스트
      • Cross Browsing Testing
      • 기능 테스트 종류
      • React Testing Pattern
      • 프론트엔드 테스트 입문
        • 테스트 범위
        • 단위 테스트 검증
        • Mock
        • UI 컴포넌트 테스트
        • 테스트 커버리지
        • 웹 통합 테스트
        • MSW
        • 스토리북
        • 시각적 회귀 테스트
        • E2E 테스트
        • Github Actions 설정
        • 깃허브 액션에서 E2E
      • 시프트 레프트
        • 테스트 기본중의 기본
        • 단위 테스트
        • 코드 복잡도
        • 리팩터링
        • 코드 리뷰
        • 통합 테스트 패턴
        • 시스템 테스트의 자동화
        • 탐색적 테스트
      • Test Tip
      • vitest
      • playwright
      • Test Data Generator
      • MSW
    • Algorithm
      • coding test
      • Data Structure
    • Next.js
      • Data Fetching
      • Hydration
      • Next 13
      • Optimization
      • Next 15
    • Tailwind
      • Tailwind CSS
      • Theme
      • Directives
      • Tool
      • Design System
    • Storybook
      • Storybook
      • CSF3
      • CDD
      • Headless Component
    • Funtional Programming
      • 함수형 프로그래밍
      • 참조 투명성
      • 부수효과
      • 함수 합성
      • 제너릭 타입 활용하기
      • 암묵적 입출력
      • 액션과 계산, 데이터
      • 계층형 설계
      • 호출 그래프
      • 함수형 설계
      • 불변성
      • 일급 함수
      • 함수형 도구
    • Git
      • Github Actions
      • Conflict
      • Branch 전략
    • Contents Format
      • Audio
    • 3D Graphic
      • 3D keyword
      • Three.js
      • Geometry
      • Material
      • Light
      • Camera
      • Decal
      • Rotation
      • Text
      • Shadow
      • Fog
      • Post Processing
      • Animation
      • Math
        • Vector Space
        • 벡터의 연산
        • 회전 계산
      • 3D 컨텐츠가 만들어지는 과정
      • R3F
      • Env
      • Scene
      • Transform
      • R3F
      • Interaction & Raycast
      • Rendering Algorithnm
      • Blender
      • Blender
    • Accessibility
      • 접근성이란
    • Interactive Web
      • Parallax
      • Canvas
      • requestAnimationFrame
      • Effect
      • HSL
      • React.js + Canvas
      • Matter.js
    • AWS
      • DevOps
      • Amplify
      • S3
      • 클라우드 컴퓨팅
        • 온프레미스와 클라우드
        • 클라우드 도입효과
        • 클라우드 컴퓨팅의 범위
        • 컴퓨팅 옵션
          • EC2 - Virtual Machin
          • ECS, EKS - Container
          • Lambda - Serverless
        • 네트워크 가상화
        • 스토리지
        • 데이터베이스
        • 데이터 수집
        • 머신 러닝 영역
        • IoT 영역
        • 블록체인 영역
      • 클라우드 아키텍처 설계
    • Network
      • Web Server & WAS
    • System Design
      • System Design
      • Component
      • 의존성을 배제한 개발
      • Error Handling
      • Architecture
        • 모노로틱 아키텍처
        • Clean Architecture
        • Layered Architecture
        • 이벤트 기반 아키텍처
      • 상황을 파악하는 메타인지
      • 중복 문제 해결하기
      • Monorepo Arhitecture
        • 모노레포 운영과 트러블슈팅
        • Module Federation
      • 코드 병목지점
      • API 대응
      • 공통 코드
      • Infra 구축
      • 모듈 기반의 개발 방식
      • Design System
        • 최소 수준의 아키텍처 설정
        • 더 효율적인 디자인시스템 만들기
        • 디자인 시스템과 UI 라이브러리 목적
        • 디자인 토큰
      • 효율적인 업무
        • 업무 프로세스 병목 파악
      • Clean Code
      • Design Pattern
        • CQRS Pattern
        • Strangler Fig Pattern
        • 데코레이터 패턴
        • 커맨드 패턴
        • 전략 패턴
        • 옵저버 패턴
      • A/B 테스팅
      • 대규모 리엑트 웹앱 개발
        • 복잡성 관리
        • 모듈성
        • 성능
        • 디자인 시스템
        • 데이터 패칭
        • 상태 관리
        • 국제화
        • 코드 조직화하기
        • 개인화 A/B 테스팅
        • 확장 가능한 웹 아키텍처
        • 테스팅
        • 툴링
        • 기술적 마이그레이션
        • 타입스크립트
        • 라우팅
        • 사용자 중심 API 디자인
        • 리액트 미래
    • Performance
      • React DevTools
      • Component 최적화
      • Page Load
      • API
    • MFA
      • MSA
      • MFA 도입하기
      • Monorepo
        • Monorepo Tool
        • Yarn Berry Workspace
        • Turborepo
      • MFA Composition
      • SPA 통합
      • Design System
      • Package Manager
        • Yarn
        • pnpm
      • Transpiler & Bundler
        • Babel
        • Rollup
        • esbuild
        • swc
        • Webpack
        • Vite
      • 분해와 통합을 위한 여러 기술 비교
    • State Management
      • Zustand
    • React v18
      • Automatic batching
      • Suspense
      • Transition
    • SEO
      • Search Engine Optimization
      • Open Graph Element
      • Metadata
    • FE Develop
      • Scrubbing
      • Clipboard
    • Refactoring
      • 리팩토링 깊게 들여다보기
      • 긴 코드 조각내기
      • 타입 코드 처리하기
      • 유사한 코드 융합하기
      • 데이터 보호
      • 코드 추가 및 제거
    • OAuth 2.0
    • Analytics
      • Mixpanel
    • ETC
      • VSCode
    • React Hook In Action
      • useContext & Provider
      • 커스텀 훅
      • 코드 분할하기 with Suspense, lazy
      • Suspense와 이미지 적재하기
      • useTransition, uesDeferredValue
      • SuspenseList
Powered by GitBook
On this page
  • 깃허브 액션 핸즈온
  • 워크플로우 파일 작성
  • 테스트가 실패한 풀 리퀘스트를 병합할 수 없도록 설정하기
  • 워크플로 파일 작성법
  • 이름(name)
  • 환경 변수(env)
  • 트리거(on)
  • 작업(jobs)
  • 작업을 병렬처리해서 워크플로 최적화하기
  1. DEV_NOTE
  2. Testing
  3. 프론트엔드 테스트 입문

Github Actions 설정

PreviousE2E 테스트Next깃허브 액션에서 E2E

Last updated 9 months ago

깃허브 액션 핸즈온

  • 깃허브 액션은 빌드, 테스트, 배포 파이프라인을 자동화할 수 있는 CI 및 CD 플랫폼

  • 깃허브 액션은 깃허브 저장소에 yaml파일을 배치시키는것 만으로 테스트를 자동화할 수 있음

워크플로우 파일 작성

  • 깃허브 액션에서 워크프로는 일련의 작업들로 구성된 자동화 프로세스를 의미

  • .github/workflows 라는 디렉터리를 생성하고 워크플로 파일을 배치한다.

    • 이 작업만으로 깃허브 액션을 실행시킬 수 있음

name: CI

on: push # 저장소에 푸시할 때마다 실행됨

jobs:
  test:
    runs-on: ubuntu-latest # 운영체제는 최신 버전의 우분투 사용
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3 # CI환경에선 Node.js 사용
        with:
          node-version: 18
      - name: Install dependencies # CI 환경에 package.json을 설치
        run: npm ci
      - name: Jest unit test # CI 환경에서 npm test 실행
        run: npm test # 테스트 실행 스크립트

테스트가 실패한 풀 리퀘스트를 병합할 수 없도록 설정하기

  • 새로 생성한 저장소는 테스트가 실패한 상태여도 병합이 가능하다.

  • 의도치 않은 병합이 일어나지 않게 하려면 [Settings] -> [Branches] 페이지에서 브랜치 보호 규칙을 설정해야함

  • 규칙을 적용하려는 브랜치명 패턴을 Branch name pattern 에 입력

  • Require status checks to pass before merging 에 체크

  • 상태 검사 검색 박스에 작업 이름을 입력해서 해당 작업을 상태 검사 대상으로 선택할 수 있음

    • yml 파일에 지정했던 작업 이름을 입력하고 목록에서 선택

  • 페이지 하단에 [Create] 버튼을 클릭해서 설정 완료

워크플로 파일 작성법

  • 워크플로를 실행시킬 트리거와 워크플로의 내용을 기술하는 작업을 조합하면 CI/CD 파이프라인을 구축 가능

이름(name)

  • 워크플로 파일 맨 위에 있는 name 은 워크플로를 잘 나타내는 이름으로 작성

  • 이름은 실행 결과 등을 쉽게 식별할 수 있도록 지어야함

  • PR이나 액션 이력에서 식별을 위한 레이블로 사용됨

name: Test UI

환경 변수(env)

  • 워크플로 파일 상단에 위치한 env

  • 워크플로에 있는 작업에서 참조할 수 있는 환경 변수들을 정의한다.

  • 주로 ID, 비밀번호, 토큰 등 민감한 크리덴셜 정보를 참조할 때 사용함

  • 저장소마다 있는 Actions secrets 에 환경 변수를 설정하면 워크플로 파일에서 참조 가능

    • ${{ secrets.환경 변수명 }} 형식의 템플릿 문자열

    • 해당 방식으로 Actions.secrets 에 저장된 정보를 참조함

env:
  REG_NOTIFY_CLIENT_ID: asdf
  AWS_BUCKET_NAME: asdf

트리거(on)

  • 워크플로를 실행할 타이밍을 지정

on: push # 푸시할 때 마다 워크플로 실행
  • 모노레포로 구성된 저장소에서는 다르게 지정해야 한다.

    • 테스트 대상과 상관없는 파일이 푸시됐을 때에도 워크플로가 실행되기 떄문

    • 특정 패키지에 포함된 소스코드가 푸시됐을 때만 워크플로가 실행되도록 세부 경로를 지정해야함

on:
  push:
    paths:
      - packages/app/**

작업(jobs)

  • 워크플로에서 수행할 작업들을 단계별로 지정함

runs-on

  • 작업을 실행할 가상 환경의 운영체제를 지정

  • 상황에 맞는 여러 운영체제를 선택할 수 있으며 선택 가능한 운영체제는 공식문서에서 확인

runs-on: ubuntu-latest

steps

  • 작업에서 실행할 모든 스텝을 그룹화함

  • 그룹에는 개별 액션, 또는 셸 스크립트를 포함시킬 수 있음

steps:

uses

  • 스탭에서 액션을 사용할 때 선언한다.

  • actions/checkout 은 가장 많이 사용되는 액션

    • CI 환경에서 저장소에 접근할 때 사용하는 액션

    • 대부분 작업에서 사용됨

- uses: actions/checkout@v3
  • 프론트엔드 프로젝트는 actions/setup-node 도 대부분의 작업에서 사용함

  • 버전을 같이 지정하면 특정 버전의 Node.js가 CI 환경에서 설치됨

- uses: actions/setup-node@v3
  with:
    node-version: 18

run

  • CI 환경에서 실행할 커맨드를 작성

  • 프로젝트에서 실행할 수 있는 커맨드를 모두 사용할 수 있으므로 package.json에 작성한 npm scripts도 실행 가능

run: npm test

액션을 조합하거나 셸 스크립트를 등록해 CD 파이프라인도 만들 수 있다.

빌드된 애플리케이션을 배포하는것 뿐만 아니라 빌드된 스토리북도 호스팅 환경에서 전송하는 등 다양한 작업이 가능

작업을 병렬처리해서 워크플로 최적화하기

  • 작업을 실행한 결과물(설치한 모듈 혹은 빌드된 파일 등)은 캐싱이 가능하다.

  • 캐시를 활용하면 실행 시간을 단축시킬 수 있고 여러 작업에서 결과물을 공유할 수 있음

  • 깃허브 액션의 워크플로는 여러 작업의 병렬처리도 가능함

    • 모든 작업이 완료될 때까지 걸리는 시간을 단축 가능

  • 병렬 및 캐싱처리하여 작업을 재조합하면 실행 시간을 단축시킬 수 있음

  • 테스트 코드가 많아질수록 작업을 병렬처리한 효과도 극대화 된다.

한개의 작업만 가진 워크플로

name: Test UI

on: push

env: 
  REG_NOTIFY_CLIENT_ID: ${{ secrets.REG_NOTIFY_CLIENT_ID }}
  AWS_BUCKET_NAME: ${{ secrets.AWS_BUCKET_NAME }}
  
jobs:
  tests:
    runs-on: ubuntu-latest
  steps:
     - uses: actions/checkout@v3
       with:
         fetch-depth: 0
     - uses: actions/setup-node@v3
       with:
         node-version: 18
     - name: Configure AWS Credentials
       uses: aws-actions/configure-aws-credentials@master
       with: 
         aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
         aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
         aws-region: ap-northeast-2
     - name: Install dependencies # 의존 모듈 설치
       run: npm ci
     - name: Run Type Check # 타입 검사 실행
       run: npm run typecheck
     - name: Run Lint
       run: npm run lint
     - name: Run Unit Tests
       run: npm test
     - name: Build Storybook
       run: npm run storybook:build --quiet
     - name: RUn Storybook Tests
       run: npm run storybook:ci
     - name: Run Storycap
       run: npm run vrt:snapshot
     - name: Run reg-suit
       run: npm run vrt:run

작업 간 병렬처리 계획하기

의존관계에 따라 병렬처리

  • 개발환경과 동일하게 CI 환경에 node_modules 를 설치하면 다음과 같은 테스크를 실행할 수 있게 됨

    • 세 가지 테스크에는 의존 관계가 없기에 각각을 하나의 작업으로 분할해서 병렬처리 가능

      • 타입 검사, Lint 실행

      • 단위 테스트 실행

      • 스토리북 빌드

  • 빌드된 스토리북을 대상으로 테스트하는 작업

    • UI 테스트와 시각적 회귀 테스트는 서로 의존하지 않기 때문에 병렬처리

      • 스토리북을 활용한 UI 테스트

      • 스토리북을 활용한 시각적 회귀 테스트

# 스텝별로 병렬처리 가능
jobs:
  install: ... # 1.의존 모듈 설치
  check: ... # 2.타입 검사, Lint
  unit-test: ... # 2.단위 테스트
  build-storybook: ... # 2.스토리북 빌드
  test-storybook: ... # 3.스토리북을 활용한 UI 테스트
  vrt-storybook: ... # 3.스토리북을 활용한 시각적 회귀 테스트

작업 간 의존관계 구성하기

  • 워크플로를 구성하려면 작업들 간 의존관계를 설정해야 함

  • 작업의 needs 라는 프로퍼티에 의존하는 작업 명칭을 지정하면 의존하는 작업이 완료될 때까지 해당작업을 실행하지 않고 대기한다.

    • 이것이 작업간 의존관계 설정

jobs: 
  install: ...
  check: ...
    needs: install
    steps: ...
  unit-test: ...
    needs: install
    steps: ...
  build-storybook: ...
    needs: install
    steps: ...
  test-storybook: ...
    needs: build-storybook
    steps: ...
  vrt-storybook: ...
    needs: build-storybook
    steps: ...

의존하는 작업들 간에 캐시 활용하기

  • 모든 작업에는 프로젝트에 설치된 node_moduels 가 필요함

  • 따라서 npm ci 로 node_modules 를 먼저 설치해야 하지만 단순히 설치한다고 해서 후속 작업에서 공유할 수 없음

  • 깃허브 액션이 지원하는 actions/cache 를 사용하면 지정하 명칭의 에셋을 캐싱하거나 캐싱된 에셋을 불러올 수 있음

    • 한 작업에서 캐싱한 에셋을 다른 작업에서 불러올 수 있게되면 독립된 여러 작업 간에 에셋을 공유할 수 있게됨

  • install 부분에 if 문으로 작성한 조건은 'node_modules_cache라는 ID로 특정 가능한 캐시가 없다면' 이다.

    • 즉, 캐시가 없으면 설치를 시작하고 캐시가 있으면 스텝을 종료한다는 의미

  • path 에는 캐시의 경로를, key 에는 캐시에 사용할 키를 지정

    • hasFiles 함수를 사용해 package-lock.json 내용으로 해시 키를 생성함

    • package-lock.json 에 갱신된 내용이 없으면 캐시를 재활용하게 됨

jobs:
  install:
    runs-on: ubuntu:latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 18
      - name: Cache node_modules # 캐시가 있는지 검사
        uses: actions/cache@v3
        id: node_modules_cache
        with:
          path: node_modules # 캐싱할 의존 모듈
          key: ${{ runner.os }}-${{ hasFiles('**/package-lock.json') }}
      - name: Install dependencies # 캐시가 없으면 설치
        if: steps.node_modules_cache.outputs.cache-hit != 'true'
        run: npm ci

캐싱한 node_modules 불러오기

  • check 라고 명명한 작업에는 타입 검사와 Lint를 실행하고 있음

  • Restore node_modeuls 에서는 install에서 캐싱했던 node_modules 를 불러온다.

    • 캐싱했을 때와 코드는 동일하지만 지금은 워킹 디렉터리에 캐싱한 에셋을 불러오는 역할임

    • 동시에 병렬처리하는 unit-test 에서도 같은 방식으로 캐시를 불러와 테스트 실행

jobs:
  install: ...
  check:
    nddes: install
    runs-on: ubuntu:latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 18
      - name: Restore node_modules # 캐싱한 의존 모듈을 불러옴
        id: node_modules_cache
        uses: actions/cache@v3
        with:
          path: node_modules 
          key: ${{ runner.os }}-${{ hasFiles('**/package-lock.json') }}
      - name: Run Type Check # 타입검사 실행
        run: npm run typecheck
      - name: Run Lint # Lint 실행
        run: npm run lint

빌드된 스토리북 캐싱하기

  • 스토리북 테스트를 안정적으로 실행하려면 미리 CI 환경에서 스토리북을 빌드 한 후, node_modules 설치와 동일하게 후속 작업을 위해 빌드된 스토리북을 캐싱

    • 지금은 캐시용 키로 github.sha 를 사용해서 같은 커밋 내에서만 캐시를 공유 가능

jobs:
  install: ...
  check: ...
  unit-test: ...
  build-storybook: 
    needs: install
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 18
      - name: Restore node_modules # 캐싱한 의존 모듈을 불러옴
        id: node_modules_cache
        uses: actions/cache@v3
        with:
          path: node_modules 
          key: ${{ runner.os }}-${{ hasFiles('**/package-lock.json') }}
      - name: Cache Storybook # 빌드된 스토리북을 캐싱
        uses: actions/cache@v3
        id: storybook_cache
        with:
          path: storybook-static
          key: ${{ runner.os }}-${{ github.sha }}   
      - name: Build Storybook # 캐싱한 빌드 결과물을 불러옴
        if: steps.storybook_cache.outputs.cache-hit != 'true'
        run: npm run storybook:build --quiet

빌드된 스토리북을 불러와서 테스트에 활용

  • 끝으로 빌드된 스토리북을 불러와서 테스트를 실행

  • 빌드된 스토리북은 UI 테스트 및 시각적 회귀 테스트에 사용됨

jobs:
  install: ...
  check: ...
  unit-test: ...
  build-storybook: ...
  test-storybook:
    needs: build-storybook
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 18
      - name: Restore node_modules # 캐싱한 의존 모듈을 불러옴
        id: node_modules_cache
        uses: actions/cache@v3
        with:
          path: node_modules 
          key: ${{ runner.os }}-${{ hasFiles('**/package-lock.json') }}
      - name: Restore Storybook # 캐싱한 빌드된 스토리북을 불러옴
        id: storybook_cache
        uses: actions/cache@v3
        with:
          path: storybook-static
          key: ${{ runner.os }}-${{ github.sha }}   
      - name: Install Playwright # 스토리북을 활용한 UI 테스트에 필요한 의존 모듈
        run: npx playwright install --with-deps chromium
      - name: Run Storybook Tests
        run: npm run storybook:ci
example