Skip to content

[1단계 - 음식점 목록] - 분주(황현정) 미션 제출합니다.#187

Merged
onschan merged 41 commits intowoowacourse:bunju20from
bunju20:step1
Mar 10, 2025
Merged

[1단계 - 음식점 목록] - 분주(황현정) 미션 제출합니다.#187
onschan merged 41 commits intowoowacourse:bunju20from
bunju20:step1

Conversation

@bunju20
Copy link
Copy Markdown

@bunju20 bunju20 commented Mar 7, 2025

학습 목표

이번 미션을 통해 다음과 같은 학습 경험들을 쌓는 것을 목표로 합니다.

  • UI와 도메인 영역을 분리할 수 있는 설계를 고민해보고, 목적에 맞게 객체와 함수를 활용
  • TDD 방식으로 개발하며, 단위 테스트 기반으로 점진적인 리팩터링

제출 전 체크 리스트

  • 기능 요구 사항을 모두 구현했고, 정상적으로 동작하는지 확인했나요?
  • 기본적인 프로그래밍 요구 사항을 준수하고 있는지 확인했나요?
  • 테스트 코드는 모두 정상적으로 실행되나요?
  • (해당하는 경우) 배포한 데모 페이지에 정상적으로 접근할 수 있나요?

리뷰 요청 & 논의하고 싶은 내용

1) 이번 단계에서 가장 많이 고민했던 문제와 해결 과정에서 배운 점

  • e2e 테스트를 처음 해보았지만 cypress를 통해서 전체적인 사용자의 흐름을 테스트를 해보고 e2e 테스트의 중요성을 깨달은 것 같습니다.
  • 너무 상세한 컴포넌트 분리보다는, 실질적으로 분리했을 때 코드의 스타일이나 재사용성 측면에서 효율적인 코드가 되는 부분들을 중심적으로 컴포넌트 분리를 하려고 노력하였습니다.

2) 이번 리뷰를 통해 논의하고 싶은 부분

컴포넌트를 분리할 때, 함수형으로 할지 클래스형으로 할지 고민이 많았습니다. 결국 페어와 같이 생각했을 때, 함수형이 상태관리나 private 같은 추가적인 로직에 집중하기 보다는 도메인 로직을 구현하는데 집중할수 있다고 판단했습니다.

온스타는 어떤 방식을 더 선호하고, 클래스형과 함수형을 선택하시는데 기준이 있으신지 궁금합니다!
클래스형과 함수형을 고민했던 예시중 하나인, 헤더를 분리하는 코드는 다음과 같았습니다..

//클래스
export class Header {
  constructor({ container }) {
    this.container = container;
  }

  renderHeader() {
    this.container.innerHTML += `
      <h1 class="gnb__title text-title">점심 뭐 먹지</h1>
      <button
        id="gnb-button"
        type="button"
        class="gnb__button"
        aria-label="음식점 추가"
      >
        <img src="./add-button.png" alt="음식점 추가" />
      </button>
    `;
  }
}

addEventListener("load", () => {
  const headerContainer = document.querySelector(".gnb");
  const header = new Header({ container: headerContainer });
  header.renderHeader();
});
//함수형
export function createHeader({ container }) {
  return {
    renderHeader: () => {
      container.innerHTML += `
        <h1 class="gnb__title text-title">점심 뭐 먹지</h1>
        <button
          id="gnb-button"
          type="button"
          class="gnb__button"
          aria-label="음식점 추가"
        >
          <img src="./add-button.png" alt="음식점 추가" />
        </button>
      `;
    }
  };
}

addEventListener("load", () => {
  const headerContainer = document.querySelector(".gnb");
  const header = createHeader({ container: headerContainer });
  header.renderHeader();
});

✅ 리뷰어 체크 포인트

1단계

  • UI를 컴포넌트 단위로 분리했는가?
  • 재사용 가능한 컴포넌트를 고려했는가?
  • 주요 기능 시나리오에 대한 E2E 테스트를 작성했는가?

2단계

  • 오류 상황(예: 잘못된 입력)에 대해서도 테스트 케이스를 정의했는가?
  • 타입 정의를 적절히 사용하여 컴파일 오류 없이 안정적으로 동작하는가?
  • 로컬/배포 환경에서 테스트가 정상적으로 동작하는지 확인했는가?

bunju20 and others added 30 commits March 4, 2025 14:28
Co-authored-by: bunju20 <bunju20@users.noreply.github.com>
Co-authored-by: bunju20 <bunju20@users.noreply.github.com>
Co-authored-by: bunju20 <bunju20@users.noreply.github.com>
Co-authored-by: bunju20 <bunju20@users.noreply.github.com>
Co-authored-by: bunju20 <bunju20@users.noreply.github.com>
- 헤더 타이틀 테스트
- 헤더 모달 버튼 테스트
- 가게 아이콘이 표시되는지 확인
- 가게 이름이 표시되는지 확인
- 캠퍼스 소요 시간이 표시되는지 확인
- 가게 설명이 표시되는지 확인
- 배경 테스트
- 모달 제목 테스트
- 카테고리 드롭다운 테스트
- 이름 테스트
- 거리 클릭 시 항목들 표시 확인
- 설명 입력 확인
- 참고 링크 입력 확인
- 모달 하단에 취소하기, 추가하기 버튼 표시 확인

