DEV Community ๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘จโ€๐Ÿ’ป

Cover image for Testing select option with React Testing Library
leo
leo

Posted on

Testing select option with React Testing Library

์ด๋ฒˆ ๊ธ€์€ ์…€๋ ‰ํŠธ ๋ฐ•์Šค๋ฅผ react testing library๋ฅผ ํ†ตํ•ด์„œ ์–ด๋–ป๊ฒŒ ํ…Œ์ŠคํŠธํ•˜๋Š”์ง€์— ๋Œ€ํ•œ ํฌ์ŠคํŠธ๋‹ค.



react testing library๋Š” Semantic HTML์„ ์‚ฌ์šฉํ• ์ˆ˜๋ก ๋” ๊ฐ„ํŽธํ•˜๊ฒŒ query๋ฅผ ํ•  ์ˆ˜๊ฐ€ ์žˆ๋‹ค. ์•„๋ž˜์˜ Select ์ปดํฌ๋„ŒํŠธ ๊ฐ™์€ ๊ฒฝ์šฐ๋Š” semantic ํ•˜๊ฒŒ html์„ ์‚ฌ์šฉํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— label ํƒœ๊ทธ์™€ ๊ฐ™์ด ์‚ฌ์šฉ๋˜์—ˆ๋‹ค.

import { FC } from 'react';

const Select: FC = () => {
  return (
    <div>
      <label htmlFor="language-select">
        Choose a country
        <select id="language-select">
          <option value="">choose a country</option>
          <option value="ko">ํ•œ๊ตญ</option>
          <option value="usa">๋ฏธ๊ตญ</option>
        </select>
      </label>
    </div>
  );
};

export default Select;
Enter fullscreen mode Exit fullscreen mode
import React from 'react';
import { render, screen, userEvent } from '@test-utils';
import Select from './Select';

