2. React Testing Library

React Testing Library

๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉ์ž ์ž…์žฅ์— ๊ฐ€๊น๊ฒŒ ํ…Œ์ŠคํŠธ ํ•  ์ˆ˜ ์žˆ๋Š” ๋„๊ตฌ

  • Implementation Driven Test(๊ตฌํ˜„ ์ฃผ๋„ ํ…Œ์ŠคํŠธ) : ์ฃผ๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€์— ๋Œ€ํ•ด ์ดˆ์ ์„ ๋‘์–ด ํ…Œ์ŠคํŠธ ์ž‘์„ฑ

  • Behavior Driven Test(ํ–‰์œ„ ์ฃผ๋„ ํ…Œ์ŠคํŠธ) : ์‚ฌ์šฉ์ž๊ฐ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ด์šฉํ•˜๋Š” ๊ด€์ ์—์„œ ์‚ฌ์šฉ์ž์˜ ์‹ค์ œ ๊ฒฝํ—˜ ์œ„์ฃผ๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑ

  • React Testing Library๋Š” Behavior Driven Test ๋ฐฉ๋ฒ•๋ก ์„ ๋”ฐ๋ฅด๋Š” ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•˜๋Š”๋ฐ ์ ํ•ฉ

  • jsdom์ด๋ผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ†ตํ•ด ์‹ค์ œ ๋ธŒ๋ผ์šฐ์ € DOM์„ ๊ธฐ์ค€์œผ๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ ๋•Œ๋ฌธ

  • ์–ด๋–ค React ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š”์ง€๋ณด๋‹ค, ์‚ฌ์šฉ์ž ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋ Œ๋”๋งํ•˜๋Š” ์‹ค์ œ HTML ๋งˆํฌ์—…์˜ ๋ชจ์Šต์ด ์–ด๋–ค์ง€์— ๋Œ€ํ•ด์„œ ํ…Œ์ŠคํŠธํ•˜๊ธฐ ์šฉ์ด

  • Enzyme์ด๋ผ๋Š” ํ…Œ์ŠคํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ๋ฆฌ์•กํŠธ VDOM์„ ๊ธฐ์ค€์œผ๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•˜์—ฌ Implementation Driven Test ๋ฐฉ๋ฒ•๋ก ์„ ๋”ฐ๋ฆ„

React Testing Library ์ฃผ์š” API

  • render() ํ•จ์ˆ˜ : DOM์— ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋ง

  • fireEvent ๊ฐ์ฒด : ํŠน์ • ์ด๋ฒคํŠธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ด

  • ์ฟผ๋ฆฌํ•จ์ˆ˜ : DOM์—์„œ ํŠน์ • ์˜์—ญ์„ ์„ ํƒ

render() ํ•จ์ˆ˜

  • @testing-library/react ๋ชจ๋“ˆ๋กœ๋ถ€ํ„ฐ ๋ฐ”๋กœ ์ž„ํฌํŠธ ๊ฐ€๋Šฅ

  • ์ธ์ž๋กœ ๋ Œ๋”๋งํ•  React ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋„˜๊น€

  • React Testing Library์‚ฌ ์ œ๊ณตํ•˜๋Š” ๋ชจ๋“  ์ฟผ๋ฆฌํ•จ์ˆ˜์™€ ๊ธฐํƒ€ ์œ ํ‹ธ๋ฆฌํ‹ฐ ํ•จ์ˆ˜๋ฅผ ๋‹ด๊ณ  ์žˆ๋Š” ๊ฐ์ฒด๋ฅผ ๋ฆฌํ„ดํ•˜๋ฏ€๋กœ destructuring ๋ฌธ๋ฒ•์œผ๋กœ render() ํ•จ์ˆ˜๊ฐ€ ๋ฆฌํ„ดํ•œ ๊ฐ์ฒด๋กœ๋ถ€ํ„ฐ ์›ํ•˜๋Š” ์ฟผ๋ฆฌํ•จ์ˆ˜๋งŒ ์–ป์–ด์˜ฌ ์ˆ˜ ์žˆ์Œ

์ฟผ๋ฆฌํ•จ์ˆ˜

  • ๋ Œ๋”๋ง๋œ DOM๋…ธ๋“œ์— ์ ‘๊ทผํ•˜์—ฌ ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋ฉ”์„œ๋“œ

  • ์ฟผ๋ฆฌ ํƒ€์ž…/ํƒ€๊ฒŸ ๊ฐœ์ˆ˜/ํƒ€๊ฒŸ ์œ ํ˜•์œผ๋กœ ๊ตฌ์„ฑ ex) get``All``ByRole

