실용적인 프론트엔드 테스트

최근에 프론트엔드 테스트에 대해서 고민이 많다. 그 동안 한번도 프론트엔드에서 테스트와 관련된 작업을 하지 않았던게 컸고, 막상 하려니 도대체 뭘 테스트 해야하지? 라는 생각이 들었기 때문이다. 이것저것 테스트 코드를 작성해보니 정말 이게 맞을까? 라는 의문도 커졌다. 다양한 자료를 찾아보다 아래 영상을 보게됐는데... 오! 나름의 방향을 찾은 것 같은 느낌이 들었다.

물론 최신 자료는 아니기에 수정되어야 할 부분 이라던가 더 개선할 수 있는 부분이 많겠지만. 우선 위 수준으로 테스트를 다뤄봐야 개선의 여지를 찾을 수 있으리라 생각된다.


왜 테스트를 할까?


아래는 클린 아키텍처에서 설명하는 테스트의 이유다.

소프트웨어는 수학이 아닌 과학이다. 과학 이론은 반증은 가능하지만 증명은 할 수 없다. 소프트웨어도 마찬가지로 언제나 동작할거라 증명할 수 없다. 테스트를 통해서 반증할 수 있을 뿐이다. 테스트가 보장할 수 있는 것은 프로그램이 목표에 부합할 만큼 충분히 참이라고 여길 수 있게 해준다는 것이다.

영상에서는 같은 맥락으로Confidence라는 단어로 테스트의 이유를 설명했다. 자신이 작성한 코드가 정말로 작동하는지 검증하여 스스로에게 자신감을 준다.


뭘 테스트 해야할까?


프론트엔드는 도대체 무엇을 테스트 해야할까? 영상에서는 사용자에게 의도한 대로 보여지는지 테스트하는 시각적 요소를 검증하는 테스트와 해당 컴포넌트의 기능이 정말 작동하는지 테스트하는 기능적 테스트로 나누어 설명한다.


시각적 요소의 검증


HTML, 스냅샷 비교

가장 보편적이고 간단하게 시각적 요소를 검증할 수 있는 방법이다. 하지만 영상에서는 이 방법을 추천하지 않는다. 이유는 아래와 같다.

  • 정말 이 테스트가 우리에게 자신감을 줄까?
  • HTML이 의도한 대로 나왔다고 정말 정확한 걸까?
  • (어차피 깨질 테스트인데) 리팩토링할때 도움이 될까?

들어보면 맞는 말이다. 이러한 테스트는 노드 네임 혹은 클래스 네임의 변경으로 쉽게 깨진다. 이를 수정한 개발자는 자신이 고쳤으니 당연히 깨진 것이라 생각하며 깨진 부분을 수정할 것이다. 결국 개발자는 불필요한 작업을 한번 더 해야하는 셈이다. (테스트 = 비용)

이미지 비교

이미지 비교는 시각적 요소를 가장 확실하게 검증할 수 있는 방법이다. 하지만 캡쳐 이미지의 신뢰성이 테스트의 신뢰성과 비례하며 (브라우저마다 렌더링되는 방식이 다르므로 이미지 픽셀이 다르게 인식되는 이슈도 있다) 결과 확인 및 이력 관리의 어려움이 있다.

영상에서는 외부 서비스를 사용하여 이러한 테스트를 관리하는 것을 추천한다. 그 중에서도 고슴도치가 귀엽다고 Percy를 추천했다. 그리고 Percy와 스토리북의 조합을 굉장히 긍정적으로 평가했다. 하지만 시각적 테스트는 속도가 매우 느리며 스펙 문서로써 역할을 못하기 때문에 기능적 테스트를 동시에 할 것을 권장한다.


기능적 테스트


시각적 요소의 의존 최소화

기능적 테스트는 시각적 테스트와 최대한 분리하는게 좋다. 값 확인을 위한 별도의 클래스를 할당하거나 테스트 아이디를 부여하여 테스트를 진행하는 등. 단순히 태그의 이름이나 클래스의 변경으로 인해서 테스트가 최대한 깨지지 않도록 하고 컴포넌트의 기능을 테스트하는데 집중이 되도록 해야한다.

// Bad
<div class="button">
    Click Me!
</div>

const [ button ] = container.getElementsByClassName('button')
expect(button).toBeInTheDocument()

이 경우 태그를 button으로 바꾸거나 클래스를 button2로 수정할 경우 테스트가 깨진다.

// Good
<div data-testid="button" class="button">
    Click Me!
</div>

expect(screen.getByTestId('button')).toBeInTheDocument()

이 경우 시각적 정보의 변경으로 테스트가 깨지지 않으므로 기능적 테스트를 작성하기에 좋다.

Jest vs Cypress

Jest 보다는 Cypress의 사용을 좀 더 추천하는데 Jest는 속도는 빠르지만 시각적인 정보가 없어서 실제적인 TDD가 어려운 반면에 Cypress는 가능하다는 입장이다. 하지만 Cypress로 모든 테스트를 커버하기엔 속도가 너무 느리지 않나...? 하는 의심은 든다.


요약


  1. 테스트가 나에게 자신감을 주도록 하라.
  2. 테스트는 비용이다.
  3. 시각적 테스트와 기능적 테스트를 분리하라.
  4. 시각적 테스트를 자동화 할 때 전문 도구를 고려하자.
  5. 모듈 단위보다 컴포넌트 단위로 작성하는 것을 먼저 생각하자.
  6. 스토리북을 사용하면 시각적 요소를 편하게 테스트 할 수 있다.
  7. Cypress를 사용하면 기능적 요소를 편하게 테스트 할 수 있다.

이 글이 도움이 되었나요?

신고하기
0분 전
작성된 댓글이 없습니다. 첫 댓글을 달아보세요!
    댓글을 작성하려면 로그인이 필요합니다.