들어가며

나는 현재 Next.js 기술스택을 이용한 사이드 프로젝트를 진행중이다.

해당 프로젝트는 Vercel로 배포되도록 해두었으며, main 브랜치로 Pull Request 생성 시 Github Actions를 사용해 jest 테스트를 자동으로 진행하도록 환경을 구축해두었다.

(대충 요런 느낌이다)

그런데 어느날 여느때와 다름없이 기쁜 마음으로 feature 브랜치에서 main으로 PR을 작성하다가 문득 이상한 점을 깨닫게 되었다.

PR 생성 후 동작은 크게 표시한 두 개로 나누어지는데, 누가봐도 오래 걸릴 것 같은 Vercel 보다 Jest 테스트가 훨신 오래 걸렸던 것이다.
(Jest=1m28s | Vercel=1m10s)

암만 Vercel이 좋다고 한들, 의존성을 설치하고, 빌드하고, 배포하는 시간이 의존성을 설치하고 테스트하는 시간보다 빠를 수는 없을 것이다. (그래도 버쎌 b)

즉, 테스트 구간에 최적화 할 부분이 있다는 것이다.

따라서 이번에는 Github Actions의 테스트 속도를 높이는 방법에 대해서 알아보도록 한다.


최적화 해보기

사태 파악

우선 잘 돌아가고 있는 애꿎은 Vercel이 아닌, 나의 테스트를 확인해보도록 한다.
애초에 Vercel이 더 빠르다고 Vercel 속도를 낮추는 것도 이상하다 (하향평준화)

현재 설정되어 있던 테스팅 .yml 파일의 동작은 크게 2가지가 존재한다.

  1. npm ci를 통해 의존성 설치
  2. npm run test:once를 통해 테스트 진행

한번 각 스텝이 얼마나 많은 시간을 소요했는지 확인해보자.

가장 많은 시간이 소요된 스텝은 의존성 설치 구간으로, 무려 1m28s 중 1m 9s를 차지하고 있었다.
그 아래 실제 테스트는 3s밖에 소요되지 않았는데, 테스트 준비 때문에 시간을 허비한 것이다.

이건 마치 배달 50분 기다려서 5분컷 한 느낌이다.

자 그럼 문제가 되는 부분을 파악했으니, 의존성 설치 부분을 최적화해보도록 하자.



최적화 진행

Github Actions 의존성 설치 캐싱하기

우리는 언제 의존성을 설치하나?

우리가 로컬에서 개발할 때를 한번 떠올려보자.
우리는 한번 의존성을 설치하고 나면, 코드를 수정 할 때 마다 다시 의존성을 설치하지 않는다.

설치되어 있는 의존성을 굳이 다시 설치할 이유가 없기 때문이다.

단, 의존성 버전이나 목록이 바뀌었을 때는 의존성 설치를 다시 해준다.

결론적으로 Github Actions에서도 필요할 때 빼고 설치한거 그대로 쓰면 된다는 것이다.



Github Actions 에게 알리기

아니 근데 Github Actions가 이전이랑 의존성 리스트가 달라졌는지 아닌지 어케 알아요 😅

그건 바로 package-lock.json 또는yarn.lock 과 같은 파일을 확인하면 알 수 있다.

이 파일들은 package.json과 같은 파일들과 달리 의존성들의 정확한 버전을 작성해두기 때문에 의존성이 이전과 변경되었는지는 이걸 보면 확연히 알 수 있다.

따라서 Github Actions에서 제공하는 hashFiles 함수를 통해 package-lock.json 파일을 해시화 하고, 이를 캐싱 데이터를 구별하는 key로써 사용하면 된다.

이를 구현하는 코드는 아래와 같다.

- name: Caching dependencies
  id: cache
  uses: actions/cache@v3
  with:
    path: '**/node_modules'
    key: ${{runner.os}}-node-${{ hashFiles('**/package-lock.json')}}
    restore-keys: |
      ${{ runner.os }}-node-

그리고 npm ci는 캐싱 된 데이터가 없을 때만 실행되도록 변경해준다.

- name: Install dependencies
    if: steps.cache.outputs.cache-hit != 'true'
    run: npm ci

한번 결과를 확인해보자!

!!!!!!!!!!!!!!!!!!!

1m 9s ----> 13s 로 무려 56s가 줄어든 모습을 확인 할 수 있다.
이 처럼 dependecies의 캐싱 하나 만으로도 획기적으로 시간이 단축 된 결과를 얻을 수 있다.


추가적으로..

사실 의존성 설치 외에도, 테스트를 구동시키는 환경을 바꿔 최적화를 진행하기도 한다.
다만 이건 지금 내 상황에서는 아직까지 필요하지 않으므로 나중에 다시 해보도록 할 것이다.



정리

테스트 자동화 환경을 구축하는 것도 중요하지만, 이를 얼마나 '잘' 구축하는 건지도 중요하다.

만약 이게 4명이 있는 조직이고, 각각 하루에 10번씩 테스트를 진행했다고 가정한다면
56 x 4 x 10 = 2240s = 37분 의 시간을 매일매일 절약하게 된 것이다.

이 처럼 아직 테스트 자동화 환경을 구축했는데 너무 오래 걸린다고 느낀다면 한번 최적화 해보는 걸 추천한다.


  • (지금 경우에는) Github Actions에서의 의존성 설치가 오래 걸리는 문제가 있었다.
  • 의존성 설치의 경우에는 캐싱을 통해 속도를 대폭 줄일 수 있다.
  • 그 외에도 테스트 시간을 줄이는 방법이 더 있으므로 꼭 공부해보자.

+ 읽어주셔서 감사합니다.
+ 오타, 내용 지적, 피드백을 환영합니다. 많이 해주실 수록 제 성장의 밑거름이 됩니다.
profile
반갑습니다. 프론트엔드 개발자 황주현 입니다. 🤗

0개의 댓글