우아한테크코스 6기

3주차 미션 [로또] 회고록

스키(ski) 2023. 11. 8. 22:01

이번주차는 가장 만족스럽지 못한 한주였다. 시간을 많이 못냈던게 가장 큰 문제였던것 같다.

 

3주차 미션코드 깃허브

https://github.com/woowacourse-precourse/java-lotto-6/pull/1460

 

[로또] 신권일 미션 제출합니다. by shin5774 · Pull Request #1460 · woowacourse-precourse/java-lotto-6

의문점 및 고려사항 Controller의 기능이 과중되는 MVC패턴의 문제를 어떤 방식으로 해결할수 있을것인가 VIew 클래스에서의 검증은 진행되어야하는가? 도메인의 필드를 getter을 통해 가져와 도메인

github.com

 

부끄럽지만 코드리뷰 같이 해봐요! 부족한점이 많이 있을거라 날카로운 리뷰도 환영합니다!

 

주차 시작전 (0~1일차/코드리뷰)

0일차

2주차를 마무리하고 바로 코드리뷰를 시작하였다. 코드리뷰에서 얻었던 것이 많았기에 바로 다른 사람들의 코드를 리뷰해보기 시작했다.

 

 

역시 다들 코드를 잘 짰다는게 보였다. 하지만 저번주와는 다른것은 저번주에는 코드 자체가 잘 안보였다면 이번주에는 어느정도 배우고 본인도 코드를 나름의 논리대로 짰다보니 어느정도 코드들의 맥락들이 보이기 시작했다. 그러다보니 코드를 읽는 속도도 전보다 빨라지고 이사람이 어느부분에서 고민을 했는지 알수 있게되었다.

그래도 내 코드는 아직 부족했다.. (그래도 전보다 만족스럽긴했다! 성장한듯!)

 

그런데 여러 코드들을 보다보니 공통점을 하나 발견했다.

이번주에는 유독 다들 클래스의 생성자를 private로 만든것이었다. 

대체 왜 그런거지? 하고 궁금증을 가지게 되었고 이는 1일차의 오프라인 코드리뷰 과정에서 해결되게 된다.

 

1일차

이 날은 나와 같이 백엔드파트를 진행하고 있는 참가자들과 만나서 각자의 코드의 리뷰를 진행했다. 

여태까지 깃허브를 통한 온라인 코드리뷰만을 진행해왔던 나에게 이 경험은 상당히 신선했다.

아무래도 오프라인이다보니까 실시간으로 의견제시가 가능했고, 각자의 생각을 빠르게 공유할수 있었다.

이런 과정에서 본인의 생각을 다시 검토해보고 이러는 중에 새로운 관점으로 코드를 바라보게 되어 발상의 전환이 가능해졌다.

 

그리고 여기서 전날 의문이었던 생성자의 private 설정의 미스테리가 풀리게되었다!

이는 정적 팩토리 메서드 라는 패턴의 구현과정이었다.

이 패턴 또한 처음 들어본 개념이었고 같이 코드리뷰하신분들이 상세하게 설명해주었기에 얼추 이에 대해 이해 할수 있었다.

 

이는 상당히 의미있고 가치있는 경험이었다.

(리뷰만 6시간 정도 한건 안비밀..)

 

작성기준(11/08) 내일도 오프라인 코드리뷰를 할 예정이다.

이 글일 읽고있는 당신도 주변에 같이 우테코를 하는 사람이 있다면 오프라인으로 코드리뷰 해보는것도 좋을것 같다!

 

 

 

주차를 진행하면서

3주차 미션은 로또 미션이었다. 이 미션또한 작년 우테코 프리코스에서 나온 미션이었다.

하지만 작년에는 제대로 수행한 기억도 없어서 사실상 새로시작하는 느낌이었다.

저번주차와 마찬가지로 이번주차에도 큰 목표를 하나 잡기로 했다.

 

이번주차는 '테스트 코드를 중점으로 둔 개발을 해보자!' 라는 타이틀을 잡고 가기로 했다.

 

이전까지는 본인 나름대로 TDD를 해보았지만 지금와서 보니 부족했다는것을 알았다.

마침 이번주차에 제시도니 목표가 '클래스분리와 도메인로직의 단위테스트 작성연습' 이었고 이는 내 중점 목표와 맞아 떨어졌기에 테스트코드를 중점으로 두고 미션을 진행해보기로 했다. 

 

그리고 저번주차의 반성점이었던 1. 기능목록의 적절한 활용  2.기초부터 진행하기 그리고 3.몰입감 회복 을 신경쓰면서 진행하기로 했다.

 

1. 기능목록의 적절한 활용 

 

저번주차 회고록에서 본인은 기능목록의 활용에 대해 반성점으로 남겨놨고 이를 잘 사용하기 위해 고민했다.

그리고 이는 나만그랬던게 아니었던것 같다.

 

기능목록에 대한 2주차 공통 피드백

 

 

