tdd

스토리북과 크로마틱

스토리북

UI 개발 도구로 비즈니스 로직 및 컨텍스트에 간섭 없이 원하는 컴포넌트를 시나리오 별로 렌더링 할 수 있도록 도와주는 도구

스토리북을 사용하면 컴포넌트의 UI 렌더링 상태와 변경 사항을 확인하며 개발을 진행할 수 있다.

스토리를 기준으로 시각적 회귀 테스트를 실행할 수 있다.

스토리북은 각 테스트 케이스에 대한 정의가 어렵고 테스트 실패, 테스트 성공, 리팩토링 사이클을 거치는 TDD에 있어 명확한 테스트 도구라기 보다는 UI개발 도구에 가깝기 때문에 성공과 실패에 대한 피드백을 명확히 받기 어렵다.

또한 개발자가 직접 수동으로 UI 렌더링 상태를 스토리북에서 확인해야 하기 때문에 번거롭다.

TDD의 적용 여부와는 상관없이 스토리북은 컴포넌트 개발의 효율성과 정확성을 높여준다.

스토리북 실행시 필요한 설정은 .storybook 폴더 내부에 정의한다.

⭕ 스토리는 props만 받아 UI만 렌더링하는 컴포넌트들을 대상으로 작성하는 것이 좋다. 렌더링 결과를 빠르게 확인할 수 있기 때문에 UI 개발 시간이 굉장히 단축된다.

❌ 복잡한 비즈니스 로직이 있는 컴포넌트를 스토리로 작성할 경우 몇 가지 UI 확인을 위해 과한 모킹이 필요해지므로 스토리 작성에 적합하지 않다.

스토리 작성

스토리는 story.js 또는 story.ts 로 끝나는 파일에 작성하며 각 컴포넌트는 ES6 모듈 기반의 CSF(Component Story Format) 으로 작성

메타 데이터 이름이나 동작에 대한 정보를 설명 (default export 로 정의)

  • title : 스토리북 네이게이션 UI에 어떻게 노출될 지 계층을 나타낸다. 필수 값은 아니지만 다른 파일의 타이틀과 겹치지 않는 고유한 값이어야 한다.
  • component : 렌더링 할 컴포넌트 설정
  • argTypes : 사용자가 스토리의 컨트롤 스탭에서 값을 변경하며 상태를 확인할 수 있는 데이터에 대한 정보
export default {
  title: '홈/상품 카드',
  component: ProductCard,
  argTypes: {
    product: {
      control: 'object',
      description: '상품의 정보',
    },
  },
};

스토리 각각의 시나리오를 나타냄 (named export 로 정의)

  • name : 스토리의 이름 설정, 이 필드를 정의하면 스토리의 이름을 원하는 대로 변경할 수 있다. 만약 이 필드를 정의하지 않으면 자동으로 변수 명으로 설정된다.
  • args : 스토리의 다양한 형태의 값을 동적으로 변경하고 싶을 때 사용
export const Default = {
  name: '기본',
  args: {
    product,
  },
};

play 함수

스토리를 렌더링 한 뒤 사용자의 상호작용을 시뮬레이션 할 수 있도록 도와주는 함수

이 기능을 사용하기 위해서는 storybook/addon-interactions 라이브러리를 설치하고 storybook-addons 설정에 추가해야 한다.

play 함수를 사용하면 순차적으로 시뮬레이션 하면서 테스트를 진행할 수 있다.

export const WithValue = {
  name: '가격이 입력된 상태',
  play: async ({ canvasElement }) => {
		// canvasElement : 스토리가 렌더링되는 루트 요소
    const canvas = within(canvasElement);

    const [min, max] = canvas.getAllByRole('textbox');
		// 유저 이벤트를 사용해 필드에 값 입력하는 과정 시뮬레이션
    await userEvent.type(min, '300');
    await userEvent.type(max, '40000');
  },
};

🤔 크로마틱 (직접 써봐야 확실하게 이해할 수 있을듯)

스토리북 메인테이너들이 만든 시각적 회귀 테스트 도구

스토리북 팀에서 만들었기 때문에 스토리북과의 연동이 매우 편리하고 CI와 연동하기도 쉬운 편이다. 또한, 팀 작업을 하기 좋은 워크 플로우 환경을 제공한다.

Github 콜라보레이터는 자동으로 리뷰어로 지정된다. 별도의 리뷰어를 지정하고 싶다면 Assign Reviewers를 통해 지정할 수 있다.

사용 방법

크로마틱 홈페이지에서 토큰을 받아야 한다.

기본 설정을 마친 뒤 스토리들을 업로드하면 크로마틱 페이지에서 확인이 가능하다.

배포할 때는 반드시 변경사항을 커밋한 후에 배포를 진행해야 한다.

만약 의도한 변경이라면 Accept를 누르고, 의도하지 않은 변경이라면 원인을 찾아 코드를 수정하고 스냅샷이 업데이트 되지 않도록 Deny 버튼을 눌러야 한다.

Github Actions를 활용해 자동화

직접 CLI를 사용해 크로마틱을 실행하는 것 보다는 커밋이나 푸시가 발생할 때마다 자동으로 스토리북을 빌드

  1. 스토리북 작성
  2. 크로마틱 CI 연동
  3. UI 회귀 테스트 진행
  4. PR 승인 및 Merge
  5. 스토리북 배포
name: 'chromatic test'
on: pull_request
jobs:
  chromatic-deployment:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0
      - uses: actions/setup-node@v3
        with:
          node-version: 19
      - name: Install dependencies
        run: npm ci
      - name: Publish to Chromatic
        uses: chromaui/action@v1
        with:
          projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
          onlyChanged: true