test('default option should be falsy when different option is selected', () => {
  render(<Select />);
  const selectElement = screen.getByRole('combobox', { name: 'Choose a country' });
  userEvent.selectOptions(selectElement, 'usa');
  const defaultOption = screen.getByRole('option', { name: 'choose a country' }) as HTMLOptionElement;
  const selectedOption = screen.getByRole('option', { name: '๋ฏธ๊ตญ' }) as HTMLOptionElement;
  expect(defaultOption.selected).toBeFalsy();
  expect(selectedOption.selected).toBeTruthy();
});
Enter fullscreen mode Exit fullscreen mode
์œ„์˜ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋Š” ์งง์ง€๋งŒ, step by step์œผ๋กœ ์ตœ๋Œ€ํ•œ ์ž์„ธํ•˜๊ฒŒ ์„ค๋ช…์„ ํ•ด๋ณด๊ฒ ๋‹ค.
  • ๋จผ์ € Select ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋ง์„ ์‹œ์ผœ์ค˜์•ผ ํ•œ๋‹ค. render๋ฅผ ํ†ตํ•ด์„œ ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ Œ๋”๋งํ–ˆ๋‹ค.
  • react testing library์˜ Query๋Š” ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์ข…๋ฅ˜๊ฐ€ ์žˆ๋Š”๋ฐ ๊ณต์‹ ํ™ˆํŽ˜์ด์ง€์—์„œ ์ •ํ•ด๋†“์€ ์šฐ์„ ์ˆœ์œ„๊ฐ€ ์žˆ๋‹ค.
  • ์šฐ์„ ์ˆœ์œ„์—์„œ 1์ˆœ์œ„์ธ getByRole ์ฟผ๋ฆฌ ๊ฐ™์€ ๊ฒฝ์šฐ๋Š” DOM์˜ Accessibility tree ์•ˆ์— ์žˆ๋Š” aria-role ์„ ํ†ตํ•ด์„œ DOM ์ ‘๊ทผ์„ ํ•œ ๋‹ค์Œ์— ํ•ด๋‹น ์—˜๋ ˆ๋ฉ˜ํŠธ๋ฅผ ๋ฐ˜ํ™˜์„ ํ•ด์ค€๋‹ค.
  • select ํƒœ๊ทธ์˜ role์€ listbox ๋˜๋Š” combobox๊ฐ€ ์ด๊ณ , multiple attribute๊ฐ€ ์‚ฌ์šฉ๋˜์ง€ ์•Š๊ณ , size attribute๊ฐ€ ์—†๊ฑฐ๋‚˜ ๋˜๋Š” ์‚ฌ์ด์ฆˆ๊ฐ€ 1๋ณด๋‹ค ํฌ์ง€ ์•Š์„ ๋•Œ์—๋Š” combobox๋กœ ๋ถ„๋ฅ˜๊ฐ€ ๋œ๋‹ค.
  • Select ์ปดํฌ๋„ŒํŠธ๋Š” ์—ฌ๋Ÿฌ ๊ฐœ์˜ select ํƒœ๊ทธ๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— getByRole ์˜ ๋‘ ๋ฒˆ์งธ ์ธ์ž์ธ option ๊ฐ์ฒด๋ฅผ ํ†ตํ•ด์„œ ๋‹ค์‹œ ์ฟผ๋ฆฌ๋ฅผ ํ•ด์ค„ ํ•„์š”๊ฐ€ ์—†๋‹ค. ํ•˜์ง€๋งŒ ๋งŒ์•ฝ์— ์ด ์ปดํฌ๋„ŒํŠธ ์•ˆ์—์„œ ์—ฌ๋Ÿฌ๊ฐœ์˜ select ํƒœ๊ทธ๊ฐ€ ์žˆ์œผ๋ฉด ์—๋Ÿฌ๊ฐ€ ๋‚˜๊ฒŒ ๋œ๋‹ค.
  • ์ด๋Ÿฌ๋ฉด ๋‘๋ฒˆ์งธ ์ธ์ž๋กœ ์˜ต์…˜ ๊ฐ์ฒด์˜ name ์†์„ฑ์„ ์ด์šฉํ•ด์„œ. ๋‹ค์‹œ ํ•œ ๋ฒˆ ๋” ์ฟผ๋ฆฌ๋ฅผ ํ•  ํ•„์š”์„ฑ์ด ์žˆ๋‹ค. ํ™”๋ฉด์— ํ‘œ์‹œ๋˜๋Š” ํ…์ŠคํŠธ๊ฐ€ ๋”์˜ Accessibility tree์˜ name(๋ ˆ์ด๋ธ” ํ…์ŠคํŠธ: Choose a country)์ด ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์˜ต์…˜๊ฐ์ฑ„์— name์†์„ฑ์„ ๋„ฃ์–ด์ค˜์„œ ์ฟผ๋ฆฌ๋ฅผ ํ•ด์ค€๋‹ค.
  • ๋งŒ์•ฝ์— semanticํ•œ html์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•˜์„ ๊ฒฝ์šฐ์—๋Š”(label์ด ์—†์ด select๋ฅผ ์‚ฌ์šฉํ•œ ๊ฒฝ์šฐ), aria-label attribute๋ฅผ select ํƒœ๊ทธ์— ์ถ”๊ฐ€ํ•ด์ฃผ๋ฉด name์œผ๋กœ query๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค. ๋‹ค๋งŒ aria-label์„ ํ™”๋ฉด์ƒ์— ๋ณด์ด๋Š” label์ด ์—†๋Š” ๊ฒฝ์šฐ์—๋งŒ ์‚ฌ์šฉ์„ ๊ถŒ์žฅํ•˜๊ณ  ๋˜ํ•œ Accessibility Tree์˜ name์„ ๋ฎ์–ด์”Œ์šธ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ฌด์กฐ๊ฑด ์‚ฌ์šฉํ•ด์„œ๋Š” ์•ˆ ๋œ๋‹ค.
  • ์ด์ œ ํ•ด๋‹น Select ์ปดํฌ๋„ŒํŠธ์˜ value๋ฅผ ๋ฐ”๋€Œ๊ธฐ ์œ„ํ•ด์„œ ์ด๋ฒคํŠธ๋ฅผ ์‹คํ–‰ํ•ด๋ณด์•„์•ผ ํ•˜๋Š”๋ฐ, ๊ณต์‹ ํ™ˆํŽ˜์ด์ง€์—์„œ fireEvent ๋ณด๋‹ค๋Š” userEvent ์‚ฌ์šฉ์„ ๊ถŒ์žฅํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— userEvent๋ฅผ ์‚ฌ์šฉํ•ด์„œ select์˜ value๋ฅผ usa๋กœ ๋ฐ”๊ฟ”์ฃผ์—ˆ๋‹ค.
  • ๋‹ค์Œ ๋‹จ๊ณ„๋Š” getByRole์˜ ์ธ์ž๋กœ option์„ ๋„ฃ์–ด์ค˜์„œ ์ฟผ๋ฆฌ๋ฅผ ํ•ด์ค€๋‹ค. option์—˜๋ ˆ๋ฉ˜ํŠธ์˜ role์€ option์ด๋‹ค. option ํƒœ๊ทธ ๋˜ํ•œ ์—ฌ๋Ÿฌ๊ฐœ๊ธฐ ๋•Œ๋ฌธ์— ์˜ต์…˜๊ฐ์ฒด์— name์„ ์ด์šฉํ•ด์„œ ์ฟผ๋ฆฌ๋ฅผ ํ–ˆ๋‹ค. ๋‹ค๋งŒ get์ฟผ๋ฆฌ ๊ฐ™์€ ๊ฒฝ์šฐ๋Š” ํ•ญ์ƒ ํƒ€์ž…์„ HTMLElement๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ๋•Œ๋ฌธ์— selected๋ผ๋Š” ์†์„ฑ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— ํƒ€์ž… assertion์„ ํ†ตํ•ด์„œ HTMLOptionElement๋ฅผ ๋ฐ˜ํ™˜์„ ํ–ˆ๋‹ค.
  • ์ž ์ด์ œ ๋งˆ์ง€๋ง‰์œผ๋กœ ์ฒ˜์Œ์— ์„ ํƒ์ด ๋ผ ์žˆ๋˜ defaultOption์˜ selected ์†์„ฑ์ด falsy์ธ๊ฒŒ ํ™•์ธ์ด ๋๊ณ , ์ƒˆ๋กœ ์„ ํƒ์ด ๋œselectedOption์˜ selected ์†์„ฑ์ด truthy์ธ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

Top comments (0)

๐ŸŒš Life is too short to browse without dark mode