Co-authored-by: bunju20 <bunju20@users.noreply.github.com>
- 이름 input 유효성 검사 로직 구현
Co-authored-by: bunju20 <bunju20@users.noreply.github.com>
@onschan onschan self-requested a review March 9, 2025 04:54
Copy link
Copy Markdown

@onschan onschan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

안녕하세요. 분주!

만나서 반가워요 😊


e2e 테스트를 처음 해보았지만 cypress를 통해서 전체적인 사용자의 흐름을 테스트를 해보고 e2e 테스트의 중요성을 깨달은 것 같습니다.

저도 cypress 처음 사용했을때 정말 재미있게 했었던 기억이 있는데요. 이미 효용을 느끼셨군요. 테스트를 좋아하는 꼼꼼한 개발자가 될 수 있겠어요. 멋진 성장 기대하겠습니다!

너무 상세한 컴포넌트 분리보다는, 실질적으로 분리했을 때 코드의 스타일이나 재사용성 측면에서 효율적인 코드가 되는 부분들을 중심적으로 컴포넌트 분리를 하려고 노력하였습니다.

좋은 포인트네요. “컴포넌트”라는 상황에 매몰되어 불필요한 부분들도 잘게 쪼개다보면 관리 포인트들이 너무 많아질 수가 있죠. 필요한 순간에 필요한 만큼 적절히 활용하는 능력이 아주 중요한데 이미 그 포인트에 대해 고민하고 계시다니 훌륭합니다.

온스타는 어떤 방식을 더 선호하고, 클래스형과 함수형을 선택하시는데 기준이 있으신지 궁금합니다!

처음엔 함수형, 클래스형 컴포넌트라는 질문이 너무 React스러운 질문이지 않을까해서 걱정을 했는데, 고민하신 포인트는 되게 합리적이고 실용적인 고민들이었군요.

함수형이 상태관리나 private 같은 추가적인 로직에 집중하기 보다는 도메인 로직을 구현하는데 집중할수 있다고 판단

해당 고민의 방향과 귀결된 결론에 동의합니다.

UI 렌더링이 목적이 강하고 간단한 비지니스 로직들을 가진 컴포넌트들을 굳이 클래스화해서 설계할 필요는 없다고 생각해요. 클래스는 해당 인스턴스 객체가 생성될때 어떤 행동을 할 지, 어떤 성격을 가지고 있는지 쉽게 볼 수 있도록하는 설계도라 생각을 하는데, 해당 미션에서 사용하는 컴포넌트들은 함수형으로만 나타내도 충분히 쉽게 알아 볼 수 있고, 파악하는데 전혀 지장이 없다고 생각해요.

제 성향과 제 시각에 내리신 결론과 과정이 흔들릴 필요는 없지만, 저는 클래스를 좀 더 선호합니다.

작은 단위의 컴포넌트부터 확장을 하고 인스턴스화해서 상태를 가지도록 하는게 프로젝트를 진행하는데에 좀 더 유리하다는 의견이에요. 미래까지 상상하며 선택의 기준을 두는 케이스라 해당 미션이나 비교적 간단한 프로젝트에서는 분주가 내린 결론처럼 함수형으로 찍어낼 것 같긴해요!


미션 잘 진행해주셨어요. 코멘트에 남긴 사항들 확인해주시면서 현재 단순 리터럴 템플릿으로만 되어있는 UI들을 데이터 측면에서 어떻게 재사용 가능하도록 할 수 있을까를 고민해주시면 좋을 것 같아요!


describe("카테고리 입력 테스트", () => {
it("카테고리 드롭박스를 선택하지 않으면 추가할수 없다.", () => {
const input = "error";
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"error"라는 특정 케이스에 의존되어있는 테스트 상황은 예측하기 힘들 것 같네요
validate 검증하는 부분에 코멘트를 더 남기도록할게요

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

드롭박스에서 입력받는게 없으면 error라는 문자열을 받아서 그걸 검증 하는거였는데 확실히 알아보기도, 예측하기도 힘든것 같습니다. 입력값을 공백으로 주고 그걸 테스팅 하는 방식으로 수정하겠습니다!

Comment on lines +95 to +96
cy.get(".button--secondary").should("contain", "취소하기");
cy.get(".button--primary").should("contain", "추가하기");
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

contain과 have.text를 사용하는 기준은 명확한가요?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이전까지는 기준에 대해서 생각해보지 않았었습니다...! 지금 찾아보고 생각해보기엔 have.text는 정확하게 텍스트가 같아야 할때 사용해야할것같고, contain은 특정부분만 확인하거나, 동적으로 바뀌는 부분이 있을때 사용해야할것 같습니다. 한번 have.text를 사용해서 덜 관대하도록 개선해보겠습니다!

Copy link
Copy Markdown

@onschan onschan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

빠르게 리뷰 반영해주셨군요!

데이터 측면에서 재활용할수 있는 방향으로 개선된 점이 좋네요.
'데이터가 HTML 요소에 바로 들어가는 부분보다는 "데이터" 측면에서 재활용할 수 있도록 컴포넌트를 구성해보자' 라는 이번 미션 방향을 신경써주세요!

지금 의도대로 진행하시면 될 것 같고 다음 단계에서 뵙겠습니다!

@onschan onschan merged commit 95d95eb into woowacourse:bunju20 Mar 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants