공지
뉴스레터 발행 주기를 주 3회로 변경합니다.

하드 스킬

0043. 리액트 테스팅과 웹 표준, 그리고 시맨틱 웹

토이스토리 2기 커리큘럼이 조정됩니다. 그리고 이번 리액트 입문하는 연재 콘텐츠에서는 실제로 테스트 코드를 작성해요. 웹 프론트엔드의 테스팅에 관심 있는 분들은 이번 연재분을 꼭 보세요!

2024.12.16 | 조회 328 |
0
|
from.
푸딩캠프
푸딩캠프의 프로필 이미지

푸딩캠프

주 3회, 하드스킬, 소프트스킬, 멘토링과 코칭 사례를 다루는 콘텐츠로 여러분의 학습과 성장을 돕습니다.

푸딩캠프 이야기

토이스토리 2기 커리큘럼 조정

푸딩캠프에서 토이 프로젝트를 만들어 출시하는 프로그램인 토이스토리 2기의 커리큘럼이 조정됩니다. 기존 4주 프로젝트와 8주 프로젝트 두 개를 진행하던 기존 커리큘럼을 6주 프로젝트 하나를 개발하여 출시하는 커리큘럼으로 조정됩니다. 참가비는 더 저렴해지고, 어디에서도 보지 못한 색다른 프로그램으로 업그레이드 됩니다! 새로운 2기를 기대해주세요!

 

Subscription 컴포넌트에 대한 단위 테스트 작성하기, 그리고 웹 표준과 시맨틱 웹

테스트 시나리오 구상

Subscription 컴포넌트는 아주 단순한 동작을 하지만, 엄밀하게 동작을 테스트한다면 여러 상황이 가능합니다.

  • 기본 Props를 전달하면 예상한 렌더링 결과를 반환한다
  • 글자를 입력하면 이메일 입력 변경을 반영한다.
  • 구독 버튼을 클릭하면 입력한 이메일을 전달한다.
  • 함수를 자식 노드로 전달하면 예상한 렌더링 결과를 반환한다.
  • 이메일이 비어있으면 자동으로 입력 창에 포커스를 준다.
  • 이메일이 비어있지 않으면 자동으로 입력 창에 포커스가 적용되지 않는다.

일부 시나리오는 굳이 테스트하지 않아도 되지만, 테스트 코드를 연습하는 목적으로 테스트 코드를 작성해보겠습니다.

테스트 시나리오 구현하기

테스트 코드 틀

먼저 테스트 파일을 만듭니다. Subscription.jsx 파일이 있는 경로에 Subscription.test.jsx 파일을 만들고 다음 코드를 작성합니다.

 
 

자, 테스트 코드를 작성해나갈 틀을 구성했습니다. 어떤 테스트인지를 기술하는 describe() 함수 안에 test() 함수를 채워나갈 것입니다. 각 테스트 함수는 앞서 정의한 테스트 시나리오 각 각에 짝지어졌다고 보시면 돼요.

셸에서 pnpm test를 입력해 실행해보세요. 테스트가 실행되고, 파일 중 변동이 있는지 지켜보고 있습니다. 켜놓은 상태에서 테스트를 작성하고 저장해보세요. 저장할 때마다 변동사항에 대한 테스트 코드를 자동으로 수행합니다. Failed 라는 메시지와 함께 테스트가 실패하다가 코딩 작업하는 중 passed 메시지가 표시되면 기분이 무척 짜릿하답니다.

 

기본 Props를 전달하면 예상한 렌더링 결과를 반환한다.

 
 

렌더링이 잘 되는지는 렌더링했을 때 화면에 나와야 할 요소가 렌더링 됐는지를 검사하면 됩니다.

컴포넌트를 렌더링하는 함수는 render()로, JSX 문법으로 리액트 노드를 인자로 전달합니다. render() 함수는 RenderResult 객체를 반환하는데, 이 객체에 있는 멤버 중 container는 HTML의 document DOM 객체와 비슷한 역할을 합니다. 물론 실제로는 리액트 DOM의 객체이기 때문에 HTML DOM의 document와는 다릅니다.

 
 

