• 코드리뷰
  • 블로그
  • 로그인

한 번에 너무 많은 테스트 케이스를 생각하며 테스트와 코드를 구현하고 있을 때

테스트를 작성할 때는 모든게 올바르게 동작하는 경우인 Happy path를 먼저 작성하고 난 후 나머지 다른 예외 케이스를 단계적으로 구현하는 것이 좋습니다.
한윤석

문제

하나의 작업을 할 때는 하나의 기능에만 집중을 해야하는데, 여러가지 경우의 테스트를 동시에 작성하고 있다.

예시

describe('Restaurants', () => {
  // 레스토랑이 비어있을 때
  context('when restaurants is empty', () => {
    it('renders empty message', () => {
    });
  });

  // 레스토랑이 존재할 때
  context('when restaurants is exists', () => {
    it('renders restaurants', () => {
    });
  });

  // 레스토랑을 불러오지 못했을 때
  context('when fethcing restaurants fail', () => {
    it('renders error message', () => {
    });
  });
  // ... 기타 등등
});

답변

테스트를 작성할 때는 모든 게 올바르게 동작하는 경우인 Happy path를 먼저 작성하고 난 후 나머지 다른 예외 케이스를 단계적으로 구현하는 것이 좋습니다. 왜냐하면 처음부터 너무 많은 기능을 생각하거나 이것저것 예외 케이스를 생각하다 보면 복잡성에 압도당하여 코딩을 시작하기 어렵게 됩니다.

먼저 모든게 올바르게 동작하는 경우를 테스트를 작성합니다.

describe('Restaurants', () => {
  it('renders restaurants', () => {
    const { container } = render(<Restaurants restaurants={restaurants} />);

    expect(container).toHaveTextContent('마녀주방');
    expect(container).toHaveTextContent('한식');
    expect(container).toHaveTextContent('강남');
  });
});

그다음에 만약에 레스토랑 목록이 비어있으면 어떻게 되지? 만약에 레스토랑 목록 중에 카테고리가 입력이 안 돼있는 경우에는 어떡하지? 같은 경우가 생각이 날 수 있습니다. 현재는 어떻게 동작하는지 정의되어 있지 않습니다. 따라서 테스트를 작성하여 정의 내릴 수 있습니다.

describe('Restaurants', () => {
  context('with restaurants', () => {
    const restaurants = [
      { id: 1, name: '마녀주방', category: '한식', address: '강남' },
    ];

    it('renders restaurants', () => {
      const { container } = render(<Restaurants restaurants={restaurants} />);

      expect(container).toHaveTextContent('마녀주방');
      expect(container).toHaveTextContent('한식');
      expect(container).toHaveTextContent('강남');
    });
  });

  context('when restaurants is empty', () => {
    const restaurants = [];

    it('renders empty message', () => {
      const { container } = render(<Restaurants restaurants={restaurants} />);

      expect(container).toHaveTextContent('레스토랑이 없습니다.');
    });
  });
  
  // TODO
  context('when restaurants is null', () => {
    it('renders empty message', () => {
      // ...
    });
  });
});

그러면 테스트가 실패할 것이고 이 테스트가 통과하도록 기능을 구현하면 됩니다. 그래서 테스트가 스펙이 되고, 살아있는 문서가 됩니다.

테스트, TDD, 코드리뷰, 올바른 협업 방법 등을 코칭하여 코드숨은 개인과 개발 조직의 성장을 돕고 있습니다. 🙏진짜 개발자로 거듭나는 방법
강의 알아보기