모두가 기능목록을 제대로 사용하지 못하였고 이를 적절하게 사용하기 위한 고려사항이 2주차의 공통 피드백으로 날라왔다.

 

결국 기능 목록이라는 건 처음부터 완벽하게 작성하려고 하기 보다는 미션을 구현하면서 여러 수정사항을 반영하면서 조금씩 완성을 향해 나아가는것, 즉 기능목록 문서를 살아있는것처럼 보이는게 하는게 기능목록의 적절한 활용법이라는 것을 알게되었다.

 

따라서 이전 주차처럼 너무 과하게 쓰기 보다는 최초에 미션의 흐름에 따라 기능목록만을 작성하고 중간에 수정이 생길때마다 수정하는 방식으로 진행했다. 

이번미션의 기능목록 중 일부

 

 

2. 기초부터 차근차근 (너만의 탑을 쌓아라)

이는 저번주에 개발 도구에 집착하다가 본질을 놓친 경험에서 느낀점이다.

배보다 배꼽이 커져버린 문제점에서 이를 해결하기 위해 가장 근본인 기능분리부터 차근차근 진행하기로 했다.

 

2주차 피드백중 일부

 

이는 공통 피드백에서도 나온 사항중 하나였다. 이를 보고 나는 대부분 나와 같이 패턴과 모델링에 집착하다 본질을 놓쳤다는것을 유추할수 있었다.

 

따라서 이번주차는 최대한 기능 분리에만 중점을 두고 미션을 진행했다. 그리고 이는 자연스럽게 테스트코드의 작은 기능 구현으로 넘어가게 된다.

 

3. 테스트코드는 프로덕트 코드만큼의 중요성을 가진다

2주동안 미션을 진행하면서 줄곧 느낀점이 있었다.

 

 

"내가 테스트코드를 잘 짜고 있는게 맞을까..?"

 

 

나름대로 TDD를 한다고 하면서 테스트코드를 짜고 이를 이용해 프로덕트코드를 짯는데 항상 프로덕트 코드가 수정되면 테스트코드가 안돌아가서 이를 수정하는 과정이 반복되었다. 그러다보니 자연스럽게 테스트코드 기반으로 진행하던 과정이 프로덕트 코드를 따라가게되는 과정으로 바뀌게 되었다.

 

3-1. 제어할수 없는것에 의존하지 말자 (feat. 랜덤코드)

이런 생각을 제대로 파게(?) 해준건 2주차의 본인 코드리뷰에 있는 한 의견에서 시작되었다.

 

해당 의견과 저 영상은 큰 영감을 주었다.

 

처음 이 의견을 보았을때 자체를 이해할수 없었고 이를 이해하기 위해 저 영상을 보았다. 저 영상이 테스트코드에 대한 생각을 깊게 하게 되었다.

 

https://www.youtube.com/watch?v=DJCmvzhFVOI

 

해당 영상에서 첫 주제가 테스트코드에 대한 내용이었다. 주제는 '제어할수 없는 것에 의존하지 않기'였다.

짧게 요약하면, 외부 API나 랜덤성이 있는 로직들, 즉 제어할수 없는것을 최대한 기능에서 분리시켜서 이를 제외한 나머지를 테스트 가능하도록 만들자는 것이었다.

 

이 영상을 보다보니 떠오르는 한가지 코드가 있었다.

 

아! 미션의 랜덤코드!

 

항상 테스트코드를 작성하면서 랜덤코드가 들어가는 기능에 대해서는 되었다고 가정하고 처리를 하거나, 아니면 아예 해당 기능의 테스트코드는 작성안하는 식으로 넘어갔었다. 이렇게 하면서도 '이렇게 해도 되는건가..?' 라는 의문점이 들었는데 이 영상을 통해 이는 잘못되었다는것을 알게되었다.

이후에는 랜덤기능이 들어가는 코드를 최대한 분리시켰다.

 

3-2. 그땐 몰랐죠.. 제가 미션 코드를 뜯어볼줄은.. (feat 모킹)

랜덤코드를 분리시킨 후 이제 이를 테스트 해야했는데 이 방법에는 모킹이라는것을 사용하면 됐었다.

이는 인자의 값이나 메서드의 반환값을 임의로 설정해줄수 있어서 이를 이용해 테스트를 진행할수 있었다.

 

하지만 이를 코드에 적용하려고 하니 미션에서의 랜덤메서드는 우테코에서 자체제작한 api였기에 이를 어떻게 적용해야할지 몰랐다.

따라서 해당 코드를 분석해보기로 했다. 마침 이를 먼저 진행한 사람이 디스코드에 내용을 올렸기에 이를 참고했다.

 

 

테스트 api 분석을 통해 만든 테스트코드

 

 

3-3. 테스트코드는 유연해야한다.

제어할수 없는것을 최대한 분리하고 이를 테스트까지 하였지만 아직 문제점이 남아있었다.

바로 리팩토링 과정에서 테스트코드가 계속 바뀌는 문제였다.

그래서 이를 해결하기 위해 여러 정보를찾아 보았고 도움이 되는 정보들을 발견하였다.

