인프런 커뮤니티 질문&답변

디건버님의 프로필 이미지
디건버

작성한 질문수

실무에 바로 적용하는 프런트엔드 테스트 - 1부. 테스트 기초: 단위・통합 테스트

2.1. 단위 테스트란 무엇일까?

toHaveClass 테스트코드 관련하여 질문 남깁니다!

해결된 질문

작성

·

299

0

안녕하세요 현재 섹션2 관련하여 강의 듣고 있는 수강생입니다.

 

다름이 아니오라, 현재 강의에선 순수 css를 통해 클래스명 테스트 코드를 작성해주셨는데요..!

 

만약에 css 모듈이나, vanilla-extract 같이 클래스명이 동적으로 생성되는 경우에는 어떤식으로 테스트 코드를 작성해야할까요 ?

 

예전에 혼자서 vanilla-extract 관련해서 테스트 코드를 작성해보려고 했던적이 있는데, 단순히 toHaveClass로만 하려고하니까, 클래스명이 동적으로 결정이 되어서 에러가 계속 발생하더라구요..! (예를 들어서 클래스명이 header라면, headerhnfgbvds341 이런식)

 

강의 너무 잘 듣고 있습니다! 읽어주셔서 감사합니다.

 

import React from "react";
import { render, screen } from "@testing-library/react";
import TestComponent from "@/components/TestComponent";
import { testContainer } from "@/components/testComponent.css";

describe("Example Component Test", () => {
  test("클래스명에 대한 테스트", () => {
    render(<TestComponent />);
    const exampleElement = screen.getByText("TestComponent");

    expect(exampleElement).toHaveClass(testContainer);
  });
});
```

답변 2

1

코드 조커, 오프님의 프로필 이미지
코드 조커, 오프
지식공유자

안녕하세요 디건버님~!

우선 css modules 처럼 동적인 해시값에 의해 className이 변경되는 경우에는 vitest의 css.modules.classNameStrategy 설정을 통해 테스트 환경에서 css에 해시값이 추가되지 않도록 할 수 있습니다.

(jest의 경우 https://github.com/keyz/identity-obj-proxy 라이브러리를 사용하면 문제를 해결할 수 있습니다.)

// 예제의 vite.config.js
export default defineConfig({
  plugins: [react(), eslint({ exclude: ['/virtual:/**', 'node_modules/**'] })],
  test: {
    // ...
    setupFiles: './src/utils/test/setupTests.js',
    // 아래 옵션 추가
    css: {
      modules: {
        classNameStrategy: 'non-scoped',
      },
    },
  },
  resolve: {
    alias: [{ find: '@', replacement: path.resolve(__dirname, 'src') }],
  },
});

// jest.config.js
module.exports = {
  // ...
  moduleNameMapper: {
    "\\.(css)$": "identity-obj-proxy",
    ...
  },
};

export default class App extends Component {
  render() {
    return (
      <div className={styles.root}>
        <h1 className={styles.hello}>Hello, world!</h1>
      </div>
    );
  }
}

// 위의 설정을 적용하면 아래처럼 해시값없이 키값만 기준으로 className이 생성됩니다.
exports[`test App renders correctly 1`] = `
<div
  className="root">
  <h1
    className="hello">
    Hello, world!
  </h1>
</div>
`;

테스트에서는 로직의 흐름에 따라 className이 올바르게 변경되는 것인지 검증하는 것이 목적입니다. 따라서 동적인 스타일 해시값까지는 굳이 검증할 필요가 없는대요.

다행히 테스트 도구들의 설정을 통해 해시값 설정을 제거하고 className이 적절하게 변경되는지 명확하게 검증할 수 있습니다.

이외에도 AI가 답변해준 것처럼 toHaveClass 매처에 정규 표현식을 사용하여 검증하는 방법도 있지만 번거로움이 있기 때문에 설정을 통해 컴포넌트의 테스트 코드를 좀 더 깔끔하게 관리하는 것이 좋을 것 같습니다..!

제가 vanila-extract는 직접 사용해보지는 않았지만 공식 문서에 위에서 이야기한 설정에 대한 가이드가 있으니 이 부분을 참고하시면 문제없이 동작하지 않을까 합니다.

혹시 추가적인 문의 사항이나 이슈가 있다면 얼마든디 편하게 답글 남겨주세요.

감사합니다! 😃

디건버님의 프로필 이미지
디건버
질문자

답변 정말 감사드립니다 🙂

 

강의 정말 잘듣고 있습니다!

1

안녕하세요, 인프런 AI 인턴입니다. 디건버님.

강의 내용 중 CSS 모듈이나, 동적으로 생성되는 클래스명을 테스트하는 방법에 대한 질문에 대해 도움을 드리고자 합니다. 질문하신 내용은 테스트 코드 작성 시 CSS 모듈이나 동적으로 생성되는 클래스명을 어떻게 처리해야 하는지에 대한 것으로 이해했습니다.

동적으로 생성되는 클래스명을 가지는 컴포넌트를 테스트할 때 toHaveClass를 사용하는 방법에 어려움을 겪고 계신 것 같습니다. 이와 관련해 유용한 정보를 찾았습니다:

  • 2.4장 마지막 border 스타일 검증 시 질문
    • 이 질문은 테스트 코드 작성 시 스타일 속성을 검증하는 방법에 대한 것입니다. 대상 질문과는 다른 맥락일 수 있으나, toHaveStyle과 같은 다른 조회 기능을 활용하는 방법에 대한 아이디어를 얻을 수 있습니다.

CSS 모듈이나 vanilla-extract를 사용하는 경우, 생성되는 클래스명이 동적이기 때문에 직접 클래스 이름을 비교하는 것이 아닌 다른 방식으로 접근하는 것이 필요합니다. 예제 코드에서 toHaveClass(testContainer)와 같이 사용할 경우, testContainer가 실제 DOM에 렌더링된 클래스명과 매칭되어야 합니다.

동적 클래스명을 처리하기 위한 몇 가지 접근 방법은 다음과 같습니다:

  1. 클래스명이 아닌 다른 속성으로 요소를 검증하는 방법을 고려합니다.: 예를 들어, 특정 역할(role)이나 텍스트 내용 등을 통해 요소가 정상적으로 렌더링되었는지 검증합니다.

  2. 정규표현식을 사용하여 클래스명 검증하기: 만약 CSS 모듈 사용 시 클래스명에 일정한 패턴이 있다면 (예: header로 시작한다), 해당 패턴을 정규표현식으로 표현하여 expect 검증 시 사용할 수 있습니다. 단, toHaveClass 메서드가 정규표현식을 직접 지원하지는 않으므로 다른 방법을 찾아보아야 합니다.

  3. 스타일이나 다른 가시적인 결과로 검증하기: 동적으로 생성된 클래스명 대신, 그 클래스명으로 인해 적용되는 스타일이나 가시적인 변화를 바탕으로 테스트를 진행합니다. 예를 들어, 특정 클래스가 적용되었을 때의 스타일 변화를 toHaveStyle을 사용하여 검증할 수 있습니다.

현재 위의 내용과 직접적으로 일치하는 자료를 제공하기 어려우니, 이와 유사한 주제를 다루는 더 많은 자료와 커뮤니티의 도움을 받아보시길 권장 드립니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

디건버님의 프로필 이미지
디건버

작성한 질문수

질문하기