pile·
프론트엔드·카카오 스타일 (지그재그)카카오 스타일 (지그재그)·

프론트엔드 테스트 자동화 전략 - 1. 테스트 자동화란?

카카오스타일이 프론트엔드 관점에서 테스트를 어떻게 잡아야 하는지 정리한 연재의 1편이다. 프레임워크 사용법이 아니라 무엇을 테스트할지, 즉 전략을 다룬다. 위양성과 위음성을 축으로 삼아 프론트엔드에서는 대부분의 테스트가 통합 테스트가 된다는 결론까지 간다.

핵심 포인트
  • 프론트엔드에는 DB를 바꾸는 로직이 없어 흔한 시나리오 문장을 그대로 테스트로 옮길 수 없다.
  • 테스트도 관리해야 하는 코드이므로 전략 없이 많이 쓰면 방치되거나 버려진다.
  • 위양성이 잦으면 테스트가 무시되고 위음성이 잦으면 애초에 버그를 못 잡아 둘 다 테스트를 무의미하게 만든다.
  • 컴포넌트의 DOM 구조나 내부 상태가 아니라 유저와 백엔드라는 외부 요소와의 상호작용을 검증해야 한다.
  • 프론트엔드는 여러 구성요소를 중개하는 코드가 대부분이라 유닛보다 통합 테스트가 어울린다.
  • 스토리북은 이미 모든 의존을 mock으로 세워둔 환경이라 통합 테스트의 가장 큰 비용을 이미 치른 상태다.
상세 정리
  • 배경: 프로젝트가 커질수록 서로 영향을 주는 요소가 늘고 회귀 테스트에 드는 시간도 늘어 잘 수행되지 않으며, 이는 기술 부채 누적으로 이어진다.
  • 자동화의 효용: 바뀐 내용이 정상 동작한다는 신뢰가 생기면 기능 단위가 아닌 전면 수정이 필요한 기술 개선도 두려움 없이 할 수 있다.
  • 현황 진단: 백엔드는 자동화 사례와 자료가 많지만 프론트엔드는 프레임워크 사용법 글만 있고 무엇을 어떻게 테스트할지 다루는 글이 드물다고 본다.
  • 용어 정리: 적은 코드를 격리해 검증하면 유닛 테스트, 여러 구성요소를 묶으면 통합 테스트, 실제 환경에서 고객이 쓸 수 있는지 보면 E2E 테스트다.
  • 프론트엔드의 어려움 1: 포인트가 차감되고 주문이 결제완료로 바뀐다는 식의 시나리오에서 DB 변경 부분은 프론트엔드 영역이 아니다.
  • 프론트엔드의 어려움 2: 백엔드는 외부에 노출할 API를 직접 선언하며 개발하지만 프론트엔드는 화면을 만드는 작업이라 무엇이 검증 대상인지 모호하다.
  • 과거 방식의 문제: 컴포넌트가 반환하는 HTML이나 내부 상태 변화를 비교하는 방식은 비효율적이고 쉽게 깨진다.
  • 위양성의 비용: 문제가 없는데 에러가 나면 처음엔 고치다가 피로가 쌓여 테스트가 방치되고 무시된다.
  • 위음성의 비용: 버그가 있는데 정상으로 판정하면 그 테스트를 믿고 배포해 장애로 이어진다.
  • 판단 기준: 고객에게 제공하는 가치, 즉 이 프로그램이 어떤 문제를 해결하며 무엇을 잃으면 안 되는지를 기준으로 삼아야 한다.
  • 시나리오 재구성: 유저와 백엔드를 외부 요소로 두면 백엔드 값이 사용자에게 어떻게 노출되는지, 버튼을 누르면 화면이 어떻게 바뀌는지, 버튼을 누르면 백엔드를 어떻게 호출하는지 세 갈래로 나뉜다.
  • 구체 예시: 주문서를 열면 상품 목록과 잔여 포인트가 노출된다, 전액사용을 누르면 결제 금액이 0원이 된다, 0원 상태에서 결제하기를 누르면 PG 호출 없이 주문 완료 API를 부른다.
  • 외부 요소의 확장: 공통 컴포넌트의 props도 한번 정해지면 바꾸기 어려운 암묵적 규약이므로 외부 요소로 보고 테스트 대상에 넣을 수 있다.
  • 유닛 테스트의 자리: 상품 목록에서 결제 금액을 계산하는 것처럼 복잡하고 독립적인 로직은 분리해 유닛 테스트로 검증하는 편이 좋다.
  • 사분면 판단: 복잡하고 독립적인 코드는 유닛 테스트, 간단하지만 외부 의존이 많은 코드는 통합 테스트, 간단하고 독립적인 코드는 굳이 다룰 필요가 없고, 복잡하면서 의존도 많은 코드는 로직과 상호작용으로 쪼개 리팩터링한다.
  • 라이브러리 선택: 내부 상태를 기준으로 검증하던 enzyme은 위양성이 나기 쉬웠고, react-testing-library는 유저가 볼 수 있고 행동할 수 있는 것을 기준으로 삼기를 권한다.
  • 가성비: 일회성이거나 자주 쓰이지 않는 기능은 테스트 우선순위가 낮다. 테스트는 코드에 대한 신뢰를 얻기 위한 것이므로 오래 쓰이지 않을 코드는 의미가 작다.
  • 통합 테스트 구현: 제어할 수 없는 외부 요소를 mock으로 대체하고 그 mock이 호출됐는지로 상호작용을 확인한다. 파일 저장 함수를 spyOn으로 가로채 호출 여부를 보는 예시를 든다.
  • 스토리북 활용: 스토리북은 컴포넌트를 격리하고 주변 환경을 mock으로 세워야 동작하므로 통합 테스트의 준비 작업이 이미 끝나 있다. Interaction Testing이 react-testing-library와 jest 기반으로 사용자 행동을 재현하는 play 함수를 제공한다.
왜 읽나프론트엔드 테스트를 어디서부터 써야 할지 막막하다면 무엇을 외부 요소로 볼 것인지부터 정하게 해주는 글이다.
카카오 스타일 (지그재그)
카카오 스타일 (지그재그) 블로그
원문은 여기서 이어서 읽을 수 있어요
원문 읽기
읽음 (0)

이 글과 비슷한

  1. 프론트엔드·여기어때 (GC컴퍼니)여기어때 (GC컴퍼니)·

    항공 프론트엔드 구축기 (7/10): 창구를 하나만 두었습니다

    여기어때 항공 서비스 프론트엔드가 웹과 앱 웹뷰 두 환경에서 동일한 함수 호출로 동작하는 앱 브릿지 추상화 레이어를 설계한 과정을 다룬다. iOS·안드로이드 규약 차이와 "웹에 존재하지 않는 브릿지를 어떻게 호출하나"라는 문제를 단일 추상화 층으로 해결한 구현 사례다.

    요약 이어보기
    #react#typescript#webview+2