-
Notifications
You must be signed in to change notification settings - Fork 172
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[2단계 - 자동차 경주 구현] 호프(김문희) 미션 제출합니다. #99
[2단계 - 자동차 경주 구현] 호프(김문희) 미션 제출합니다. #99
Conversation
- dom 조작 기능은 View 클래스에 위임
- getElementById 대신 querySelector, querySelectorAll 사용 - ID 대신 SELECTOR 상수화
- 기존의 Move 메서드에서 t/f 반환 제거 - 해당 함수에서 직접 확인하도록 수정
- 자동차 이름 입력 후 자동차 이름 폼 비활성화 - 레이싱 횟수 입력 후 레이싱 횟수 폼 비활성화
…script-racingcar into step2-moonheekim0118
- getInputValue 에서 element로 받은 input value의 값을 바로 리턴하도록 수정 - 쿼리 셀렉터에 target 값으로 APP 추가
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
호프님 안녕하세요 피드백 드린 내용을 충실히 잘 구현해 주셨네요 구현하느라 고생하셨습니다
추가적으로 더 나은 코드를 위해 많은 고민을 해주셨네요
아직 미션일정 여유가 있고 고민하시는 부분이 있으니 피드백과 함께 수정요청 드립니다
질문주신 5가지 사항에 대해서 개인적인 일정상 먼저 3가지에 대해서 답변 드립니다 나머지는 다음 피드백 때 마저 답변 드리도록 할께요 양해 부탁드려요
질문에 대한 답변
- 저는 도메인 단위로 분리하는걸 선호하는 편인데요
이 프로그램은 크게 봤을 때 입력, 경주, 우승자 표시 이렇게 3개의 도메인으로 구성되어 있다고 봅니다
그런 관점에서 봤을 때 RacingCarGame이 다루고 있는 도메인은 입력 form과 경주화면 2가지를 모두 담고 있는데 이 2개는 분리가 가능할 것 같습니다
그리고 View는 화면단의 모든 영역을 핸들링 하고 있는데 이 부분도 도메인 단위로 분리가 가능한 영역으로 보입니다 - 테스트코드를 상세히 잘 구현해 주셨지만 "1초의 텀을 두고 진행상황을 출력하는 기능에 대한 테스트"는 누락된 것 같습니다
하지만 사실 이 부분은 테스트하기 굉장히 까다로운 부분이라고 생각하는데요
이유는 Spinner가 무조건 표시되거나 안되거나 할 수 있다면 테스트 할 수 있지만 랜덤으로 표시되기 때문에 "게임시작 전에 spinner가 표시되지 않았다"만 정확하게 테스트 가능하기 때문입니다
물론 레이서와 게임횟수가 충분히 늘어난다면 각 단계별로 최소 1개 이상의 Spinner가 존재하고 게임이 끝났을 때도 최소 1개 이상의 Spinner가 존재한다고 할 수 있지만 100% 확실한건 아니라서 과연 테스트 대상으로서의 의미가 있는가에 대해서는 의문입니다
만약 게임시작이라는 상태와 횟수별 레이싱의 시작을 상태로 관리한다면 해당 상태가 바뀌었는지의 여부를 테스트 하는 정도면 충분할 것 같습니다 - 하나의 메서드가 하나의 기능만 한다는 관점에서 이번에 작업하신 "전진여부는 외부 함수에서 결정한 후에 Move 메서드는 전진만 하도록" 분리하신게 더 나은 방식이라고 봅니다
"array-callback-return":"off", | ||
|
||
} | ||
"no-return-assign":"off", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lint까지 세분화 하셨군요 박수를 보냅니다 신입때의 제 모습과 너무 대조되서 반성하게 되네요
@@ -9,32 +9,33 @@ Cypress.Commands.add('checkAlertMessage', expectedMessage => { | |||
|
|||
// CarName 을 입력하는 커맨드 | |||
Cypress.Commands.add('inputCarNames', names => { | |||
cy.get(`#${ID.CAR_NAMES_INPUT}`).type(names); | |||
cy.get(SELECTOR.CAR_NAMES_INPUT).type(names); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#를 변수에 포함시켜서 기존 로직보다 명료한 것 같습니다
|
||
## [✅] UI 마크업 | ||
- figma 시안을 기준으로 구현한다. | ||
## [✅] 자동차 이름 입력 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
요구사항에 구현한 기능을 나열하라고 했는데 제가 놓치고 피드백을 드리지 못했던 부분인데 셀프로 잘 반영해 주셨네요
@@ -0,0 +1,20 @@ | |||
export default class Car { | |||
#racingCount = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
접근제한과 캡슐화에 대해서도 고민하셨군요 👍
@@ -1,94 +1,131 @@ | |||
import { MESSAGE, ID, RACING_COUNT } from '../../src/constants.js'; | |||
import { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
테스트 케이스를 상당히 잘게 쪼개서 다양한 경우에 대해서 테스트 해주셨군요 👍
cy.tick(RACING_COUNT.MAX * milliseconds + delayTime); | ||
cy.tick(END_MESSAGE_DELAY); | ||
// then | ||
cy.checkAlertMessage(MESSAGE.GAME_END); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이렇게만 테스트하면 2초 후에 축하 메시지가 출력됐다는 사실은 테스트 되지만 그 이전에 해당 메시지가 출력되지 않았다는 사실은 테스트 되지 않을 것 같네요
보다 정확히 테스트 하기위해 2초 전에는 축하 메시지가 출력되지 않았다는 점도 추가적으로 테스트되면 좋을 것 같습니다
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
생각지도 못했던 부분입니다..ㅎㅎ..맞네요. 2초가 지난 후에 테스트하는건 2초 전에 alert이 떴는지 아닌지를 검증못해주네요..감사합니다 테스트코드 추가했습니다 :)
cy.submitRacingCount(RACING_COUNT.MIN).then(() => { | ||
cy.get(`#${ID.WINNERS}`).should('have.text', winners); | ||
it('자동차 이름은 쉼표(,)를 기준으로 구분한다.', () => { | ||
// given |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
given, when, then으로 의미적인 분리를 하니 보다 구조가 명확해 졌네요!
index.html
Outdated
<h1>🏎️ 자동차경주 게임🏁</h1> | ||
<form id="racing-game-form"> | ||
<div class="input-section"> | ||
<form id="racing-game-form" class="racing-game-form"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
id와 class의 이름을 동일하게 주신건 안티패턴일 것 같습니다
id는 전체 document에서 유일하게 1개만 존재해야 되므로 보다 구체적인 이름을, class는 복수로 존재하는걸 가정하기 때문에 보다 일반적인 이름을 붙이는게 일반적입니다
네이밍에 대해서 조금 더 고민해 보시면 좋을 것 같습니다
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
단순히 같은 엘리먼트를 가리키니까, CSS와 JS에서 가리키는 엘리먼트가 모두 같은 이름이면 개발자가 인식하기 편할 것 이라고 생각했는데, 생각이 짧았네요..이 부분 더 고민해서 고쳐보도록 하겠습니다. :)
src/class/RacingCarGame.js
Outdated
@@ -0,0 +1,116 @@ | |||
import Car from './Car.js'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
전체 코멘트 참고해서 분리해 보시면 좋을 것 같습니다
src/class/View.js
Outdated
@@ -0,0 +1,132 @@ | |||
import { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
뷰 영역도 전체 코멘트 참고해서 개선해 보시면 좋을 것 같습니다
안녕하세요 YB님 남겨주신 리뷰와 질문에 대한 답변 정말 감사드립니다 🙇 많은 도움이 되었습니다. 그리고, 처음에 너무 많고 모호한 질문을 드린 것 같아서 죄송합니다... 나머지 두 질문은 저 스스로 답을 찾는게 맞는 것 같아서 삭제했습니다.. 번거롭게 해드려 죄송합니다. 😢 YB님의 리뷰로 리팩토링한 결과는 아래와 같습니다. 테스트코드 추가 작성
class, id 네이밍
구조 변경이 부분도 제가 너무 깊게 생각하지 않고 무턱대고 질문한 것 같아서 죄송합니다 😢 말씀해주신
조금 찝찝한 점은, RacingCarGame 컴포넌트에서 FormView 까지 제어를 한다는 것 입니다. ( 자동차 결과가 출력 될 때와 게임이 끝날 때를 RacingCarGameForm 컴포넌트에서 감지 할 수 없기 때문입니다.) 주말인데,,정말 좋은 답변과 리뷰 감사드립니다 ~ 혹시 더 수정해야할 부분이 있다면 말씀해주시면 감사하겠습니다 :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
호프님 안녕하세요 구현하느라 고생하셨습니다
제안드린 리팩토링 너무나 잘 수행해 주셔서 승인드리려고 합니다
질문주신 5개 중에 아직 질문 못드린 영역에 답변 드리려고 보니 질문을 삭제하셨네요 ㅠ
절대 과한 질문은 아니었고 차차 답변드리려고 했던 부분인데 히스토리가 안남아서 답변을 드릴수가 없게 되었네요
해결해 보시다가 잘 안되시면 언제든 편하게 다시 질문 부탁 드려요
그리고 말씀주신 Spinner 관련된 테스트는 "1초의 텀을 두고 진행상황을 출력하는 기능에 대한 테스트"라고 기재해 주셔서 전진여부(↓)를 테스트 하시고자 하신걸로 오해하고 피드백 드린 부분이고 (�피드백 중에도 ↓를 제가 Spinner로 잘못 말씀 드렸네요 이 부분은 혼선을 드려 죄송합니다) Spinner의 출력여부만 테스트 하고자 한다면 Spinner는 전진여부와 상관없이 매 게임마다 표시되므로 테스트 가능한게 맞습니다
미션 완료하느라 고생 많으셨습니다 진행중에 끊임없이 고민하고 개선해 주신 점들이 인상 깊었습니다 남은 나머지 과정도 화이팅하세요 :)
데모페이지
안녕하세요 ! YB님 ~ 이전 코드리뷰에서 많은걸 얻어갔습니다 감사합니다. 이번 step2 진행하면서 기존의 코드도 많이 리팩토링해보았습니다! 변수명이나 함수명을 유의미하게 수정하려고 많이 노력했는데,,어떨지 모르겠네요!! 그럼 이번에도 잘부탁드립니다 😃
파일 구조
Step 2 필수 구현 목록
추가된 기능들
disable
상태로 변경된다.리팩토링
View
라는 클래스를 만들어서, RacingCarGame 클래스에서는 View 클래스의 객체를 멤버변수로 지정해주었습니다.given, when, then
을 구분하여 재작성했습니다.궁금한 점
현재 따로 디자인 패턴을 채택하지 않고 필요 시에 나누고 있는데요, 현재 RacingCarGame 클래스나 View 클래스에서 더 나눌 부분이 있을지 조언을 얻고싶습니다.
Step2 기능 사항에 대한 테스트코드는
정상적으로 게임의 턴이 다 동작된 후에는 결과를 보여주고, 2초 후에 축하 메시지를 확인 할 수 있다.
만 구현한 상태입니다. 1초의 텀을 두고 진행상황을 출력하는 기능에 대한 테스트는 위의최종 우승자 출력
에서 이미 검증되었다고 생각했기 때문입니다. Step2 기능 사항에 대한 테스트코드는 이정도면 충분할지 궁금합니다.step1에서는 Car 클래스의 Move 메서드의 역할이, '랜덤함수를 실행한 후, 전진여부를 결정하고 전진한다'였는데요, 이번에는 전진여부는 외부 함수에서 결정한 후에 Move 메서드는 전진만 하도록 구현해보았습니다. 그런데 이게 올바른 방법인지 궁금합니다. 아예 전진 여부 결정도 클래스 내부 메서드에서 해주는게 맞을까요? 아니면 이렇게 외부로 분리해도 괜찮을까요?
질문이 좀 많네요..ㅠㅠ,,늘 감사합니다 : )