์ฟผ๋ฆฌํƒ€์ž…

  • get : ๋™๊ธฐ์ ์œผ๋กœ ์ฒ˜๋ฆฌ๋˜๋ฉฐ ํƒ€๊ฒŸ์„ ์ฐพ์ง€๋ชปํ• ์‹œ ์—๋Ÿฌ๋ฅผ ๋˜์ง

  • find : ๋น„๋™๊ธฐ์ ์œผ๋กœ ์ฒ˜๋ฆฌ๋˜๋ฉฐ ํƒ€๊ฒŸ์„ ์ฐพ์ง€ ๋ชปํ• ์‹œ ์—๋Ÿฌ๋ฅผ ๋˜์ง

  • query : ๋™๊ธฐ์ ์œผ๋กœ ์ฒ˜๋ฆฌ๋˜๋ฉฐ ํƒ€๊ฒŸ์„ ์ฐพ์ง€ ๋ชปํ• ์‹œ null์„ ๋ฐ˜ํ™˜

ํƒ€๊ฒŸ์˜ ๊ฐœ์ˆ˜

  • ๋‹ค์ˆ˜์˜ ์—˜๋ฆฌ๋จผํŠธ๊ฐ€ ํƒ์ƒ‰๋˜๋Š” ์ƒํ™ฉ์ด๋ผ๋ฉด ๋’ค์— All์„ ๋ถ™์ž„

ํƒ€๊ฒŸ ์œ ํ˜•

  • ByRole, ByLabelText, ByPlaceholderText, ByText, ByDisplayValue, ByAltText, ByTitle, ByTestId

์ •์  ์ปดํฌ๋„ŒํŠธ ํ…Œ์ŠคํŒ…

Page Not Found ์ปดํฌ๋„ŒํŠธ ์˜ˆ์ œ

import React from "react";

function NotFound({ path }) {
  return (
    <>
      <h2>Page Not Found</h2>
      <p>ํ•ด๋‹น ํŽ˜์ด์ง€({path})๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.</p>
      <img
        alt="404"
        src="https://media.giphy.com/media/14uQ3cOFteDaU/giphy.gif"
      />
    </>
  );
}

h2๊ฐ€ ๋ Œ๋”๋ง ๋˜๊ณ  ์žˆ๋Š”์ง€ ๊ฒ€์ฆ

import React from "react";
import { render } from "@testing-library/react";
import NotFound from "./NotFound";

describe("<NotFound />", () => {
  it("renders header", () => {
    const { getByText } = render(<NotFound path="/abc" />);
    const header = getByText("Page Not Found");
    expect(header).toBeInTheDocument();
  });
});
  1. <NotFound /> ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ž„ํฌํŠธํ•ด์„œ render()์˜ ์ธ์ž๋กœ ๋„˜๊ธด ํ›„์— ๋ฆฌํ„ด ๊ฐ์ฒด๋กœ๋ถ€ํ„ฐ getByText() ํ•จ์ˆ˜๋ฅผ ์–ป์Œ

  2. ํ™”๋ฉด์—์„œ ๊ฒ€์ƒ‰ํ•  ํ…์ŠคํŠธ์ธ Page Not Found๋ฅผ getByText()์— ์ธ์ž๋กœ ๋„˜๊ฒจ <h2/> ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ์–ป์Œ

  3. jest-dom์˜ toBeInTheDocument() matcher ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด์„œ ํ•ด๋‹น <h2/> ์—˜๋ฆฌ๋จผํŠธ๊ฐ€ ํ™”๋ฉด์— ์กด์žฌํ•˜๋Š” ๊ฒ€์ฆ

p๊ฐ€ ๋ Œ๋”๋ง ๋˜๊ณ  ์žˆ๋Š”์ง€ ๊ฒ€์ฆ

it("renders paragraph", () => {
  const { getByText } = render(<NotFound path="/abc" />);
  const paragraph = getByText(/^ํ•ด๋‹น ํŽ˜์ด์ง€/);
  expect(paragraph).toHaveTextContent("ํ•ด๋‹น ํŽ˜์ด์ง€(/abc)๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.");
});
  1. ์ •๊ทœ์‹์œผ๋กœ <p/>์•ˆ์˜ ํ…์ŠคํŠธ๊ฐ€ ํฌํ•จ๋œ ์š”์†Œ๋ฅผ ๊ฐ€์ ธ์˜ด

  2. ๊ฐ€์ ธ์˜จ ์š”์†Œ์˜ ํ…์ŠคํŠธ๊ฐ€ ์˜ˆ์ƒ๊ณผ ์ผ์น˜ํ•˜๋Š”์ง€ ๊ฒ€์ฆ