container 객체엔 렌더링 된 정보가 DOM 형태로 저장되어 있으며, DOM 다루듯이 리액트 DOM을 다룰 수 있습니다. Subscription 컴포넌트가 문제 없이 렌더링되면 “이메일 주소를 입력하세요” 문구가 placeholder로 표시하는 input 요소가 표시되며, Props와 자식 노드에 따라 출력되는 요소가 있습니다. 테스트 코드에서 자식 노드는 h2 이고, Props로 전달된 버튼 Label은 “구독하기”입니다. 테스트 코드는 이에 대한 검증을 했습니다.

 

글자를 입력하면 이메일 입력 변경을 반영한다.

글자를 입력하면 입력한 DOM 요소의 값이 반영됩니다. 이건 뻔하고 자명해서 사실 테스트 코드가 별 의미는 없습니다. 하지만, 입력값에 따라 해당 input 컴포넌트 상태가 변화한다면 이러한 테스트가 필요할 것입니다.

 
 

RenderResult 객체에는 다양한 유틸리티 함수가 있습니다. 분류를 하자면 크게 세 종류가 있지요.

함수 유형요소가 존재할 때요소가 없을 때여러 요소가 일치할 때비동기 동작
getBy* 요소 반환오류 발행오류 발생동기식
queryBy*요소 반환null 반환오류 발생동기식
findBy*Promise로 요소 반환Promise reject오류 발생비동기식

getBy*는 요소가 반드시 존재해야 할 때 사용합니다. queryBy*는 요소가 있는지 없는지 확인할 때 유용하죠. findBy*는 비동기적으로 나타나는 요소를 테스트할 때 사용하며, Promise 기본 제한 시간은 1000ms 입니다.

예를 들어, placeholder 값이 “이메일 주소를 입력해주세요”인 요소가 반드시 있어야 하므로 getByPlaceholderText 함수를 사용했습니다. 만약 없다면, 예를 들어, placeholder 문자열을 변경하면 오류가 발생하여 이 테스트는 실패하게 되지요.

userEvent는 뒤에서 자세히 설명하고, 이 단계에서는 사용자 상호작용을 하는 데 사용하는 도구 정도로 알아두겠습니다. userEvent.setup()을 호출해 상호작용할 사용자 객체를 하나 생성합니다. 그리고 사용자가 키를 타이핑하는 것을 시뮬레이션 하기 위해 type() 메서드를 사용하여 이메일 주소 하나를 입력합니다.

입력을 마친 후 input 요소의 값(value)을 확인하면 우리가 방금 입력한 이메일 주소인 걸 확인할 수 있습니다.

 

구독 버튼을 클릭하면 입력한 이메일을 전달한다.

이번엔 이메일 주소를 입력한 후 “구독하기” 버튼을 누르면 Props로 전달된 콜백 함수를 호출하는지를 테스트 합니다.

 
 

const onSubscribe = vi.fn() 이 무엇인지에 대해서는 다음 편에서 자세히 다루기로 하고, 여기에서는 목(Mock) 객체를 사용해 모킹(Mocking)하는 것 정도로 알아두세요. 목 객체인 onSubscribe를 Props로 전달하고, 이메일 주소를 입력한 후 “구독하기” 버튼을 누르면 입력한 이메일 주소를 인자로 받아 onSubscribe 콜백 함수가 호출되어야 합니다. 이를 코드로 기술한 것이 위 코드입니다.

 

함수를 자식 노드로 전달하면 예상한 렌더링 결과를 반환한다.

Subscription 컴포넌트는 자식 노드가 함수이면 해당 함수를 제목과 현 email 상태값을 인자로 전달하며 실행합니다. 제목은 “학습과 성장 컨텐츠 소식”이지요. 이 테스트 역시 첫 번째 테스트처럼 화면에 렌더링되어야 할 요소가 있는지 검사하는 방식으로 테스트를 작성하면 됩니다.

 
 

