리액트에서는 Testing Library, Jest를 통해 테스트 가능
- 두 개의 역할이 각각 다르므로 함께 사용해야 함
- Vue, Svelte에서도 사용 가능
create-react-app으로 설치하면 자동으로 해당 라이브러리가 같이 설치된다
: JavaScript의 Testing Framework / Test Runner
npx create-react-app 생성폴더명
"dependencies": {
"@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^13.3.0",
"@testing-library/user-event": "^13.5.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
@testing-library/jest-dom : Jest-dom 제공하는 custom matcher를 사용할 수 있게 해줌@testing-library/react : 컴포넌트의 요소를 찾기 위한 query가 포함됨@testing-library/user-event : click 등 사용자 이벤트에 이용함npm run test이나 npm t )해보면
test 함수test 함수react-testing-library를 통해 render() 함수의 인자로 테스트할 컴포넌트를 전달getByText() 메서드로 render(<App />);로 가져온 App컴포넌트에 learn react라는 문자열이 있는지 확인하고 linkElement 변수에 할당.i : Regular Expression으로 "i"를 붙임으로써 대소문자 구분안함)document.body에 존재하는지 toBeInTheDocument 함수를 사용하여 체크.toBeInTheDocument 함수는 matchers 함수라고 부름.import { render, screen } from '@testing-library/react';
import App from './App';
test('renders learn react link', () => {
render(<App />);
const linkElement = screen.getByText(/learn react/i);
expect(linkElement).toBeInTheDocument();
});
App.test.js 파일에서 test, expect 함수는 Jest의 함수고, toBeInTheDocument는 jest-dom 라이브러리에 포함된 Custom matchers다.
Q, 하지만 아직 jest-dom을 import 한 적이 없는데?
A, jest-dom은 src/setupTests.js 파일 내에서 import했기 때문이다.
만약 setupTests.js에서 import 삭제하면 toBeInTheDocument 함수를 사용할 수 없다.
src/파일명.test.js or src/파일명.spec.js 생성toBe함수 : matchers 함수 중 하나로 expect 함수에 지정한 값이 toBe 함수에 지정한 값과 일치하는지 체크. npm run test하고 a를 선택하면 Example.test.js와 App.test.js가 모두 실행되고 PASS 출력// src/Example.test.js
test("1 더하기 1은 2", () => {
expect(1 + 1).toBe(2);
});
it함수로도 동일한 결과 출력// src/Example.test.js
it("1 더하기 1은 2", () => {
expect(1 + 1).toBe(2);
});
describe함수 : 하나의 파일에 it, test함수 여러개 포함가능// src/Example.test.js
describe("간단한 테스트", () => {
test("1 더하기 1은 2", () => {
expect(1 + 1).toBe(2);
});
it("2 더하기 2은 4", () => {
expect(2 + 2).toBe(4);
});
});
describe 함수 블록 - Test Suites라고 부름test/it 함수 블록 - Test(Test Case)라고 부름// Light.jsx
import { useState } from "react";
function Light({ name }) {
const [light, setLight] = useState(false);
return (
<div>
<h1>
{name} {light ? "ON" : "OFF"}{" "}
</h1>
<button onClick={() => setLight(true)} disabled={light ? true : false}>
ON
</button>
<button onClick={() => setLight(false)} disabled={!light ? true : false}>
OFF
</button>
</div>
);
}
export default Light;
npm start 해보기import "./App.css";
import Light from "./components/Light";
function App() {
return <Light name="스위치" />;
}
export default App;
// Light.test.js
import { render, screen } from '@testing-library/react';
import Light from './Light';
it('renders Light Component', () => {
render(<Light name="전원" />);
const nameElement = screen.getByText(/전원 off/i);
expect(nameElement).toBeInTheDocument();
})
// Light.test.js
import { fireEvent, render, screen } from "@testing-library/react";
import Light from "./Light";
describe("컴포넌트 테스트", () => {
it("renders Light Component", () => {
render(<Light name="전원" />);
const nameElement = screen.getByText(/전원 off/i);
expect(nameElement).toBeInTheDocument();
});
it("off button disabled", () => {
render(<Light name="전원" />);
const offButtonElement = screen.getByRole("button", { name: "OFF" });
expect(offButtonElement).toBeDisabled();
});
it("on button enable", () => {
render(<Light name="전원" />);
const onButtonElement = screen.getByRole("button", { name: "ON" });
expect(onButtonElement).not.toBeDisabled();
});
it("change from off to on", () => {
render(<Light name="전원" />);
const onButtonElement = screen.getByRole("button", { name: "ON" });
fireEvent.click(onButtonElement);
expect(onButtonElement).toBeDisabled();
});
});
getByText
props로 전달된 전원이 올바르게 표시되어 있는지 확인
getByRole
button을 지정하고, 버튼이 2개이므로 옵션의 name을 이용하여 OFF 버튼을 찾음. toBeDisabled로 OFF버튼이 disabled 상태인지 확인
expect(onButtonElement).not.toBeDisabled()
toBedisabled 함수 앞에 not을 붙여 ON 버튼이 disabled 안된 것을 테스트
fireEvent
버튼 click 등 이벤트 유무 테스트
click 메서드에 전달인자로 테스트할 요소 전달