img๊ฐ€ ๋ Œ๋”๋ง ๋˜๊ณ  ์žˆ๋Š”์ง€ ๊ฒ€์ฆ

it("renders image", () => {
  const { getByAltText } = render(<NotFound path="/abc" />);
  const image = getByAltText("404");
  expect(image).toHaveAttribute(
    "src",
    "https://media.giphy.com/media/14uQ3cOFteDaU/giphy.gif"
  );
});
  1. ์ด๋ฏธ์ง€ ํƒœ๊ทธ๋Š” ํ…์ŠคํŠธ๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— alt์†์„ฑ๊ฐ’์„ ์ด์šฉ

  2. jest-dom์˜ toHaveAttribute() matcher ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด์„œ <img/> ์—˜๋ฆฌ๋จผํŠธ์˜ src ์†์„ฑ๊ฐ’์ด ์ •ํ™•ํ•œ์ง€ ๊ฒ€์ฆ

๋™์  ์ปดํฌ๋„ŒํŠธ ํ…Œ์ŠคํŒ…

๋‚ด๋ถ€ ์ƒํƒœ์— ๋”ฐ๋ผ UI์— ๋ณ€ํ™”๊ฐ€ ์ƒ๊ธธ ์ˆ˜ ์žˆ๋Š” ์ปดํฌ๋„ŒํŠธ ํ…Œ์ŠคํŠธ

import React, { useState } from "react";

function LoginForm({ onSubmit }) {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");

  return (
    <>
      <h2>Login</h2>
      <form onSubmit={onSubmit}>
        <label>
          ์ด๋ฉ”์ผ
          <input
            type="email"
            placeholder="user@test.com"
            value={email}
            onChange={({ target: { value } }) => setEmail(value)}
          />
        </label>
        <label>
          ๋น„๋ฐ€๋ฒˆํ˜ธ
          <input
            type="password"
            value={password}
            onChange={({ target: { value } }) => setPassword(value)}
          />
        </label>
        <button disabled={!email || !password}>๋กœ๊ทธ์ธ</button>
      </form>
    </>
  );
}

์ด๋ฉ”์ผ๊ณผ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•ด์•ผ ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ์ด ํ™œ์„ฑํ™” ๋˜๋Š” ์˜ˆ์ œ

import React from "react";
import { render, fireEvent } from "@testing-library/react";
import LoginForm from "./LoginForm";

describe("<LoginForm />", () => {
  it("enables button when both email and password are entered", () => {
    const { getByText, getByLabelText } = render(
      <LoginForm onSubmit={() => null} />
    );

    const button = getByText("๋กœ๊ทธ์ธ");
    const email = getByLabelText("์ด๋ฉ”์ผ");
    const password = getByLabelText("๋น„๋ฐ€๋ฒˆํ˜ธ");

    expect(button).toBeDisabled();

    fireEvent.change(email, { target: { value: "user@test.com" } });
    fireEvent.change(password, { target: { value: "Test1234" } });

    expect(button).toBeEnabled();
  });
});
  1. ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ์˜ ๊ฒฝ์šฐ์—๋Š” getByText() ์ฟผ๋ฆฌ ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ์„ ํƒํ•˜๊ณ , ์ด๋ฉ”์ผ๊ณผ ๋น„๋ฐ€๋ฒˆํ˜ธ ์ž…๋ ฅ์นธ์€ getByLabelText() ์ฟผ๋ฆฌ ํ•จ์ˆ˜๋กœ ์„ ํƒ

  2. jest-dom์˜ toBeDisabled()์™€ toBeEnabled() matcher ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด์„œ ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ์˜ ํ™œ์„ฑํ™” ์—ฌ๋ถ€๋ฅผ ์ด๋ฒคํŠธ ๋ฐœ์ƒ ์ „ํ›„๋กœ ๊ฒ€์ฆ

  3. ๋‘ ๊ฐœ์˜ ์ž…๋ ฅ์นธ์— change ์ด๋ฒคํŠธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๊ธฐ ์œ„ํ•ด์„œ fireEvent.change() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉ

๋กœ๊ทธ์ธ ๋ฒ„ํŠผ์„ ํด๋ฆญํ–ˆ์„๋•Œ prop์œผ๋กœ ๋„˜๊ธด onSubmit ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜๋Š”์ง€ ๊ฒ€์ฆ