두 번째 querySelector를 보면 DOM Selector가 조금 복잡해보입니다. 리액트 웹 프로그래밍을 한다면 좋든 싫든 웹, 그 중에서도 DOM, CSS에 대해서는 숙지하는 게 좋습니다. 리액트 테스트 코드 작성하는데 CSS Selector 문법이 불쑥 나오니 말이죠. 혹시 긴가민가 하실 분을 위해 설명해드리면 요소 속성(Element attribute)인 role의 값이 "paragraph", role-label의 값이 "현재 이메일"인 p 컴포넌트를 찾는 것입니다.

 

이메일이 비어있으면 자동으로 입력 창에 포커스를 준다.

Subscription 컴포넌트는 사용자가 이메일 주소를 입력하지 않은 채 가만히 5초 이상 있으면 자동으로 이메일 입력란에 포커스를 두어 입력을 촉구합니다. 이러한 타이머 관리도 테스트 코드에서 모사됩니다. 바로 vi 객체에 있는 advanceTimersByTime()입니다.

 
 

이 메서드에 5초(5000ms)를 인자로 전달하면 5초 동안 시간을 보냅니다. 시간이 지난 후에 현 document의 현 활성 요소가 input 컴포넌트인지 확인합니다. document는 실제 HTML DOM은 아니고, JSDOM의 document 객체로 시뮬레이션 된 객체입니다. vitest.config.js 파일에 다음과 같은 설정이 있어서 사용 가능한 것이지요.

 
 

이메일이 비어있지 않으면 자동으로 입력 창에 포커스가 적용되지 않는다.

마지막 테스트는 이메일 입력란에 내용이 있으면 자동으로 포커스하지 않는 동작을 테스트합니다. 이번 테스트는 활성 요소(activeElement)를 명확하게 구분하기 위해 이름 입력란(input)을 하나 더 둡니다.

 
 

테스트는 먼저 이메일 입력란에 이메일을 입력합니다. 그리고 곧바로 이름 입력란에 PuddingCamp 문자열을 입력하지요. 이제 활성 요소는 이름 입력란입니다. 그 상태에서 5초를 기다린 뒤 다시 확인합니다. 물론 제대로 동작한다면 여전히 이름 입력란이 활성 요소이며, 기대한(expect) 대로 동작합니다.

 
 

우리의 테스트 여섯 개 모두 통과하였습니다!

 

userEvent

userEvent는 사용자 상호작용을 시뮬레이션하는 도구입니다. 이 라이브러리는 브라우저에서 실제 사용자 상호작용이 발생할 때 일어나는 이벤트를 모사하지요.

userEvent는 단순히 DOM 이벤트를 일으키는 것이 아니라 실제 사용자의 행동을 모방합니다. 그리고 사용자의 동작 하나에 대해 관련된 여러 이벤트를 차례대로 발생시키지요. 사용자의 행동을 모방하는 동작이기 때문에 당연스럽게도 실제 상호작용이 가능한 요소에 대해서만 상호작용이 일어납니다. 가령, 숨겨진 요소이거나 비활성화 된 버튼, 인풋에 입력이 일어나지 않습니다.

userEvent와 비슷한 도구로 fireEvent가 있습니다. userEvent가 fireEvent보다 더 높은 수준으로 추상화를 제공합니다. 더 사용자 상호작용과 비슷한 동작과 흐름으로 테스트를 하고자 한다면 userEvent를 권장합니다.다음은 주요 API입니다.

  • setup() : userEvent 인스턴스를 구성하고 시작합니다.
  • click() : 요소를 클릭하는 동작을 시뮬레이션합니다.
  • type() : 텍스트 입력을 시뮬레이션합니다.
  • selectOptions() : <select> 요소에서 옵션을 선택하는 동작을 시뮬레이션합니다.
  • clear() : 입력 필드를 지우는 동작을 시뮬레이션합니다

웹 표준, 시맨틱 웹, 그리고 테스팅

웹 표준(Web Standards)이란?

웹 표준은 웹 페이지와 웹 애플리케이션을 개발할 때 따라야 할 규범적 지침과 기술 사양의 집합을 뜻합니다. 대표적으로 W3C(World Wide Web Consortium)에서 제정한 HTML, CSS, JavaScript의 표준 사양과 ARIA(Accessible Rich Internet Applications) 같은 접근성 관련 표준들이 있습니다. 웹 표준을 준수하면 브라우저와 기기 종류, 운영체제에 상관 없이 일관성 있는 사용자 경험을 (이상적으로는) 제공합니다.

 