https://techblog.woowahan.com/8942/

 

단위 테스트로 복잡한 도메인의 프론트 프로젝트 정복하기(feat. Jest) | 우아한형제들 기술블로그

최근 저는 복잡한 도메인의 서비스를 개발하는 개발자라면 공감할 만한 문제를 겪고 있었습니다. 찬호 님, 서비스가 비마트일 때, 공급사 반품 상세페이지에서 공급사 계정으로 로그인한 사용

techblog.woowahan.com

https://jojoldu.tistory.com/614

 

테스트 코드에서 내부 구현 검증 피하기

테스트 코드를 작성하고 운영하다보면 기존 코드가 조금만 변경되어도 테스트를 다 고쳐야하는 경우가 종종 있다. (모든 경우가 그렇진 않겠지만) 기능의 최종 결과를 검증하는게 아니라 내부

jojoldu.tistory.com

https://mntdev.tistory.com/91?category=1403630

 

private 메소드 테스트 꼭 해야 할까?

private 테스트 해야돼? private 메소드는 어떻게 하나요? 라는 질문이 우테코 단톡에 올라왔다. 리플렉션을 사용하는 방법(개인적으로 절대 사용하지 않는) 내가 답변했던 package-private을 사용하는

mntdev.tistory.com

 

이러한 정보들을 요약하면 다음과 같다.

 

1. Private 메서드를 테스트하기위해서 해당 메서드를 public으로 바꿔야만 한다면 이는 문제가 된다

private 메서드들은 클래스 내부에서 사용되는 메서드이다. 즉, 이를 사용하는 public 메서드가 있을것이다. 따라서 public 메서드를 테스트함으로서 private도 검증이 가능해져야한다.

만약 접근제어자를 변경해야한다면 이는 기능 분리의 신호일수도 있다.

 

2. 단위 테스트는 중간 과정을 검증하는것이 아닌 최종 결과를 검증하는 것이다.

테스트코드를 내부기능을 일일이 검증하게 되면 차후 프로덕트 코드가 수정됐을떄 테스트코드를 바꿔야만 한다.

따라서 단위 테스트의 경우는 중간과정을 검증하는것이 아닌, 최종 결과값을 검증하는것이 리팩토링에서의 유연성을 가지게된다.

 

 

이러한 정보들을 통해 아래와 같이 본인만의 테스트코드 개발과정을 어느정도 적립할수 있었다.

 

1. 작은 단위의 기능별로 테스트코드를 작성

2. 차후 큰 단위로 병합되는 과정에서는 해당 과정의 진입접을 통해 하위 기능까지 테스트 가능하도록 수정 

 

 

주차 반성점 및 개선사항

이번주차는 여태까지중 가장 본인에게 실망스러운 한주였기에 반성점도 많다..

 

1. 수면 빚을 갚을때가 와버렸다.

2주간 우테코를 진행하면서 기존의 수면시간보다 훨씬 적은 시간만 자게되었다. (평균 4~5시간) 

이게 2주차까지는 어찌저찌 버텼는데 3주차가 되니 후폭풍이 한번에 몰려왔다.

운동하면서 체력이 어느정도 좋아졌다고 생각했는데.. 아무래도 내 착각이었나보다..

 

며칠간은 헤롱헤롱거리면서 몸상태도 최악을 달리게되면서 미션에 집중할수 없었다. 어쩔수 없이 몸을 회복하기로 하였고 자연스럽게 미션에 사용한 시간이 앞선 주차보다 상당히 줄어버렸다.

결국 만족스러운 결과물을 내지 못했고, 마무리가 깔끔하지 못하다는 느낌을 받았다.

 

물론 그 와중에도 미션 진행을통해 얻은것도 많지만.. 그래도 불만족 스러웠다.

이제 어느정도 몸도 회복됐고 우테코는 1주만을 남겨두고 있기에 이번주는 진짜 이몸을 불살라서 해볼 생각이다.

(끝나고 쓰러진다는 각오로)

 

 

주차에 포스트한 우테코 관련 정보 

이번주는 시간 자체가 부족해서 구현만 하는데도 시간이 빠듯했다..

하지만 쓸 내용은 몇가지 확보했다.(테스트코드의 유연성,중요성,TDD의 리팩토링 방법(aka 단위테스트),정적팩토리 메서드)

아마 이번주는 시간이 많을것으로 예상되기에 이번주는 이 내용들을 포스트할것 같다.!

 

기타 잡담

1. 잠은 줄이면 줄여지만 적당히 줄이자. 

-어느 순간 정신이 멍한 본인을 발견했다. 가뜩이나 부족한 시간에 집중을 제대로 못했다. 하루를 밤을 샜다면 하루는 적절하게 자자. 계속 세다보면 어느샌가 무너진다.

 

2. 현재 관심사: - Controller의 기능 과중 문제 어떻게 해결하지?

                         - 블로그 포스팅(밀린 정보,써야만..한다..!!)