it("submits form when buttion is clicked", () => {
  const obSubmit = jest.fn();
  const { getByText, getByLabelText } = render(
    <LoginForm onSubmit={obSubmit} />
  );

  const button = getByText("๋กœ๊ทธ์ธ");
  const email = getByLabelText("์ด๋ฉ”์ผ");
  const password = getByLabelText("๋น„๋ฐ€๋ฒˆํ˜ธ");

  fireEvent.change(email, { target: { value: "user@test.com" } });
  fireEvent.change(password, { target: { value: "Test1234" } });

  fireEvent.click(button);

  expect(obSubmit).toHaveBeenCalledTimes(1);
});

Mocking

์œ„์˜ ์˜ˆ์ œ์—์„œ onSubmit์— ์ „๋‹ฌํ•  ํ•จ์ˆ˜๋ฅผ jest.fn()์„ ์ด์šฉํ•ด์„œ ๋งŒ๋“ค์—ˆ์Œ

mocking: ๋‹จ์œ„ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•  ๋•Œ ํ•ด๋‹น ์ฝ”๋“œ๊ฐ€ ์˜์กดํ•˜๋Š” ๋ถ€๋ถ„์„ ๊ฐ€์งœ(mock)๋กœ ๋Œ€์ฒดํ•˜๋Š” ๊ธฐ๋ฒ•

jest.fn()

jest.fn() ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด ๊ฐ€์งœ ํ•จ์ˆ˜๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Œ

์ผ๋ฐ˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ•จ์ˆ˜์™€ ๋™์ผํ•œ ๋ฐฉ์‹์œผ๋กœ ์ธ์ž๋ฅผ ๋„˜๊ฒจ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Œ

const mockFn = jest.fn();
mockFn();
mockFn(1);
mockFn("a");
mockFn([1, 2], { a: "b" });

mockReturnValue(๋ฆฌํ„ด๊ฐ’) ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด์„œ ์–ด๋–ค ๊ฐ’์„ ๋ฆฌํ„ดํ•ด์•ผํ• ์ง€ ์ •ํ•ด์ค„ ์ˆ˜ ์žˆ์Œ

mockFn.mockReturnValue("I am a mock!");
console.log(mockFn()); // I am a mock!

mockResolvedValue(Promise๊ฐ€ resolveํ•˜๋Š” ๊ฐ’) ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด์„œ ๊ฐ€์งœ ๋น„๋™๊ธฐ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Œ

mockFn.mockResolvedValue("I will be a mock!");
mockFn().then((result) => {
  console.log(result); // I will be a mock!
});

mockImplementation(๊ตฌํ˜„ ์ฝ”๋“œ) ํ•จ์ˆ˜๋กœ ์žฌ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Œ

mockFn.mockImplementation((name) => `I am ${name}!`);
console.log(mockFn("Dale")); // I am Dale!

๊ฐ€์งœํ•จ์ˆ˜์šฉ Jest Matcher์ธ toBeCalled*** ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด์„œ ๊ฐ€์งœํ•จ์ˆ˜๊ฐ€ ๋ช‡๋ฒˆ ํ˜ธ์ถœ๋˜์—ˆ๊ณ  ์ธ์ž๋กœ ๋ฌด์—‡์ด ๋„˜์–ด์™”์—ˆ๋Š”์ง€๋ฅผ ๊ฒ€์ฆํ•  ์ˆ˜ ์žˆ์Œ

mockFn("a");
mockFn(["b", "c"]);

expect(mockFn).toBeCalledTimes(2);
expect(mockFn).toBeCalledWith("a");
expect(mockFn).toBeCalledWith(["b", "c"]);

jest.spyOn()

์–ด๋–ค ๊ฐ์ฒด์— ์†ํ•œ ํ•จ์ˆ˜์˜ ๊ตฌํ˜„์„ ๊ฐ€์งœ๋กœ ๋Œ€์ฒดํ•˜์ง€ ์•Š๊ณ , ํ•ด๋‹น ํ•จ์ˆ˜์˜ ํ˜ธ์ถœ์—ฌ๋ถ€์™€ ์–ด๋–ป๊ฒŒ ํ˜ธ์ถœ๋˜์—ˆ๋Š”์ง€๋งŒ์„ ์•Œ์•„๋‚ด์•ผํ•˜๋Š” ๊ฒฝ์šฐ

const calculator = {
  add: (a, b) => a + b,
};

const spyFn = jest.spyOn(calculator, "add");

const result = calculator.add(2, 3);

expect(spyFn).toBeCalledTimes(1);
expect(spyFn).toBeCalledWith(2, 3);
expect(result).toBe(5);

Given - When - Then

