Jest

dana·2022년 1월 26일
3

Javascript / algorithm

목록 보기
5/15
post-thumbnail

Jest란?

제스트는 테스트 코드를 찾고, 테스트를 실행하고, 실패인지 성공인지를 판단하는 테스트 러너. facebook 에서 개발하고 관리(https://jestjs.io/)

제스트만의 특징은
Html 요소를 탐색하는데 접근성 마커 즉, aria를 이용해 TDD를 작성함으로서 자연스럽게 접근성을 향상시키는 장점이 있음. 제스트가 요소를 aria를 통해 찾을 수 있다 == 스크린 리더들도 찾을 수 있다

실습

리액트 앱 생성

npx create-react-app jest
yarn create react-app

jest가 기본적으로 함께 설치됨.

test실행을 위해

npm test
yarn test

제스트가 watch mode로 실행되는것을 확인.
watch mode : 파일에 수정 사항이 감지될 경우 자동으로 테스트를 실행해주는 상태

💡 만약 제스트 실행 시 노드 버전 이슈로

이런 에러가 발생한다면 제스트와 관련된 패키지를 설치.

npm i -D --exact jest-watch-typeahead@0.6.5

jest 명령어

a - 모든 테스트를 실행
f - 실패한 테스트들만 실행
p - 정규표현식에 해당하는 파일이름만 필터링

t - 정규표현식에 해당하는 테스트만 필터링
enter - 모든 테스트를 실행.
q - 테스트 종료

시작부터 모든 테스트를 실행하도록 하고 싶다면 명령어 뒤에 --watchAll을 붙여서 실행

샘플 코드

실행 코드는 파일이름.test.js 형식을 가진다.

import { render, screen, fireEvent } from '@testing-library/react';
import App from './App';

// test(테스트에 대한 설명)
test('renders learn react link', () => {
  render(<App />);
  const linkElement = screen.getByText(/learn react/i);
  expect(linkElement).toBeInTheDocument();
});
  • Test 함수 : 글로벌 함수. 두 가지 인자를 가짐
    - 첫번째 인자는 문자열로 테스트의 설명 (자스민에서는 describe)
    - 두번째 인자는 테스트를 실행하는 테스트 함수
  • Render 함수 : 인자로 받는 JSX의 가상돔을 생성. 여기서는 app 컴포넌트를 전달받음
  • Screen : 생성된 가상돔에 접근하기 위한 전역 객체 (render(<App />);에 접근)
  • getByText 함수 : 인자로 전달된 텍스트를 가지는 돔 안의 요소를 찾음. 정규표현식 사용 가능 (/learn react/i 뒤에 붙은 i는 대소문자를 구분하지 않겠다는 의미)
  • expect 함수 : 기대한 결과가 성공인지 실패인지 판단하는 함수
  • .toBeInTheDocument : matcher 함수 제스민의 ( ==.toBe() 함수)
    - 💡 matcher 함수 종류
  • fireEvent : 가상돔과의 상호작용이 가능하도록 하는 객체

테스트 코드

test('버튼이 제대로 잘 작동하고 있습니까?', () => {
  	render(<App />);
	const button = screen.getByRole('button', { name: 'change to blue!' });
	expect(button).toHaveStyle({ backgroundColor: 'red' });
});

getByRole

getByRole( role, 찾아야할 요소 안의 텍스트 )
screen.getByRole('button', { name: 'change to blue!' })
-> change to blue라는 값을 가진 버튼이 있어야한다.

role : aria에서 사용하는 요소의 역할을 의미하는 속성

  • 특정 요소는 role 을 명시하지 않아도 암묵적으로 가지고 있는 경우도 있음.
    https://www.w3.org/TR/html-aria/#docconformance
  • role 값이 틀렸을 경우 친절하게 제스트에서 제안을 해주기도 
  • 암묵적인 role이 없는 요소의 경우, role 속성을 직접 명시 <div role = "wrapper"/>
  • 되도록이면 정식으로 지원하는 role을 사용하는 것이 좋음.
    - 💡 role의 종류
  • getByRole함수는 두번째 인자로, 찾아야할 요소 안의 텍스트를 지정할 수 있습니다.
  • toHaveStyle 함수 : 요소가 특정한 CSS 스타일을 가지고 있는지 체크

App.test.js

import { render, screen, fireEvent } from "@testing-library/react"
import App from "./App"

test("버튼이 제대로 동작하고 있나요", () => {
  render(<App />)
  const button = screen.getByRole("button", { name: "change to blue!" })
  fireEvent.click(button)
  // 버튼 요소를 클릭했을 때, 아래의 결과를 기대함
  expect(button).toHaveStyle({ backgroundColor: "blue" })
  expect(button.textContent).toBe("change to red!")
})

App.js

import "./App.css"
import { useState } from "react"

function App() {
  const [buttonColor, setButtonColor] = useState("red")
  function handleClick(e) {
    setButtonColor(buttonColor === "red" ? "blue" : "red")
  }
  return (
    <div className="App">
      <button
        style={{ backgroundColor: buttonColor }}
        onClick={() => handleClick()}
      >
        change to {buttonColor === "red" ? "blue" : "red"}!
      </button>
    </div>
  )
}

export default App

실행화면

테스트 결과

profile
PRE-FE에서 PRO-FE로🚀🪐!

2개의 댓글

comment-user-thumbnail
2022년 1월 28일

너무 멋져요♡

1개의 답글