시맨틱 웹(Semantic Web)이란?

시맨틱 웹은 웹 문서와 애플리케이션에 “의미(시맨틱)”를 부여해, 시각적으로 정보를 보여주는 것에 그치지 않고, 기기(컴퓨터) 또한 그 구조와 의미를 이해하고 활용할 수 있도록 돕는 개념입니다. 예를 들어, 단순히 <div> 태그로 모든 것을 감싸는 대신, <header>, <nav>, <main>, <article>, <section>, <footer>와 같은 시맨틱 태그를 적절히 사용하여 문서 구조를 명확히 하면, 검색 엔진이나 스크린 리더 등의 보조기기는 물론, 테스트 도구 또한 해당 요소의 역할과 의미를 보다 명확하게 파악할 수 있습니다 . 이는 접근성과 SEO(검색 엔진 최적화)를 강화할 뿐만 아니라, 자동화된 테스트에서 요소를 식별하고 상호작용하는 과정을 수월하게 만듭니다.

 

왜 웹 표준과 시맨틱 웹을 알아야 하는가?

웹 프론트엔드 테스팅은 단순히 “코드가 동작하는가?”를 넘어 “코드가 올바르게 구현되었는가?”, “접근성과 호환성이 확보되었는가?”, “향후 리팩터링과 유지보수가 수월한가?”를 살펴보는 과정입니다. 웹 표준을 준수하고 시맨틱한 마크업을 적절히 활용하면, 다음과 같은 장점이 있습니다.

  • 테스트 시 요소 선택자 관리 용이
  • 접근성 및 호환성 테스트 향상
  • 브라우저 간 이슈 최소화

 

프론트엔드 테스팅 역량 강화로 이어지는 이유

  • 코드 품질 향상
  • 테스트 자동화 효율성
  • 지속 가능한 코드베이스
 
 

결론

웹 표준과 시맨틱 웹에 대한 이해는 “잘 보이는 웹페이지”를 만드는 것을 넘어, 향후 자동화 테스트, 접근성 검증, SEO 최적화, 유지보수성 강화 등 다양한 관점에서 당신이 맡은 프론트엔드 개발 업무를 한 단계 성장시켜줄 수 있습니다. 웹 표준과 시맨틱 웹을 충분히 학습하고 코드에 반영한다면, 프론트엔드 테스팅의 품질과 효율이 눈에 띄게 개선될 것입니다.


푸딩캠프 뉴스레터가 유익하셨나요? 주변에 소개해주세요. 뉴스레터 구독자 수는 더 좋은 컨텐츠를 만드는 원동력입니다.

뉴스레터 관련하여 문의나 건의는 이 이메일 주소인 newsletter@puddingcamp.com 로 답장을 보내시면 됩니다.

또한 한날과 커피챗은 언제든 열려있고 환영합니다. https://puddingcamp.com/coffeechat 에 방문하셔서 커피챗 일정을 잡아보세요!

다가올 뉴스레터가 궁금하신가요?

지금 구독해서 새로운 레터를 받아보세요

✉️

이번 뉴스레터 어떠셨나요?

푸딩캠프 님에게 ☕️ 커피와 ✉️ 쪽지를 보내보세요!

댓글

의견을 남겨주세요

확인
의견이 있으신가요? 제일 먼저 댓글을 달아보세요 !

다른 뉴스레터

© 2024 푸딩캠프

주 3회, 하드스킬, 소프트스킬, 멘토링과 코칭 사례를 다루는 콘텐츠로 여러분의 학습과 성장을 돕습니다.

뉴스레터 문의newsletter@puddingcamp.com

메일리 로고

자주 묻는 질문 서비스 소개서 오류 및 기능 관련 제보

서비스 이용 문의admin@team.maily.so

메일리 사업자 정보

메일리 (대표자: 이한결) | 사업자번호: 717-47-00705 | 서울 서초구 강남대로53길 8, 8층 11-7호

이용약관 | 개인정보처리방침 | 정기결제 이용약관 | 라이선스