BDD

  • Behavior Driven Development

  • ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ…Œ์Šค๋ฅด ์ผ€์ด์Šค๋ฅผ ์ž‘์„ฑํ•˜๋ฉฐ ํ•จ์ˆ˜๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ๊ถŒ์žฅํ•˜์ง€ ์•Š์Œ

  • Given - When - Then ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง€๋Š” ๊ฒƒ์„ ๊ถŒ์žฅ

Given - When - Then ํŒจํ„ด

  • Given : ํ…Œ์ŠคํŠธ ์ƒํƒœ๋ฅผ ์„ค๋ช…

  • When : ๊ตฌ์ฒดํ™”ํ•˜๊ณ ์ž ํ•˜๋Š” ํ–‰๋™

  • Then : ์˜ˆ์ƒ๋˜๋Š” ๋ณ€ํ™”

๊ธฐ๋Šฅ : ์‚ฌ์šฉ์ž ์ฃผ์‹ ํŠธ๋ ˆ์ด๋“œ

์‹œ๋‚˜๋ฆฌ์˜ค : ํŠธ๋ ˆ์ด๋“œ๊ฐ€ ๋งˆ๊ฐ๋˜๊ธฐ ์ „์— ์‚ฌ์šฉ์ž๊ฐ€ ํŒ๋งค๋ฅผ ์š”์ฒญ

"Given" ๋‚˜๋Š” MSFT ์ฃผ์‹์„ 100๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.
        ๊ทธ๋ฆฌ๊ณ  ๋‚˜๋Š” APPL ์ฃผ์‹์„ 150๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.
        ๊ทธ๋ฆฌ๊ณ  ์‹œ๊ฐ„์€ ํŠธ๋ ˆ์ด๋“œ๊ฐ€ ์ข…๋ฃŒ๋˜๊ธฐ ์ „์ด๋‹ค.

"When"  ๋‚˜๋Š” MSFT ์ฃผ์‹ 20์„ ํŒ”๋„๋ก ์š”์ฒญํ–ˆ๋‹ค.

"Then"  ๋‚˜๋Š” MSFT ์ฃผ์‹ 80 ๊ฐ€์ง€๊ณ  ์žˆ์–ด์•ผ ํ•œ๋‹ค.
        ๊ทธ๋ฆฌ๊ณ  ๋‚˜๋Š” APPL ์ฃผ์‹ 150์„ ๊ฐ€์ง€๊ณ  ์žˆ์–ด์•ผ ํ•œ๋‹ค.
        ๊ทธ๋ฆฌ๊ณ  MSFT ์ฃผ์‹ 20์ด ํŒ๋งค ์š”์ฒญ์ด ์‹คํ–‰๋˜์—ˆ์–ด์•ผ ํ•œ๋‹ค.

Test fixture

  • ํ…Œ์ŠคํŠธ ์‹คํ–‰์„ ์œ„ํ•ด ๋ฒ ์ด์Šค๋ผ์ธ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ๊ฐ์ฒด๋“ค์˜ ๊ณ ์ •๋œ ์ƒํƒœ

  • ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜๋ณต๊ฐ€๋Šฅํ•  ์ˆ˜ ์žˆ๊ณ  ๊ณ ์ •๋œ ํ™˜๊ฒฝ์—์„œ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋จ

  • ์ค‘๋ณต ๋ฐœ์ƒ๋˜๋Š” ํ–‰์œ„๋ฅผ ๊ณ ์ •์‹œ์ผœ ํ•œ๊ณณ์—์„œ ๊ด€๋ฆฌ

  • jest beforeEach๋ฅผ ํ†ตํ•ด ํ•ด๋‹น ํŒŒ์ผ ํ˜น์€ ํด๋ž˜์Šค ๋‚ด๋ถ€์˜ ํ•จ์ˆ˜๋“ค์ด ์‹œ์ž‘ํ•˜๊ธฐ ์ „์— ํ•ญ์ƒ ์ˆ˜ํ–‰ํ•  ์ผ์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Œ(afterEach๋Š” ๊ฐ ํ•จ์ˆ˜ ์‹คํ–‰ ํ›„์—)

  • beforeAll(), afterAll()์€ ๊ฐ๊ฐ ํ•จ์ˆ˜์˜ ์ „ ํ›„์— ๋งค๋ฒˆ ํ˜ธ์ถœ๋˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๋งจ ์ฒ˜์Œ๊ณผ ๋งจ ๋์— ๋”ฑ ํ•œ ๋ฒˆ์”ฉ๋งŒ ํ˜ธ์ถœ๋จ

Last updated