블로그

sdsd988

인프런 워밍업 클럽 후기 (2기 백엔드 클린코드, 테스트 코드)

인프런 워밍업 클럽 수료! 1. 워밍업 클럽 참여! 인프런의 효과적인 마케팅, 새로운 기술 학습에 대한 열정으로 다양한 강의를 구매했다.하지만, 완강하지 못한 강의가 쌓이기 시작했다.인프런에서 워밍업 클럽이라는 온라인 스터디를 제공해준다는 글을 보았다.공부도 하고, 혜택도 있다니 안 할 이유가 없어서 즉시 신청 했다.나는 평소에 관심이 있던, 클린코드와 테스트 코드 주제를 신청했다. 2. 1달 동안 강의 지옥(천국) 1달 동안 들어야 하는 강의는 2가지 강의였다.클린코드(14시간), 테스트코드(12시간) 이 정도는 쉽게 완강하겠다는 생각이 있었다.역시 예상은 틀렸고, 매주 정해진 스케줄과 미션을 완료하는 데 빠듯했다. (하지만, 수료했다.)클린 코드의 경우, 객체 지향 설계 원칙에 따라 직접 2가지 프로젝트를 리팩토링하는 과정으로 진행되었다.테스트 코드의 경우, 직접 작은 프로젝트에 대해 테스트 코드를 작성하는 과정으로 진행되었다.매주 정해진 미션, 중간 점검 등이 있어서 자칫 느슨해 질 수 있는 온라인 스터디에 지속성을 더해주었다.3. 회고 스스로 1달동안 열심히 했냐고 물어봤을 때, 열심히 했다고 대답이 나왔다.모든 미션과 강의를 완주했기에 보람과 뿌듯함이 있었다.그럼에도 불구하고, 스스로에게 아쉬움도 있다.멘토님이 중간점검과 특별 점검을 통해 직접 미션 리뷰(코드리뷰)를 해주시고, 개발 관련 질문을 받았다.다른 스터디원들은 미션에 대해 적극적으로 코드 리뷰를 신청하고 질문을 하셨다.나는 안했다. 스스로의 과제에 대해 미흡하다고 느꼈고, 공지 사항을 놓치기도 하였다.그렇다면, 다음 워밍업 클럽이 열린다면 신청할 것 인가?나는 신청할 것 같다.그리고 이 글을 다시 보며, 부족했던 점을 돌아보고 나에게 더 도움이 되는 스터디가 될 수 있도록 노력해보고 싶다.오프라인 수료식 후기  내향적이지만, 용기내서 오프라인 수료식에 참여했다.늦은 시간임에도, 오프라인 수료식을 위해 노력해주시는 인프런 관계자 분들에게 감사했다. 또한, 워밍업 클럽 수료생들로부터 많은 에너지를 충전할 수 있었다.그리고, 준비해주신 피자 너무 맛있었다. 어디 브랜드인지 궁금하다.

백엔드인프런워밍업클럽백엔드테스트코드클린코드후기

홍석주

[인프런 워밍업 스터디 클럽 2기 백엔드(클린코드, 테스트코드)] 후기

강의 후기길다면 길고 짧다면 짧은 인프런 워밍업 클럽이 종료되었다.내가 워밍업 클럽을 신청했던 이유는 Readable Code 강의를 되게 감명깊게 들었는데, 마침 우빈님께서 해당 부캠의 코치로 참여하신다 들었고, 테스트 코드 강의도 들어보고 싶어서 신청하게 되었다.그리고 강의를 들으면서 좋은 내용들을 많이 들을 수 있었고, 지금은 실무에서 어떻게 적용해볼 수 있을까 생각하면서 내 스스로 노력하려고 한다. 내가 노력해보려는 것은SOLID 원칙을 아직까지 철저하게 준수하진 못하지만 SRP 같이 단일 책임 원칙을 적용하여 객체의 책임을 작게 나누려고 있다. 이렇게 작게 나눠 보니까 수정이 생겼을 때 범위를 최소화 할 수 있었다.추상적으로 접근하기, 네이밍 잘 짓기 등 구체적으로 적기 보단 추상적인 메시지를 만들려고 하는데, 때로는 직관적인 메서드 명을 짓는게 나은거 같기도 한 생각이 든다. 이 부분은 계속 숙련해서 나만의 기준을 정해야겠다.테스트 코드를 작성할 때 레드&그린 리팩토링을 적용해보는 것. 나같은 경우엔 비즈니스 코드를 우다닥 짜고, 시간 나면 테스트 코드를 통해 검증하는데 레드&그린 리팩토링을 적용하면서 하면 계속 검증을 하면서 코드를 짜니 안정도가 더 올라가는 기분이었다.등등 위에 기술한거 외에도 많은 부분을 적용해보려고 한다. 좋은 강의를 제공해준 우빈님과 인프런에 감사를 표한다.앞으로 반복 수강하여 더 내 지식으로 체화할 수 있도록 해야겠다 😀오프라인 수료식 간단 후기워밍업 클럽을 진행하면서 미션과 발자국(후기)을 열심히 남기려고 노력하다 종종 까먹긴했었는데, 운영진의 친절 덕분에 감사하게도 모든 미션을 수행하고 기분 좋게 오프라인 수료식을 다녀올 수 있었다!먼저 이렇게 입구에서 귀여운 인프런 캐릭터와 반겨주고 있었다.이것은 SNS 팔로우를 맺어 받은 스티커인데, 이것 또한 너무 귀여웠다 ㅎㅎ이후에 각각 파트에 맞게 자리를 앉아 인프런에서 제공해주는 피자를 먹으며, 다양한 사람들과 네트워킹 활동을 가질 수 있었다. 신기하게도 같이 앉으셨던 분들이 나랑 비슷한 직종의 회사를 다니셨는데, 동일하게 이 직종으론 이직 안 한다고 선언하셔서 재밌었다 ㅎㅎ그리고 대망의 나의 두 번째 온라인 스승님이신 우빈님을 영접할 수 있었고, 내가 궁금했던 것과 다른 분들이 하신 질문들의 답변을 들으면서 아주 좋은 귀동냥 시간이 되었다.이번 워밍업 클럽을 통해서 우빈님의 좋은 강의들을 들을 수 있었던 거 같다.우빈님의 말씀 중에서 돈 받고 일하는 프로라면 주어진 시간 안에 일정 수준 이상의 품질을 보장하는 산출물을 만들어야 한다고 말씀 하셨다. 물론 나도 아직까지 일정을 못 지킨적은 없었는데 시간이 부족하면 품질 쪽은 일단 넘겼던 적이 있는데 강의에서 말씀했던 조상 코드를 내 스스로 만들고, 내가 다시 후손이 되어 내가 왜 이렇게 짰을까 싶은게 더러 있었다. 우빈님이 주신 피드백 처럼 숙련도를 올릴 수 있도록 노력해봐야겠다.다시 한 번 좋은 자리를 마련해준 인프런 팀과 좋은 말씀 주신 우빈님께 감사를 표하며, 글을 마무리 하겠다 끝~ 😀

백엔드

김민성

[워밍업 클럽 스터디 2기 - BE] (클린코드, 테스트코드) 완주 후기

0. 워밍업 클럽 참가 계기평소에 혼자 공부하고, 혼자 써보고 그렇게 개발을 해왔고, 업무도 했었는데, 뭔가 점점 성장에 한계가 오고 있다는 걸 느끼고, 또 이직을 하기 위해 공부를 어떻게 할까 고민하다가 2년차 고졸 개발자의 한계를 넘어선 성장이야기를 읽고 평소에 관심이 좀 있던 테스트 코드에 대해 강의도 듣고, 또 이 강의를 미션을 통해 추가 학습 할 수 있는 기회가 있어서 바로 신청하게 되었다. 1. 강의강의는 Readable Code, 테스트 코드 두 개의 강의를 4주 동안 들어야 한다. 일정이 좀 타이트하긴 했는데 퇴근 후, 주말에 몰아서 들어서 일정은 맞출 수 있었다.듣다 보면 이제 예제를 가지고 강의를 진행하시는데, 잠깐 한눈 팔면 어느새 흐름을 놓쳐버리기 때문에, 적어가면서, 멈춰 놓고 따라 쳐보면서 강의를 학습했고 이러한 방식이 기억에 더 남아서 마음에 들었다.또 강의를 학습하다 보면 코드를 바라보는 시각? 생각이 넓어지고 있다는게 느껴진다. 2. 미션미션 자체는 강의를 열심히 들었다면 크게 어렵진 않지만, 코드 구현하는 미션보다 뭔가 내 생각으로 키워드를 정리하는 미션들이 좋았다. 이거에 대해 깊게 생각해 볼 수 있게 되고, 또 한번 정리를 할 수 있게 된다.또 코드 미션 제출하고, 라이브 세션에서 우빈님이 신청자에 한해 코드 리뷰를 해주셔서 좋았다. 코드 리뷰를 처음 보는데 이런 식으로 진행되는 구나 느꼈다. 3. 후기많은 걸 배우고 느낀 4주간 과정이었다. 기간이 길다면 길고, 짧다면 짧은데 이 기간 동안 꾸준히 공부를 해야 하기 때문에 습관을 만들기에도 좋다고 생각했다.비록 적극적으로 질문하고 이러지는 못했는데, 다음 스터디 주제가 마음에 들면 또 참가해서 적극적으로 참여하고 싶다. (그래서 우수러너로 선정되고 ㅎㅎ) 끝으로 이런 자리를 만들어주신 인프런과 강의 및 진행 해주신 우빈님께 감사드립니다. 

백엔드백엔드스터디2기인프런인프런워밍업클럽

조혜림

[인프런 워밍업 클럽 스터디 2기] 프로덕트 디자인 완주 후기

지난 주 금요일 수료식으로 약 한 달 간의 인프런 워밍업 스터디가 막을 내렸습니다.우여곡절 끝에 그래도 끝까지 완주했다는 생각에 뿌듯하면서도 한편으로는 그렇게 치열하게 아등바등하며 달려온 하나의 목표가 마침내 끝을 맞이했다는 생각에 아쉬운 마음도 들었습니다.지금의 이런 벅찬 감정을 나중에도 되돌아볼 수 있도록 그리고 다음 스터디의 참석을 고민하시는 분들께 조금이나마 도움이 되었으면 하는 마음으로 이번 '인프런 워밍업 클럽 스터디 2기'를 되돌아보고자 합니다. 🙋‍♀️ 스터디에 참여하기까지 저는 현재 스타트업 기업에서 근무하고 있는 9년차 웹디자이너 겸 UI/UX 디자이너입니다. 웹 에이전시에서 4년 가량 근무하다가 현 직장에 웹디자이너로 이직했으나 점점 UI/UX 업무의 비중이 늘어나기 시작하더니 현재는 UI/UX 업무의 비중이 웹디자인 업무보다 훨씬 더 많아지게 되었습니다.웹디자인을 할 때에는 이전에도 그랬지만 지금도 여전히 포토샵이나 일러스트레이터와 같은 그래픽 툴이 불편하다는 생각을 해본 적이 거의 없었습니다. 그러나 UI/UX 업무의 비중이 늘어나면서부터 점점 포토샵에서 UI/UX 디자인 작업을 진행하는 일이 잦아졌고 작업량이 늘어나면 늘어날수록 체감하게 되는 불편함은 점점 더 커져갔습니다. 컴포넌트의 갯수가 늘어나면서 배치해야하는 레이어나 오브젝트의 갯수가 매우 많이 늘어났고 그 과정에서 형태가 동일함에도 레이어 하나, 오브젝트 하나 배치할 때마다 동일하고 반복적인 값을 매번 측정하고 배치해줘야 하는 불편함이 매우 컸습니다. 거기다 수정하다가 실수로 레이어가 움직인 파일을 미처 눈치 채지 못하고 복사해서 여러 페이지를 만들고 나중에서야 실수를 알아차리면 지금까지 작업한 페이지들을 전부 열어 하나하나 레이어를 수정해줘야 했습니다. 이런 불편함은 점점 가중되어 작업의 속도를 더디게 만들었고 이제는 작업 환경의 개선이 필요하겠다는 생각이 들어 스터디에 참여하게 되었습니다. 🤔 초보자가 생각하는 스터디의 난이도 스터디 이전에는 피그마를 배워보거나 경험해본 적이 없었고 이번 인프런 워밍업 클럽 스터디에 참여하면서 처음으로 피그마를 설치하고 배우게 되었습니다. 몇 년 전 피그마와 스케치, XD가 새로 출시되어 서로 경쟁하던 시절에 '포토샵을 다룰 줄 알면 이 세 가지 툴은 금방 익힐 수 있다'는 주변에 먼저 익힌 직장 동료들의 조언을 기억하고 야심차게 참여하였으나...출시 초창기의 피그마는 한 두시간이면 쉽게 익힐 수 있는 툴이었을지도 모르겠지만 몇 년 간 업데이트가 쌓이고 특히 배리어블의 등장 이후로는 제가 경험해본 바로는 단 몇 시간으로 금방 배울 수 있는 툴은 아니었습니다.그리고 본 스터디의 목적은 이렇게 저처럼 스터디에서 난생 처음 피그마를 다루는 사람에게 맞춰져 있지 않기 때문에 스터디에서 수강 하는 강의의 내용이 기능의 정의나 툴의 역할 하나하나를 설명하는데에 초점이 맞춰져 있지 않습니다. 따라서 처음 피그마를 경험하시는 분들에게는 스터디와 강의가 다소 어려울 수 있을 것 같습니다. 특히 올해 GUI3로 대규모 업데이트가 진행되면서 인터페이스의 변화가 매우 크게 발생하여 궁금한 점을 검색하더라도 이전 버전의 인터페이스로 설명해주는 정보가 많아 더더욱 프로그램에 적응하기 어려울 수 있습니다. 실제로 저 역시 상술한 이유로 1주차~2주차의 2주간 매우 많이 헤맸고 2주간 공휴일이 며칠 씩 있었음에도 공휴일과 주말 모두를 반납해서 겨우겨우 강의를 다 듣고 과제를 마무리할 수 있었습니다. 그래서 피그마를 한 번도 실행해본 적이 없는 분이라면 스터디에 참여하기 전에 피그마를 설치해보고 기본적인 툴의 기능이나 인터페이스와 메뉴를 꼭 익히고 스터디를 참여하시길 추천드립니다.제 생각에 피그마를 익히는데에 도움이 되는 관련 지식으로는 포토샵과 퍼블리싱에 대한 이해가 아닐까 싶습니다. 포토샵이나 일러스트레이터를 다룰 줄 아는 분이라면 툴 내의 기능이나 단축키가 유사한 점이 많아 툴에 대한 적응을 보다 수월하게 할 수 있을 것 같습니다. 또한 피그마에서 구조를 설계하는 방식이 퍼블리싱을 할 때 그리드를 설계하고 다양한 css 값으로 각 엘리멘트를 조절하는 방식과 유사하여 퍼블리싱에 대한 지식이 있으신 분들에게는 피그마 내에서 구조를 설계하고 레이아웃을 구현하는데에 보다 쉽게 적응하실 수 있지 않을까 싶습니다. ✨4주간 진행된 스터디에 대한 후기 ⭐⭐⭐⭐⭐비록 이번 스터디를 통해 피그마를 처음으로 접해보았지만 그럼에도 감히 후기를 남긴다면 '피그마로 구현할 수 있는 A부터 Z까지 모든 것을 다 경험해볼 수 있는 강의이자 스터디였다.'라고 남기고 싶습니다. 스타일과 배리어블의 개념 이해와 배리어블 등록, 다양한 기본 컴포넌트 제작, 제작한 컴포넌트와 베리어블을 활용한 레이아웃 구현과 서비스 페이지 제작까지. 강의와 스터디의 커리큘럼을 따라가다 보면 피그마를 통한 UI/UX 디자인의 가장 작은 단위부터 가장 큰 결과물까지 모든 과정을 경험해 볼 수 있었습니다. 개념 설명과 구현 방법은 강의에서 매우 자세하게 다뤄주시기 때문에 피그마가 아직 서툴고 익숙하지 않은 분들도 강의를 따라가다 보면 어렵지 않게 이해하고 구현할 수 있습니다. 또한 배리어블의 개념과 등록 역시 아주 상세하게 알려주시기 때문에 아직 배리어블을 접하지 않으셨거나 혹은 배리어블에 적응하지 못하신 분들에게도 본 강의와 스터디가 큰 도움이 될거라고 생각합니다.강의와 스터디의 커리큘럼 구성이 상술한 바와 같이 개념-컴포넌트-레이아웃-서비스 페이지 구현으로 이루어져 있고 이는 작은 단위에서부터 큰 결과물까지 점점 그 단위가 커지는 양상을 띄고 있어 수강생 입장에서는 점점 지식이 쌓이고 성장하는 것을 체감할 수 있었고 아울러 종래에는 서비스 페이지 구현을 통해 스스로의 성장을 시각적으로 확인할 수 있어서 매우 뜻깊었습니다.그리고 해당 스터디는 특강의 내용이 다른 데에서 쉽게 찾아보기 어려운, 정말 유용한 정보로 가득하여 특강만으로도 스터디에 참여할 이유가 충분하다는 생각이 들 정도였습니다. 실무에 당장 적용할 수 있는 정보 뿐만 아니라 디자이너로써의 역량을 향상 시킬 수 있는 기술을 배울 수 있는 특강이라 정말 의미 있는 시간이었습니다. 특히 프로토타입 특강의 경우 쉽게 찾아보기 어려운 수준의 구현까지 특강에서 배워볼 수 있어 보다 더 연습하여 체득하고 싶은 의지도 불태울 수 있는 시간이었습니다. 4주간의 스터디 시간이 이렇게 막을 내리게 되었는데 스터디는 끝이 났지만 이제 또 다른 시작점이라고 생각합니다. 아직은 부족한 점이 많기에 스스로 더 찾아보고 공부하면서 피그마를 다루는 능력도 키우고 포트폴리오도 피그마로 제작해볼 계획입니다. 무엇보다 이번 스터디로 가장 크게 배운 건 '안주하지 않고 새로운 것에 도전할 수 있는 힘'이었습니다. 지금까지 배운 지식들을 토대로 현재에 안주하지 않고 보다 멋진 디자이너, 보다 유능하게 다른 팀과 커뮤니케이션 할 수 있는 디자이너가 되기 위해 노력해야겠습니다. 4주 동안 스터디를 진행하시면서 많은 가르침을 주시느라 고생 많이 하신 볼드 선생님께 감사의 말씀을 올리며 마치겠습니다. 읽어주셔서 대단히 감사합니다😁

UX/UIUI/UXFigma프로덕트디자인디자인시스템인프런인프런워밍업클럽스터디2기

홍석호

[인프런 워밍업 스터디 클럽 2기 백엔드(클린코드, 테스트코드)] 후기

왜 참여했는가?스프링과 JPA 공부를 한 뒤, 간단한 웹 애플리케이션을 만들어보는 프로젝트를 진행해보았다. 프로젝트에 테스트 코드를 작성하는데, 막상 어떻게 작성해야 할지는 알 수 없었다. 관련 자료를 찾아보아도 TDD나 유닛 테스트, JUnit에 관한 내용은 잔뜩 있었지만 '그래서 실제로 테스트를 어떻게 작성해야 하는지'를 알려주는 자료는 많지 않았다. 결국 우격다짐으로 테스트 코드를 작성하긴 했지만, 결과물은 만족스럽지 않았다. 프로젝트를 끝낸 후 인프런에 테스트 관련 강의를 찾아보던 중, 마침 워밍업 스터디 클럽을 진행하고 있어서 참여하게 되었다. 강의 내용은 어떠했는가?테스트 관련 내용이 궁금해서 들었지만, 클린코드 관련 내용도 아주 좋았다. '클린 코드'나 '오브젝트'같은 책들에서 얻을 수 있는 지식을 벗어나는 얘기는 없었지만, 파편화되어 있던 지식들을 조각 모음하는 것 같은 기분이 들었다. 그 과정에서 들어보긴 했지만 정확히 알고 적용하지 못하고 있던 내용들을 많이 발견할 수 있었다. '추상화 계층'같은 개념이 그랬다. 독창적인 설명 방식이나 현직자의 관점을 엿볼 수 있는 점이 가장 큰 장점이다. '추상'에 관한 설명은 정말 인상적이었다.테스트코드 강의는 정말 좋았다. 각 레이어별로 어떻게 테스트를 작성해야 하는지 구체적으로 알려주는데, 이게 정말 내가 원하던 것이었다. 정말 속이 시원할 정도였다. 또 Spring Rest Docs처럼 궁금하긴 했지만 우선순위로 두지 않았던 것을 이번 기회에 배울 수 있어서 좋았다. 워밍업 클럽 경험은 어땠는가?미션을 해결하고 온라인 라이브를 통해 피드백을 받으면서 부족한 점을 발견할 수 있었다. '안다고 생각했지만 사실은 모르고 있던' 지점들을 발견해서 공부하고 발전할 수 있었다.온라인 라이브에서는 Q&A도 진행하였는데, 궁금하던 점들을 정말 시원하게 모두 해소할 수 있었고, 또 다른 사람들의 질문을 보면서도 많이 배웠다.매주 회고를 적어야 했는데, 이 회고는 좀 더 자세하게 적을걸 그랬나 하는 아쉬움이 살짝 들긴 한다. 마무리하며나에게 워밍업 클럽의 가장 큰 장점은 '몰입'이었다. 하루마다 정해진 분량이 있어서 강의를 몰입해서 들을 수 밖에 없었다.전반적으로 워밍업 클럽은 이후에 다른 주제로 또 참여하고 싶을 정도로 좋았다.강의를 들으면서, 글의 마무리로써는 조금 엉뚱할 수 있지만 코틀린을 공부해야겠다는 생각이 확고하게 되었다. 지금은 코틀린으로 아주 간단한 애플리케이션을 만들고 있고, 스프링과 코틀린을 함께 써 볼 예정이다.  

Groot

<워밍업 클럽 2기 - 백엔드 클린 코드, 테스트 코드> 후기

워밍업 클럽 참여 후기지난 한 달 동안 클린 코드와 테스트 코드 주제의 강의를 들으며 시간을 보냈다.두 개의 강의를 모두 수강해야 하다보니 일과 후 강의를 듣고 공부하는 것만으로도 시간이 빠듯했다. 처음엔 익숙한 내용이라 여유롭게 공부했지만 방심하는 순간 진도가 쌓여 버려 다급하게 몰아서 하고는 했다. 후반부에는 미션 수행을 위해 외출 중에도 강의 자료(+코드)를 보며 학습했다.스스로 평가를 해보자면 밤샐정도는 아니지만, 한정된 시간동안 열심히했다..! 하지만 급하게 한 경우도 많아서 다시 복습해야 할 것 같다. 그럼 워밍업 클럽에 참여하며 느낀 후기를 남겨본다. 1. 강의강의는 실습 중심으로 직접 코드를 작성하며 다양한 내용을 설명하는 방식이었다. 강의 자료는 내용을 떠올리기 위한 참고용으로 좋은 정도이고 코드 위주로 진행되었기 때문에 복습하려면 별도로 정리가 필요했다. 하지만 이러한 방식이 큰 도움이 되었다. 2. 미션모두가 열심히 참여해서 놀랐다. 덕분에 나도 중간에 포기하지 않고 끝까지 해낼 수 있었다. 미션을 하나씩 해결하면서 리팩터링의 막막함도 점차 해소되었고, 어디서부터 시작해야 할지 감이 잡히기 시작했다. 중간 중간의 QNA의 답변들도 많은 힌트가 되었다. 학교 과제(인프런 강의 미션도)는 피드백을 받기 어려운 점이 고민이었는데 워밍업 스터디에서는 다른 사람들의 코드 작성 방식을 볼 수 있어 큰 도움이 되었다. 이를 통해 새로운 코딩 습관을 배우고 기본기를 다질 수 있었다. 마지막으로, 꿀팁을 가득 담아 좋은 강의를 만들어 주신 박우빈님께 감사드립니다.

백엔드인프런인프런워밍업클럽스터디2기

혼자 공부하는 운영체제 - CPU

2024-11-03혼자 공부하는 운영체제 과목에서 CPU와 관련된 부분을 공부하였습니다.학습한 내용을 자바스크립트 코드로 구현하는 중입니다.구현하면서 느끼는 점이 확실하게 이해하지 못한 부분들에 대해서 강제로 다시 살펴보게 되는 것 같습니다.하지만 데이터 흐름을 확실히 정리하지 않고 구현을 하다 보니, 공부한 데이터 흐름과 약간 달라지는 일을 경험하였습니다. 어떻게 수정할지 고민해보아야겠습니다.고민을 조금 해봤는데 구현하는데 한세월 걸릴 것 같아서 강의 내용과 데이터 흐름을 일치시키는 것은 포기하기로 결정하였습니다.현재 구현 초반부이고, 다음 테스트만 통과시킨 상태입니다. 구현의 편의를 위해 ISA로는 1바이트 opcode, 2바이트 워드, addressing mode를 위해 1byte를 따로 마련했습니다. import { test, expect } from "@jest/globals"; import { AddressingMode, Byte, Cpu, Opcode, Register, Word } from "./cpu"; const { R1, R2 } = Register; const { LOAD, STORE, NOP, ADD } = Opcode; const { IMMEDIATE, DIRECT } = AddressingMode; test("can fetch instructions with variable length", () => { // prettier-ignore const program: Byte[] = [ LOAD, R1, DIRECT, 0x00, 0x01, // TODO: Addressing mode 구현 LOAD, R2, IMMEDIATE, 0x00, 0x02, NOP, ADD, R1, R2, STORE, R1, DIRECT, 0x00, 0x01, ]; const stack: Byte[] = []; const cpu = new Cpu(program, stack); const instructions: Word[] = []; while (cpu.programCounter < program.length) { cpu.handleClock(); instructions.push(cpu.instructionRegister); } expect(instructions).toEqual([LOAD, LOAD, NOP, ADD, STORE]) }) 구현 관련해서 참고 중인 사이트들입니다.https://github.com/pbohun/basic-cpu/tree/masterhttps://github.com/skilldrick/easy6502/blob/gh-pages/simulator/assembler.js2024-11-04CPU의 클럭과 관련해서 잘못 이해한 부분이 있었습니다.한 클럭에 fetch도 하고, decode도 하고, execute도 하는 것을 염두에 두었어야 했는데, 너무 단순화를 많이 해서 모든 것을 한 클럭 안에 담아버려서 MBR이 다음 클럭 때 쓸 데이터를 저장하는 버퍼라는 것 등을 전혀 고려하지 못했습니다.fetch, decode,execute가 동시에 일어날 수 있도록 하는 설계를 해보고 오늘 안에 할 수 있는지 확인한 후, 가능하면 고려해서 수정해보아야겠습니다.업데이트: 오늘 안에 못 끝낼 것 같습니다. 원래 해보고 싶었던 것은 다음과 같았지만, 시간 상 기존의 약간 아쉬운 방식으로 진행할 예정입니다.class Register extends Vertex { constructor() { this.state = 0; } handleClockTick(inputEdge: Edge) { this.state = inputEdge.value; } // TODO: steady state보다 나은 이름을 고려해보기 handleClockSteadyState(outputEdge: Edge) { outputEdge.value = this.state; } }업데이트: 서로 다른 Addressing mode에 대해서 다른 명령어로 구분하는 게 편한 것 같습니다. Fetch, Decode, Execute, Memory, WriteBack 사이클에 맞추려다 보니, 같은 명령어로 구현하기 불편한 부분이 많은 것 같기 때문입니다.업데이트: fetch와 decode를 조금 더 깔끔하게 나타내기 위해서 모든 명령어들의 길이를 똑같이 맞추어놓는 것이 구현하기 더 편하다는 생각이 들었습니다. 이를 위해서 0x00으로 남는 길이는 pad를 하고 decode시 이는 무시하기로 하였습니다.

학습일기

정보처리기사 실기 합격 후기

(2024) 일주일만에 합격하는 정보처리기사 실기https://u.inf.run/3Bu7c2O 한 줄 요약: 위 강의 일부 수강 + 실기 기출문제집 1회독, 약 3주간 학습 후 실기 합격 위 강의를 선택한 이유실기 기출문제집을 풀면서 방대한 개념을 전부 커버하는 게 의아하여 이를 추릴 수 있는 방법을 찾았습니다. 더불어 출퇴근 시간을 활용하고자 인터넷 강의를 필요로 했습니다. 타 사이트보다 전략적이면서 양이 많지 않은 특징을 가진 강의를 찾았습니다. 마침 인프런에서 앱을 지원하기 시작하여 덕분에 시간을 잘 활용할 수 있었습니다.사실 시간 관계상 강의 전부를 듣지는 못했습니다. 그래도 이론 통합 요약본 pdf는 시험 전날까지 유용하게 잘 썼습니다. 베이스저는 비전공자이며, 1년차 프론트엔드 개발자입니다. 컴퓨터 공학 수업은 교양으로밖에 듣지 않았으며 코딩테스트로 python, javascript를 준비한 것이 다입니다. 학습 팁저는 필기의 경우 1회독을 한 상태였고, 그 이후로 잊고 있었다가 시험 4주 전에 학습 계획을 짜고, 1주일을 허비한 다음 3주 전부터 제대로 대비를 하기 시작했습니다.기출 문제집에서 최신 회차부터 풀기 시작했고, 한 5회차 풀이 이후 개념이 부족하다고 생각하여 그때부터 시간이 날 때마다 강의를 듣기 시작했습니다.주말코딩님의 강의는 10분~1시간까지 시간대가 다양한데, 그 중 20분 내외 짜리를 주로 러닝머신에서 들었었습니다. 프로그래밍 언어의 경우 같은 듯 비슷한 부분이 많은데 1.5배속으로 듣다가 의문이 생기는 지점이 있으면 캡쳐한 뒤 다시 공부했습니다. 각잡고 공부하기보다는 시간이 날 때마다 틈틈이 부족한 부분을 채워나가는 것을 반복했습니다.출퇴근 시간 때는 영상이 끊길 때가 많아(이건 아마 인프런 앱의 문제인 것 같습니다) [이론 문제 학습하기] 부분의 학습 메모 파트를 주로 봤습니다.무엇보다 어떤 것에 집중해야하는지 명확하게 알려주셔서 전략적으로 학습을 할 수 있다는 점이 가장 도움이 많이 됐습니다.실기를 본 지가 벌써 세 달이 넘어가 가물가물하지만, 주말코딩님께서 알려주신 공부 방법이 도움이 됐다는 것은 기억이 납니다. 만약 강의를 수강하지 않았더라면 불필요한 것에 투자하여 정작 필요한 부분을 많이 놓쳤을 것 같아요. 비록 높은 점수는 아니지만 합격 기준에 맞추었으니 그만이라고 생각합니다. 이 자리를 빌어 주말코딩 강사님께 감사의 인사드리고 싶습니다!

정보처리기사정보처리기사실기

thagyun

[인프런 워밍업 스터디 클럽 2기 FE] 3주차 발자국

[따라하며 배우는 자바스크립터, 리액트 A-Z - John Ahn] 강의 수강 정리프레임워크 (Framework):애플리케이션을 만들기 위해 필요한 대부분의 요소를 포함하고 있으며, 사용자가 작성한 코드를 호출한다.라이브러리 (Library):특정 기능을 모듈화하여 제공하며, 사용자가 라이브러리를 호출하여 기능을 구현한다.리액트 컴포넌트의 두 가지 유형클래스형 컴포넌트 (Class Component)함수형 컴포넌트 (Functional Component)가상 돔은 간략하게 말해서 이전 가상 돔과 비교하는 디핑 알고리즘을 적용하여 돔 조작 비용을 줄이는 것웹팩: 오픈 소스 자바스크립트 모듈 번들러로, 여러 개의 파일을 하나의 자바스크립트 코드로 압축하고 최적화하는 라이브러리바벨: 최신 자바스크립트 문법을 지원하지 않는 브라우저에서도 작동하도록 변환해주는 라이브러리npx는 Node 패키지 실행을 도와주는 도구로, npx create-react-app ./로 npm 레지스트리에 있는 create-react-app 패키지를 통해 리액트를 설치한다.SPA는 웹사이트의 전체 페이지를 하나의 페이지에 담아 동적으로 화면을 변경한다.JSX를 사용하면 자바스크립트와 HTML 구조를 함께 사용할 수 있어 UI의 데이터 변화나 이벤트 처리 부분을 쉽게 구현할 수 있다.가상 DOM을 사용하여 변경된 부분만 실제 DOM에 적용하는데, Key 속성을 사용하면 어떤 부분이 바뀌었는지를 인식할 수 있다.React State란 컴포넌트의 렌더링 결과물에 영향을 주는 데이터를 갖고 있는 객체다.React Hooks로 class없이 state를 사용할 수 있는 새로운 기능으로 코드가 더 간결해지고 HOC 컴포넌트를 Custom React Hooks로 대체하여 많은 Wrapper 컴포넌트를 줄이게 된다.(HOC: 화면에서 재사용 가능한 로직만을 분리해서 component로 만들고, 재사용 불가능한 UI와 같은 다른 부분들은 parameter로 받아서 처리하는 방법이다. 즉, 컴포넌트를 인자로 받아서 새로운 리액트 컴포넌트를 처리하는 함수다.)TDD: 테스트 주도 개발로 React에서 React Testing Library와 Jest를 함께 사용하여 테스트할 수 있다.Next.js: React 기반의 서버 사이드 렌더링(SSR) 및 정적 사이트 생성(SSG) 프레임워크로, 페이지 기반의 라우팅을 지원하고 API 라우트를 통해 백엔드 로직을 포함할 수 있다.Pre-rendering: 페이지가 요청되기 전에 HTML을 생성하는 방식Data Fetching: getStaticProps와 getServerSideProps, getStaticPaths사용으로 데이터를 가져와 페이지에 전달할 수 있다.Type annotation, Type inference: 타입 주석을 사용해 변수의 타입을 명시하거나, 타입 추론을 통해 자동으로 타입을 결정하는 방법Type assertion: 변수의 타입을 강제로 지정하여 TypeScript의 타입 체크를 우회하는 방법JS 과제전체 과제 제출 - https://www.inflearn.com/blogs/9104Day 2 - 음식 메뉴 앱github : https://github.com/thayoon/study/tree/main/%5BFE%5DInflearn_WarmingUP_Club_Study_2nd/day_2 Day 3 - 가위 바위 보 앱github : https://github.com/thayoon/study/tree/main/%5BFE%5DInflearn_WarmingUP_Club_Study_2nd/day_3 Day 4 - 퀴즈 앱github : https://github.com/thayoon/study/tree/main/%5BFE%5DInflearn_WarmingUP_Club_Study_2nd/day_4 React 과제Day 9 - 예산 계산기 앱github : https://github.com/thayoon/study/tree/main/%5BFE%5DInflearn_WarmingUP_Club_Study_2nd/day_93주차 회고그동안 리액트로 진행한 프로젝트가 있었기 때문에 강의 듣기 전에 자신만만한 상태였는데 강의 시작하고 전 그냥 리액트의 리도 모르는 사람이 되었습니다! 그리고 제가 지금까지 해온 학습은 학습이 아니었구나를 깨닫게 되었습니다. 진짜 너무나도 얕은 지식으로 개발하고 있었더라구요.. 반성하게 됐습니다.리액트 강의를 듣는데 next.js랑 CI/CD까지 배울 수 있었다니.. 너무 좋은 기회가 됐고 next.js부분 부터 강의 듣기로도 바빠서 배운 내용 정리도 못했는데 다시 복습하면서 천천히 정리해 봐야겠습니다. 그리고 항상 상태관리 라이브러리로 zustand만 사용했었는데 리덕스 보니까 설계부터 중요하다고 느꼈습니다.미션을 다 못 끝냈지만.. 최대한 빠르게 끝내보겠습니다!!

[Practical Testing: 실용적인 테스트 가이드] 회고 4주차

출처 : Practical Testing: 실용적인 테스트 가이드 학습 내용 요약섹션6 Spring & JPA 기반 테스트테스트케이스 세분화Presentation Layer파라미터 검증Persistence, Business Layer는 Mocking 처리 후 테스트@Transactional /* * readOnly = true : 읽기 전용 * CRUD에서 CUD 동작 X / only Read * JPA : CUD 스냅샷 저장, 변경감지 X (성능 향상) * * CQRS - Command(CUD) / Read Query 분리 * Read 빈도가 훨씬 많음 * Read에 의해 CUD가 영향 받아도 안되고 CUD에 의해 Read Query가 영향 받아서도 안됨 * */Dummy : 아무 것도 하지 않는 깡통 객체Fake : 단순한 형태로 동일한 기능은 수행하나, 프로덕션에 쓰기에는 부족한 객체(FakeRepository)stubbing(상태 검증)미리 준비한 결과를 제공하는 객체, 그 외에는 응답하지 않음mock 객체의 행위에 원하는 응답 입력Spy : Stub이면서 호출된 내용을 기록하여 보여줄 수 있는 객체, 일부는 실제 객체처럼 동작시키고 일부만 stubbing 할 수 있다Mock(행위 검증) : 행위에 대한 기대를 명세하고 그에 따라 동작하도록 만들어진 객체  @Mock, @MockBean, @Spy, @SpyBean, @InjectMocks 의 차이@Mock타겟 객체의 껍데기를 생성다른 객체에 의존성을 주입하려면 해당 객체에 @InjectMocks 필요테스트 클래스에 @ExtendWith(MockitoExtension.class) 필요Mockito.when(mailSendClient.sendEmail(anyString(), anyString(), anyString(), anyString())) .thenReturn(true); BDDMockito.given(mailSendClient.sendEmail(anyString(), anyString(), anyString(), anyString())) .willReturn(true); BDDMockito는 Mockito.when이 given에 해당하는 내용이지만 네이밍이 when이로 발생하는 부조화 방지@MockBean껍데기를 Bean으로 등록테스트 클래스에 @SpringBootTest, 주입 대상에 @Autowired 필요@Spy객체의 기능 일부만 stub하고 나머지는 실제 기능 호출테스트 클래스에 @ExtendWith(MockitoExtension.class) 필요doReturn(true) .when(mailSendClient) .sendEmail(anyString(), anyString(), anyString(), anyString());@SpyBean@Spy Bean으로 등록테스트 클래스에 @SpringBootTest, 주입 대상에 @Autowired 필요@SpyBean 대상이 인터페이스인 경우 구현체가 스프링 컨텍스트에 등록되어있어야함@InjectMocks@SpringBootTest가 아닌 경우 @Mock, @Spy 설정된 객체를 타겟 객체에 주입Classicist vs MockistClassicist실제 기능 테스트 필요외부 시스템은 모킹처리 필요내부 기능 테스트라면 실제 기능 확인Stubbing이 누락된 경우?Mockist개별 레이어별로 모킹하여 테스트하면 충분 더 나은 테스트를 위한 구체적인 조언(섹션8)한 문단에 한 주제if 문 지양단위 테스트의 목적이 분명해야함 완벽하게 제어하기메서드 내에서 변경될 수 있는 값은 외부에서 주입하기LocalDateTime.now() 등테스트에서는 LocalDateTime.now() 지양 (영향도 검토 없이 무분별하게 사용되는 문제) 테스트 환경의 독립성 보장given 절에서 테스트가 실패하지 않도록 구성하기생성자를 이용한 given절 구성 지향 (팩토리 메서드는 지양)  테스트 간 독립성 보장테스트별 공유자원 사용 지양 (테스트별 다른 given절 활용)테스트 순서에 무관하게 같은 결과 발생객체의 여러 상태 변경을 확인해야하는 테스트는 @DynamicTest 활용 한 눈에 들어오는 Test Fixture 구성Test Fixture테스트를 위해 원하는 상태로 고정시킨 일련의 객체given절에서 활용됨Fixture 생성 메서드는 테스트에 필요한 메서드만 파라미터로 받기 (나머지는 고정값)@BeforeAll모든 테스트 실행 전 1번 수행@BeforeEach각 테스트 실행 전 수행given절 생성 지양 최하단 메서드에서 해당 내용 확인하려면 긴 스크롤 이동 필요모든 테스트에 영향 발생각 테스트 입장에서 아예 몰라도 테스트 이해하는 데에 문제가 없는 사항수정해도 모든 테스트에 영향을 주지 않는 코드@AfterAll모든 테스트 실행 후 1번 수행@AfterEach각 테스트 실행 후 수행data.sql 등을 활용한 given 절 생성 지양 (테스트 파편화)Test Fixture 생성 빌더 구성 클래스는 비추천 (난잡화) Test Fixture 클렌징deleteAll()테이블의 전체 데이터 조회 후 건별 삭제데이터가 많은 경우 성능 이슈 발생 가능성 있음순서 고려 필요deleteAllInBatch()delete from tableA테이블의 필드가 B테이블에 외래키로 활용되고 있는 경우 B테이블 데이터 삭제 후 A테이블 삭제 필요 (순서 중요)@TransactionalSide Effect 고려 필요 @ParameterizedTest특정 데이터들을 바꿔가며 테스트하고 싶을 때 활용CsvSource@ParameterizedTest @CsvSource({ "HANDMADE, false", "BOTTLE, true" , "BAKERY, true" , }) @DisplayName("재고타입인지 테스트") public void test2(ProductType productType, boolean expected) { // given // when boolean result = ProductType.containsStockType(productType); // then assertThat(result).isEqualTo(expected); }MethodSource메서드의 내용이 given에 해당하므로 테스트 위에 위치시킨다.private static Stream<Arguments> ofProductTypes(){ return Stream.of( Arguments.arguments(ProductType.HANDMADE, false), Arguments.arguments(ProductType.BOTTLE, true), Arguments.arguments(ProductType.BAKERY, true) ); } @ParameterizedTest @MethodSource("ofProductTypes") @DisplayName("재고 관련 상품타입 확인") void initializeGame(ProductType productType, boolean expected) { // given // when boolean result = ProductType.containsStockType(productType); // then assertThat(result).isEqualTo(expected); } @DynamicTest공유 변수를 사용하여 테스트하는 것은 지양해야하지만 단계별 시나리오 테스트가 필요한 경우 활용@DisplayName("재고 차감 시나리오 테스트") @TestFactory Collection<DynamicTest> stockDeductionDynamicTest(){ Stock stock = Stock.create("001", 1); return List.of( DynamicTest.dynamicTest("재고로 주어진 개수만큼 차감할 수 있다.", () ->{ // given int quantity = 1; // when stock.deductQuantity(quantity); // then assertThat(stock.getQuantity()).isZero(); }), DynamicTest.dynamicTest("재고보다 많은 수의 수량으로 차감 시도하는 경우 예외가 발생한다.", () ->{ // given int quantity = 1; // when // then assertThatThrownBy(() -> stock.deductQuantity(quantity)) .isInstanceOf(IllegalArgumentException.class) .hasMessage("차감할 재고 수량이 없습니다."); }) ); } 테스트 수행도 비용이다. 환경 통합@SpringBootTest는 상이한 환경마다 테스트 서버 기동이 필요하여 공통 환경을 추출하여 서버 기동 횟수 줄이기@ActiveProfiles, @MockBean 등 공통 요소를 Layer별 구성 또는 필요에 따라 설정@WebMvcTest(controllers = { OrderController.class, ProductController.class, }) public abstract class ControllerTestSupport { @Autowired protected MockMvc mockMvc; @Autowired protected ObjectMapper objectMapper; @MockBean protected OrderService orderService; @MockBean protected ProductService service; } class OrderControllerTest extends ControllerTestSupport { @Test ... }private 메서드 테스트는 어떻게?테스트 지양 - public 메서드를 통해서 검증하면 충분꼭 테스트 필요해보인다면 객체를 분리할 시점인지 고민 테스트에만 필요한 메서드는 어떻게? (프로덕션 코드에 필요없는 메서드)Test Fixture 생성 메서드 등만들어도 되지만 최대한 지양해야함 부록(섹션9)학습 테스트잘 모르는 기능, 라이브러리, 프레임워크를 학습하기 위해 작성하는 테스트여러 테스트 케이스를 정의하고 검증하면서 구체적인 동작과 기능 학습 가능팀적으로 학습이 필요하다면 작성 후 공유  Spring REST Docs테스트 코드를 통한 API 문서 자동화 도구API 명세를 문서로 만들고 외부에 제공함으로써 협업을 원활하게 한다.AsciiDoc(MarkDown)을 사용하여 문서 작성됨테스트를 통과해야 문서가 만들어져 신뢰도가 높음프로덕션 코드에 비침투적이다.코드 양이 많다.설정이 어렵다. Swagger적용이 쉽다.문서에서 바로 API 호출 수행 가능프로덕션 코드에 침투적테스트와 무관하여 신뢰도가 떨어짐

뒤늦게 작성하는 2주차 발자국

미션을 수행하고, 메모에만 옮겨놓고 완수 메모를 남기려고 확인해보니 2주차 발자국을 안 적었었다.2주차에는 실제로 객체지향을 적용하는데 필요한 테크닉과 실제로 리팩토링을 실행해보는 과정그리고, Practical Testing 강의를 시작하는 파트였다.이전에, 우빈님의 라이브에서 내 코드가 피드백 부분에 있었는데 라이브를 듣지 못해서 너무 아쉬웠다.해당 방식이 오버엔지니어링이라는 피드백을 받았는데, 그 부분에 있어서 타당한 근거가 있었다.하지만 요구사항보다는 더 들어갔기에 오버엔지니어링은 맞을 것이다. 그렇다면 우리는 언제쯤 하나로 통합하여 관리 포인트를 줄이는 작업을 할 수 있을까?Value ObjectValue Object는 늘 불변을 유지해야 한다.어떠한 로직이 들어가더라도 새로운 값이 반환이 되어야 한다. 즉, 새로이 객체를 생성하여야 한다.Value Object는 Entity와 달리 식별자가 없기 때문이다.객체의 책임과 응집도이 부분은 항상 고민이 많다. 어느정도로 책임을 줄여야하지? 이정도면 다른데서는 수정 될 이유가 없을까?정말 수정되지 않으려면 정말 작게 만들어야 하는데 그 부분이 참 어렵다. 단위 테스트Junit을 통한 단위테스트와 테스트 개념, 그리고 인터페이스를 활용한 테스트하기 어려운 영역을 분리하는 개념에 대해서 배웠다. 이 부분은 늘 테스트를 짜면서 실천하고 있기에 더 중요하다는 것을 인지하는 계기가 되었다.

클린코드테스트코드

인프런 워밍업 클럽 스터디 백엔드 클린 코드, 테스트 코드를 마치며

먼저, 이번 주차에 학습한 내용에 대해서 정리를 하고 시작한다.클린 코드도, 테스트 코드도 모두 지금 나의 회사가 처해있는 코드의 상황에서 더 어떻게 개선해나갈 수 있을까? 를 고민을 하고 해당 스터디를 진행하면서 이러한 고민거리를 해소하고자 하였다.그리고, 스터디를 진행하면서 많은 부분이 해소가 되기도 하였다.특히, Mock을 대하는 자세가 회사에 들어오기 전과 후가 조금 달라졌다.실제로 회사내에서 Facade 코드를 다루기 위해 Mock이 많이 이용된다. 이 부분은 리팩토링을 위해 테스트를 작성하고자 이루어졌다고 생각한다. 현재 있는 코드에서 리팩토링을 할 계획인데 단위 테스트를 전부 작성을 하게 된다면 리팩토링을 하는 과정에서 테스트 코드가 지속적으로 수정 될 것이기 때문이다.그렇기에, 비슷한 상황에서 테스트 코드가 빠르게 돌아가는 상황이 필요했는데, 지금 현재 있는 상황에서는 더 개선을 하려면 Application Context Cache 를 유지하면서 테스트 코드의 Spring Container를 유지하여 테스트 코드가 빠르게 돌아가도록 하여 리팩토링을 하는게 좋을 것 같다고 생각한다.추가적으로, Presentation Layer에서의 테스트와 영속성 계층의 테스트에 대해서 궁금한 부분이 있어 우빈님에게 질문을 드렸고 많은 인사이트를 얻어 갈 수 있었다.해당 질문의 답변은 다음에서 찾아 볼 수 있다.https://www.inflearn.com/community/questions/1409734/%EC%98%81%EC%86%8D%EC%84%B1-%EA%B3%84%EC%B8%B5%EA%B3%BC-e2e-%ED%85%8C%EC%8A%A4%ED%8A%B8%EC%97%90-%EB%8C%80%ED%95%B4-%EC%A7%88%EB%AC%B8%EC%9D%B4-%EC%9E%88%EC%8A%B5%EB%8B%88%EB%8B%A4 마치며이번 스터디는 내가 회사를 위해 더 나은 회사로 나아가기 위해 나 자신의 성장뿐만 아니라 회사의 성장을 위해서 신청을 하게 되었고, 많은 부분 코드 습관이 고쳐지게 되었다. 특히, private 메서드를 사용하는 것을 지양을 하였던 부분(모든 메서드를 테스트 하고 싶은 마음에)에서 요즘은 오히려 읽기 쉬운 코드로 작성하고자 하고 있다.이 부분은 꼭 테스트가 필요한 걸까? 에 대해서 많은 질문을 던지며 코드를 리팩토링 해나가고 있다.회사를 다니면서 스터디를 참가하는 것이 쉽지는 않았지만 끝 마칠 수 있었던 나 자신에게 칭찬 한마디 던지고, 잘 이끌어준 우빈님에게 칭찬 백마디 전달하고 싶다.

백엔드테스트코드

Xangle*

[Rising Star Week 2024] 반드시 주목해야 할 Web3 재단들! 💫

Rising Star Week 2024📍 위워크 선릉 3호점 2층 메인라운지 (서울 강남구 선릉로 428 2층)🗓 2024년 11월 26일 - 28일, 19:00~21:30 Rising Star Week 2024는 주목받고 있는 9개의 Web3 재단들이 한자리에 모여 혁신적인 프로젝트를 공유하는 자리입니다. 업계 리더들과 자유롭게 소통하며 새로운 아이디어와 협력 기회를 만들 수 있는 네트워킹 기회를 놓치지 마세요! 👉신청하기 : https://lu.ma/bxcdmv0h Daily Session Lineup 💡💡Day 1 (Tuesday, Nov 26th)​#Solayer솔라나의 탈중앙화 프로토콜 클라우드 인프라The Decentralized Protocol Cloud Infrastructure on Solana#Babylon비수탁형 무신뢰 기반의 비트코인 스테이킹 프로토콜Non-custodial/Trustless Bitcoin Staking Protocol​#Orderly NetworkCeFi와 DeFi의 강점을 결합한 궁극의 하이브리드 거래소The Ultimate Hybrid Exchange Combining the Strengths of CeFi & DeFi​💡Day 2 (Wednesday, Nov 27th)​#Synfutures누구나 어떤 자산도 자유롭게 거래할 수 있는 온체인 오더북 Perp DEXPermissionless On-chain Orderbook: Onchain Perp For Any Asset​#Monad병렬 처리로 강화된 초고속 EVM 호환 레이어1Parallel EVM Layer1 with 10,000 TPS with 100% EVM-compatibility​#Aylab블록체인으로 웹3 마케팅을 혁신하는 통합 플랫폼 솔루션Integrated Platform Solution Revolutionizing Web3 Marketing​💡Day 3 (Thursday, Nov 28th)​#Initia앱 맞춤형으로 유연하게 즉시 구축 가능한 롤업 생성을 상호 연결된 앱 네트워크에 가능하게 하는 프로토콜Enabling creation of flexible, app-specific, production-ready roll ups into an interwoven network of applications​#Berachain유동성 증명으로 PoS의 한계를 극복한 커뮤니티 주도 블록체인Community-Driven Blockchain Overcoming PoS Limitations Through Proof of Liquidity​#Morph소비자를 위한 체인: 하이브리드 롤업으로 만드는 블록체인의 일상화Consumer Chain: Integrating Blockchain into Everyday Life with Hybrid Rollup✔ 주차 안내💡주차비 지원은 불가한 점 양해해주시기 바랍니다.🅿 선릉역 위워크 선릉3호점 민영주차장이용 요금 : 30분당 3,000원행사장 건물 내 유료주차 가능하나, 정기주차 등으로 주차공간이 협소하오니, 가급적 대중교통 이용 바랍니다.✔ 식사 안내💡행사장 내 제공될 예정입니다. 맛있게 즐겨주세요! 🍔 & 🍗 & 🍕 + 🍺Day별로 다르게 간단한 식사류와 맥주가 제공될 예정입니다. 

블록체인AylabBabylonBerachainInitiaMonadMorphOrderlyNetworkSolayerSyfuturesXangle

winnercold

워밍업 클럽 스터디 - 2기 4주차 발자국

해당 글은 [인프런 워밍업 클럽 2기 클린 코드 & 테스트 코드]에 참가하여 박우빈님의 <Practical Testing: 실용적인 테스트 가이드> 강의를 듣고 작성한 글입니다. 강의를 통해 배운것Test Double한 문단에는 한 주제를 1. Test DoubleDummy : 아무것도 하지 않는 깡통 객체Fake : 단순한 형태로 동일한 기능은 수행하나, 프로덕션에서 쓰기에는 부족한 객체Stub : 테스트에서 요청한 것에 대해 미리 준비한 결과를 제공하는 객체Spy : Stub이면서 호출된 내용을 기록하여 보여줄 수 있는 객체, 일부는 객체처럼 동작 시키고 일부만 Stubbing 할 수도 있다.Mock : 행위에 대한 기대를 명세하고, 그에 따라 동작하도록 만들어진 객체Mock 은 Stub이 아니다. Stub을 상태를 검증, Mock 은 행위를 검증2. 한 문단에는 한 주제테스트 환경의 독립성을 보장테스트 간 독립성을 보장 (공유자원 관리)Test Fixture 구성테스트를 위해 원하는 상태로 고정시킨 일련의 객체테스트 수행도 비용이다.환경 통합, @DataJPATest 보다는 @SpringBootTest 사용 권장private 메서드는 테스트할 필요가 없다. 테스트가 꼭 필요하다고 생각이 된다면 추상화가 잘 되었는지 다시 생각해보고 리팩토링하기 회고이번 강의를 끝으로 워밍업 클럽 스터디가 끝났다. 개발자라면 누구나 클린 코드와 테스트 코드를 잘 작성하고 싶을 것이다. 나 또한 그런 바램으로 이 스터디에 참여하게 되었는데 이 두 강의를 모두 자기 것으로 만든다면 나도 5년 후에는 좀더 나은 환경에서 개발자로 일하고 있지 않을까 기대해본다. 그렇게 하기 위해서는 다시 이 두강의를 복습하러 가야겠다.  

백엔드

winnercold

워밍업 클럽 스터디 - Day4

해당 글은 [인프런 워밍업 클럽 2기 클린 코드 & 테스트 코드]에 참가하여 박우빈님의 <Readable Code: 읽기 좋은 코드를 작성하는 사고법> 강의를 듣고 작성한 글입니다. 미션 2-1AS-ISpublic boolean validateOrder(Order order){ if(order.getItems().size() == 0) { log.info("주문 항목이 없습니다."); return false; }else{ if(order.getTotalPrice() > 0){ if(!order.hasCustomerInfo()){ log.info("사용자 정보가 없습니다."); return false; }else{ return true; } }else if(!(order.getTotalPrice() > 0)) { log.info("올바르지 않은 총 가격입니다."); return false; } } return true; }  validateOrder가 하는 일 파악하기주문 항목이 있는지 체크가격이 0보다 큰지 체크사용자 정보가 있는지 체크1. early return 적용하기early return을 적용함으로써 else의 사용을 지양한다.public boolean validateOrder(Order order){ if(order.getItems().size() == 0) { log.info("주문 항목이 없습니다."); return false; } if(!order.getTotalPrice() > 0){ log.info("올바르지 않은 총 가격입니다."); return false; } if(!order.hasCustomerInfo()){ log.info("사용자 정보가 없습니다."); return false; } return true; }2. 부정어를 대하는 자세부정어구를 쓰지 않아도 되는 상황인지 체크부정의 의미를 담은 다른 단어 존재하는지 체크3. getter 사용 자제객체에 직접 메세지를 보내 확인 하는 것이 무례하지 않다.4. 예외처리OrderException 클래스 생성public class OrderException extends RuntimeException{ public OrderException(String message) { super(message); } } TO-BEpublic boolean validateOrder(Order order){ if(order.isItemEmpty()) { throw new OrderException("주문 항목이 없습니다."); } if(order.isTotalPriceLessThanZero()){ throw new OrderException("올바르지 않은 총 가격입니다."); } if(order.isCustomerInfoMissing()){ throw new OrderException("사용자 정보가 없습니다."); } return true; } // Order private boolean isItemEmpty() { return this.items.isEmpty(); } private boolean isTotalPriceLessThanZero() { return this.items.stream() .mapToInt(Item::getPrice).sum() <= 0; } private boolean isCustomerInfoMissing() { return this.customInfo.isEmpty(); }  미션 2-2. SOLID 에 대해 자기만의 언어로 적어보기 1. SRP : 단일 책임 원칙레스토랑에서 일하는 사람들에 비유해 적어보고자 한다. 레스토랑에 주방장, 웨이터, 청소부 가 있다고 생각해 보면, 주방장은 요리만, 웨이터는 주문과 서빙만, 청소부는 청소만 해야 한다. 만약 주방장이 서빙까지 맡게 된다면 주방 일이 제대로 안 될 수 있다. 이와 같이 모든 역할이 각자 하나의 책임만 맡고, 그 일을 잘하는 것이 단일 책임 원칙이라고 생각한다.2. OCP : 개방 폐쇄 원칙레스토랑에 새로운 메뉴를 추가할 때, 기존 주방의 동선 이나 도구 배치를 크게 바꾸지 않고 새로운 메뉴를 준비할 수 있어야 한다. 주방의 구조나 기존 메뉴는 그대로 두고, 필요한 추가 장비나 재료만 추가하는 식이다. 새로운 요구사항에 맞게 확장(새로운 메뉴 추가)은 쉽게 가능하지만, 기존 시스템 (기존 메뉴 및 도구 배치)은 유지하는 것이 이 원칙이라고 생각한다.3. LSP : 리스코프 치환 원칙예를 들어 새로운 웨이터가 채용 되더라도 기존 웨이터가 하던 일을 동일하게 할 수 있어야 한다. 만 약 새로 온 웨이터가 “서빙은 할 수 있지만 손님과의 소통은 못 한다”라고 하면 문제가 생긴다. 따라 서 기존 역할을 무리 없이 수행할 수 있도록 상호 대체 가능해야 하는 원칙이라고 생각한다.4. ISP : 인터페이스 분리 원칙모든 직원이 모든 일을 다 할 수 있도록 하는 대신, 각자의 역할에 맞는 것만 하도록 하는 것이 더 효율적이다. 웨이터는 서빙과 주문만 받고, 주방장은 요리와 재료 준비만, 청소부는 청소만 할 수 있게 역할 별로 필요한 업무만 하는 것이 인터페이스 분리 원칙이라고 생각한다.5. DIP : 의존성 역전 원칙레스토랑에서 업주 마음대로 직원에게 지시하는 것보다, 문서로 만들어 일관된 방식으로 전달하는 것이다. 이렇게 하면 업주나 직원이 바뀌더라도 직원들은 동일한 업무 지침에 따라 일할 수 있다. 즉, 업주가 아닌 지침서에 의존하도록 하는 것이다. 이 원칙을 통해 레스토랑 운영이 특정 사람의 방식에 좌우되지 않고, 유연하게 유지 될 수 있도록 한다.

whffkaos007

워밍업 클럽 2기 BE 클린코드&테스트 - 회고 4회

Practical Testing : 실용적인 테스트 가이드 - 회고 4회 이 글은 박우빈님의 강의를 참조하여 작성한 글입니다. 벌써 4주차가 되었습니다. 인프런 워밍업 클럽의 마지막 회고입니다. 다른 것도 한다는 핑계로 시간을 많이 투자하지 못한 거 같아 아쉽기도 하지만 최대한 잘 녹여서 작성하겠습니다. 테스트 작성에 대한 많은 팁을 알게 되어 좋았지만 테스트를 바라보는 여러 관점을 알게 되고 이에 대한 주관이 나름 생긴 거 같아 좋은 시간이었습니다. 학습 목차Spring & JPA 기반 테스트: Presentation Layer(제외) Mock을 마주하는 자세더 나은 테스트를 작성하기 위한 구체적 조언학습 테스트(제외) Mock을 마주하는 자세Mock에 대한 찬반 의견이 있다. 물론 현재 상황(구현 기간, 서비스 특성 등)에 따라 얼마나 Mock 처리의 빈도가 달라질 것이다.기본적인 Mock에 대한 의견은 Classicist와 Mockist 로 나뉜다. Classicist VS Mockist말그대로 Mock을 하면 안 된다와 해야 한다로 나뉜다. Classicist는 여러 객체(모듈)이 상호작용하기에 A와 B에 대한 통합 테스트를 구현하는 경우에 A, B 둘 다 실제 객체를 사용해야 한다고 Mockist는 이미 A, B 각 객체에 대한 단위 테스트가 이뤄졌기에 A, B에 대한 통합 테스트를 구현할 때 A 또는 B 하나를 Mock 처리해서 하는 것이 비용과 시간에 대해 더 합리적이라고 주장한다.  더 나은 테스트를 작성하기 위한 구체적 조언완벽하게 제어하기// 시간에 따라 주문 여부가 정해지는 로직 void createOrderWithCurrentTime(){ CafeKiosk cafeKiosk = new CafeKiosk(); Americano americano = new Americano(); cafeKiosk.add(americano); Order order = cafeKiosk.createOrder(LocalDateTime.of(2023,1,17,10,0)); assertThat(order.getBeverage()).hasSize(1); assertThat(order.getBeverage().get(0).getName()).isEqualTo("아메리카노"); } // 시간, 외부 API 등 변할 수 있는 요소는 외부로 빼서 가져오기 // 예로 시간을 파라미터로 가져오는 게 아니라면 // LocalDateTime.now()가 내부 로직에 있다면 테스트를 실행하는 // 시간마다 성공 여부가 다를 것이다. 따라서 제어가 어려운 것은 // 외부로 내보내 완벽하게 제어하자. public Order createOrder(LocalDateTime currentTime){ // 위 시간 인자를 통해 지정한 시간 내인지 확인하는 로직 // 가능하면 주문 생성, 아니면 예외 발생 }  테스트 환경의 독립성을 보장하자(테스트 하나에는 하나만 검증)void createOrderWithNoStock(){ //given LocalDateTime registeredDateTime = LocalDateTime.now(); Product product1 = createProduct(BOTTLE, "001", 1000); Product product2 = createProduct(BAKERY, "002", 2000); Product product3 = createProduct(HANDMADE, "003", 3000); Stock stock1 = Stock.create("001", 2); Stock stock2 = Stock.create("002", 2); stock1.deductQuantity(3); // 행위1 stockRepository.saveAll(List.of(stock1, stock2)); OrderCreateServiceRequest request = OrderCreateServiceRequest.builder() .productNumber(List.of("001","001","002", "003")); .build(); // when/then (행위2) assertThatThrownBy( () -> orderService.createOrder(request, registerDateTime)) .isInstanceOf(IlligalArgumentException.class) .hasMessages("재고가 부족한 상품이 있습니다")); 밑줄 친 코드를 보자. 테스트는 하나의 행위만 검증해야 한다. 위 상황에서는 현재 재고보다 더 많은 상품을 주문했을 때, 예외가 발생하는 지 검증하는 테스트이다. given 절에 밑줄 코드를 보면 어떠한 행위가 또 들어가 있다. 즉, 상황을 준비만 해야 하는 given 절에서 어떠한 행위가 일어났다. 위 테스트 코드를 이해하려면 밑줄 친 코드(메서드)의 행위를 알기 위한 논리적 사고가 발생하여 독립적이지 못한 테스트이다. }  한 눈에 들어오는 Test Fixture 구성하기테스트를 작성하다 보면 공통적인 given절로 중복되는 코드가 발생한다. 보통, 코드의 중복을 줄이기 위해 @BeforeEach, @BeforeAll, @Afrer... 등이나 data.sql 파일로 손 쉽게 데이터의 삽입이 이뤄진다. (삭제는 테스트 간 결합도를 낮추기 위해 사용하므로 @BeforeEach 혹은 @Transactional을 사용하자) 비즈니스 로직 개발 관점에서는 당연히 코드의 중복을 줄이는 것이 합리적이며 유지보수성이 좋다고 생각하지만 테스트에서는 위와 같은 방법을 지향해야 한다. 테스트는 말 그대로 테스트고 위와 같은 방법을 사용하면 모든 테스트가 @BeforeEach, data.sql 등에 강결합하여 의존성이 커진다. 위 설정 과정이 달라졌을 때, 어떤 결과가 나올지 모른다. 따라서 테스트 코드가 길어지더라도 given 절에서 설정하는 것이 올바르며 한 눈에 파악하기 쉽다.(data.sql로 given을 구성하면 테스트를 볼때마다 data.sql로 이동하기에 파악하기 어렵다.[파편화]) ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ 1. 각 테스트 입장에서 아예 몰라도 테스트 내용을 이해하는 데에 문제가 없는가? 2. 수정해도 모든 테스트에 영향을 주지 않는가? 위 질문에 해당하지 않는다면 @BeforeEach와 같은 기능을 사용해도 괜찮다. 위 내용을 떠나서라도 @BeforeEach을 사용하더라도 전달하고자 하는 도메인 개념이나 로직 등 관련 내용이 충분히 전달되면 괜찮다. 핵심은 도메인이다.  Test Fixtuer 클렌징 @BeforeEach void beforEach(){ // 1 orderProductRepository.deleteAllInBatch(); orderRepository.deleteAllInBatch(); productRepository.deleteAllInBatch(); // 2 orderProductRepository.deleteAll(); orderProductRepository.deleteAll(); orderProductRepository.deleteAll(); } 1번은 해당 테이블 데이터 전체를 삭제하겠다는 의미이다. 2번은 해당 테이블 데이터 전체를 조회하고 1씩 삭제하겠다는 의미이다. 데이터가 많을수록 성능 차이가 커지므로 1번을 사용하자. 대신 참조키, 무결성 관계를 고려해서 순서에 맞게만 사용하면 된다. ex) orderRepository.deleteAllInBatch(); orderProductRepository.deleteAllInBatch(); productRepository.deleteAllInBatch(); 위 예시처럼 실행하면 orderProduct가 order를 참조하기 있기 때문에 테스트가 실패한다. [ order <- 일대다 -> orderProduct ] ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ **추가로 @Transactional, @BeforeEach 중 어떤 것을 사용할 지는 상황에 맞게 선택하면 된다.  테스트 간편화 기능 @ParameterizedTest : 다양한 인자를 통해서 테스트의 완성도를 높이거나 코드를 줄일 수 있음 @CsvSource, @MethodSource 등 제공하는 값을 통해서 메서드 인자로 넘기면 해당 수만큼 실행한다. @DynamicTest @Test 대신 @TestFactory를 사용해야 하고 Collection을 기준으로 연쇄적인 기능을 가진 객체를 사용하면 된다.(List, stream 등) 연쇄적인 테스트가 필요하다면 해라. 따로 따로 하는 것보다 연쇄적으로 하는 것이 좀 더 직관적일 수 있다. 예로, 해피 케이스랑 예외 케이스를 따로 테스트를 작성해서 검증할 수 있다. 하지만 해당 어노테이션을 사용하면 하나의 테스트에서 연쇄적으로 검증할 수 있다. '성공 -> 예외' 한 묶음으로. 하지만 given-when-then 절이 중첩 if 문 같이 사용되어 가독성이 떨어질 수 있으니 적절하게 사용하자. 추가로 연쇄적인 시나리오를 위해서도 사용 가능하다. 재고 차감을 예시로 보면 재고가 1인 경우에 감소하고 0인 경우 감소하는 경우를 연속으로 확인할 수 있어 좀 더 가독성이 높다.  private 메서드는 테스트 해야 할까? 외부 관점(컨트롤러, 외부 호출자 등)에서는 공개된 API만 사용한다. private 메서드를 직접적으로 호출하는 경우는 없으며 공개 API(public 메서드)를 호출한다. 또한 공개 API를 호출하면서 내부에 있는 private 메서드도 호출한다. 즉, 공개 API가 검증이 되면 내부에 있는 기능 또한 검증되므로 굳이 private 메서드를 검증할 필요가 없다. 결국 private 메서드는 테스트 할 필요가 없다. 그럼에도 이런 생각이 든다면 ‘**객체를 분리할 시점인가?‘**라는 질문을 해라.위와 같은 생각이 든다면 객체의 책임이 복합적일 수도 있다는 신호라고 한다.(사실, 이러한 경험이 없어 위와 같은 느낌이 아직은 모호하게 다가온다.)  개인 의견기존에는 고려하지 못한 부분에 대해 많이 알게 되어 테스트 코드에 대한 주관이 조금은 생겼다. 물론 아직도 명확하게 답을 할 수 있는 것들이 적지만 충분히 의미 있는 시간이었다.위에서도 말했듯이 절대적인 것은 없기에 자신이 처한 상황에 따라 되게 유동적으로 테스트 코드의 중요성과 작성법 등 변한다. 상황에 맞게 적용할 수 있게 여러 방법을 시도해 보는 것도 좋은 거 같다.번외로 가장 인상 깊었던 부분은 클린 코드 강의의 목수 이야기다. 대게 새로운 것을 통해 기존의 방식을 변경하는데 어려움을 겪어 거부하기도 하고. 기존에 사용하는 방식만 안 다면 더 쉽고 좋은 방법이 있더라도 이를 적용할 생각조차 하지 않는다는 내용이다.새로운 기술을 학습하고 적용하는 것은 현실을 고려했을 때 어렵긴 하지만 새로운 기술에 대한 학습과 적용을 두려워하지 않는 습관을 기르는 것이 좋다는 것을 상기시켜줘서 좋았다. 학습적인 측면을 넘어 개발자로서 필요한 자세나 습관에 대한 내용도 담겨 있어 좋은 선생님이라 생각합니다. 

백엔드테스트코드인프런워밍업클럽

whffkaos007

워밍업 클럽 2기 BE 클린코드&테스트 - 회고 3회

이 글은 박우빈님의 강의를 참조하여 작성한 글입니다. 벌써 3주차가 되었습니다. 읽기 좋은 코드 관련 강의가 마무리되고 실용적인 테스트 강의를 시작했습니다. 부족한 부분도 있겠지만 열심히 달려온 과정을 적겠습니다. 강의 목적테스트 코드의 중요성과 작성해야 하는 이유테스트 코드를 작성하는 방법  테스트의 필요성테스트는 기능에 대한 부가적인 요소이다. 실제로는 기능을 구현하기 바쁘다. 그런데도 왜 테스트의 중요성이 강조될까?테스트를 작성하면 위와 같은 단점이 있다. 반대로 테스트를 작성하지 않는다면 어떻게 될까? 커버할 수 없는 영역 발생경험과 감에 의존 → 인간이기에 이럼.늦은 피드백 → 수동으로 테스트 해야 함.유지보수 어려움 → 확장, 수정이 일어난다면 어디까지 영향을 미칠지 모름소프트웨어 신뢰성 낮음 → 언제 어디서 버그가 터질지 불안함  테스트 코드를 작성하지 않는다면변화가 생기는 매순간마다 발생할 수 있는 모든 Case를 고려해야 한다.변화가 생기는 매순간마다 모든 팀원이 동일한 고민을 해야 한다.빠르게 변화하는 소프트웨어의 안정성을 보장할 수 없다.테스트 코드가 병목이 된다면프로덕션 코드의 안정성을 제공하기 힘들어진다.테스트 코드 자체가 유지보수하기 어려운, 새로운 짐이 된다.잘못된 검증이 이루어질 가능성이 생긴다. 테스트 코드를 작성하지 않는다면변화가 생기는 매순간마다 발생할 수 있는 모든 Case를 고려해야 한다.변화가 생기는 매순간마다 모든 팀원이 동일한 고민을 해야 한다.빠르게 변화하는 소프트웨어의 안정성을 보장할 수 없다.테스트 코드가 병목이 된다면프로덕션 코드의 안정성을 제공하기 힘들어진다.테스트 코드 자체가 유지보수하기 어려운, 새로운 짐이 된다.잘못된 검증이 이루어질 가능성이 생긴다.   그럼 올바른 테스트 코드를 서비스에 적용시킨다면 어떤 결과를 가져올까?올바른 테스트 코드는자동화 테스트로 비교적 빠른 시간 안에 버그 발견, 수동 테스트에 드는 비용을 크게 절약소프트웨어의 빠른 변화를 지원한다.팀원들의 집단 지성을 팀 차원의 이익으로 승격시킨다.가까이 보면 느리지만, 멀리 보면 가장 빠르다.    테스트 케이스 세분화하기 테스트에는 해피 케이스와 예외 케이스가 있다.   우리는 요구사항대로 기능을 구현할 때, 이외 여러 경우를 고려해야 한다 예를 들어 커피 주문하기에 대한 기능을 구현할 때는 커피의 개수가 1 이상이여야 한다는 숨겨진 조건이 있다.이처럼 숨겨진 조건을 고려하여 작성할 때 도움이 되는 것은 경계값 테스트이다. 경계값 : 범위(이상, 이하, 초과, 미만), 구간, 날짜 등경계값을 기준으로 테스트를 고려해야 기능(도메인)에 대한 명확한 인지에 도움이 되며 예외 상황도 쉽게 파악할 수 있다.   테스트하기 어려운 영역을 분리하기테스트 코드는 작성하기 쉬운 부분과 어려운 부분이 존재한다. 예를 들어 오전 10시부터 오후 2시까지만 주문이 가능한 조건이 있다 가정하자. order(List<Item> items){ LocalDateTime now = LocalDateTime.now(); if(now < 오전 10시 || 오후 2시 < now){ // 예외 발생 } ... } 위 메서드에 대한 테스트를 진행하면 어떻게 될까?테스트를 실행하는 시간에 따라 성공 여부가 달라질 것이다.그렇다면 이처럼 테스트하기 어려운 상황이 생기면 어떻게 해야 할까?바로 테스트하기 어려운 부분을 외부로 분리해야 한다.  order(List<Item> items, LocalDateTime time){ if(time< 오전 10시 || 오후 2시 < time){ // 예외 발생 } ... } 위 코드처럼 시간이란 테스트하기 어려운 영역을 외부로 분리하여 파라미터로 받는다. 이렇게 코드를 작성하면 테스트하는 시간마다 성공 여부가 달라지지 않는다.테스트라는 기능을 온전히 수행할 수 있을 것이다. 이처럼 우리는 테스트하기 어려운 부분이 있다면 이를 외부 세계로 분리하여 테스트하기 쉽게 만들어야 한다.그럼 이런 어려운 부분은 무엇이 있을까? 어려운 영역관측할 때마다 다른 값에 의존하는 코드현재 날짜/시간, 랜덤 값, 전역 변수/함수, 사용자 입력 등외부 세계에 영향을 주는 코드표준 출력, 메시지 발송, 데이터베이스에 기록하기 등쉬운 영역 → 순수함수(pure fuction)같은 입력에는 항상 같은 결과외부 세상과 단절된 형태테스트하기 쉬운 코드이러한 영역은 위와 같이 있지만 직접 경험하면서 어떤 부분을 분리하는 것이 더 좋을 지에 대한 고민을 해야 시야를 기를 수 있다. TDD:Test Driven Development TDD는 위 구조를 통해 테스트 코드를 작성하는 것이다. 구현 → 테스트 순이 아닌테스트 → 구현 순으로 진행하는 방법이다.왜 TDD가 좋을까? 어떤 가치를 지니지?가장 큰 가치 중 하나는 빠른 피드백이다. 선 기능 구현, 후 테스트 작성테스트 자체의 누락 가능성특정 테스트 케이스만 검증할 가능성(해피 케이스)잘못된 구현을 다소 늦게 발견할 가능성테스트를 먼저 작성한다면 테스트에 대한 고려에 대한 시야를 가질 수 있다. 선 테스트 작성, 후 기능 구현복잡도 낮은 테스트 가능한 코드로 구현할 수 있게 한다.유연하며 유지보수가 쉽다.쉽게 발견하기 어려운 엣지 케이스를 놓치지 않게 해준다.구현에 대한 빠른 피드백을 받을 수 있다.과감한 리팩토링이 가능하다.  TDD : 관점의 변화지금까지 기능 구현과 테스트의 관계를 봤을 때, 우리는 아래와 같이 기능과 테스트가 상호작용하는 구조를 추구해야 한다.기존에는 테스트는 구현부의 검증을 위한 보조 수단이었다면 TDD를 이용하면 테스트와 상호 작용하며 발전하는 구현부를 가질 수 있다.클라이언트 관점에서의 피드백을 주는 Test Driven.  테스트는 문서다. 문서란?프로덕션 기능을 설명하는 테스트 코드 문서다양한 테스트 케이스를 통해 프로덕션 코드를 이해하는 시각과 관점을 보완어느 한 사람이 과거에 경험했던 고민의 결과물을 팀 차원으로 승격시켜서, 모두의 자산으로 공유할 수 있다.우리는 테스트 코드를 통해 해당 기능이 어떻게 동작하는 지 파악할 수 있다. 해피 케이스와 예외 케이스를 통해 코드(도메인 지식)를 인지하는데 도움을 얻을 수 있고 기존의 테스트를 통해 잘못된 부분이나 놓친 부분을 파악할 수 있다.우리는 항상 팀으로 일한다. 팀원에게 어떻게 보일 지 항상 고민하면서 작성하는 습관을 기르자.DisplayName을 섬세하게@DisplayName("음료 1개 추가 테스트") // 1 @DisplayName("음료 1개를 추가하면 주문 목록에 담긴다.") // 2 우리는 신규 입사자다. 서비스의 테스트 코드를 봤을 때 1, 2 중 어떤 것이 테스트 코드의 담긴 의미를 더 많이 전달해주는가?바로 2번이다. 왤까? 명사의 나열보다 문장으로 표현하기우리는 좀 더 명확한 의미를 파악할 수 있다. 정보의 생략의 없기 때문이다.테스트 행위에 대한 결과까지 기술하기이 또한 해당 기능에 대한 모든 정보를 알기 위해 행위에 대한 결과까지 기술하자.도메인 용어를 사용하여 한층 추상화된 내용을 담기(메서드 자체의 관점보다 도메인 정책 관점으로)테스트의 현상을 중점으로 기술하지 말 것  특정 시간 이전에 주문을 생성하면 실패한다. // 1 영업 시작 시간 이전에 주문을 생성하면 생성할 수 없다. // 21, 2 중 당연히 2가 더 추상화된 내용을 전달해준다. 우리가 도메인 지식을 이해하는데 더욱 도움을 준다.또한 ‘실패한다’와 ‘생성할 수 없다’를 보자. 실패한다는 것은 도메인에 대한 정보가 아니다. 단순히 테스트의 성공, 실패라는 결과에 의존한 것이다. 우리는 도메인의 정보를 전달할 수 있게 주의해야 한다.  BDD 스타일로 작성하기given - when - then → ‘테스트의 준비 - 행위 - 결과’ 를 의미한다.명확하게 표시해 줌으로써 테스트 코드를 좀 더 이해하기 쉽다.  Test의 양면성과 바라봐야 할 시각(개인 정리)이처럼 테스트에 대한 이점과 작성법이 있다. 하지만 테스트 또한 비용이다. 테스트가 오히려 기능 구현보다 비용이 비쌀 수도 있고 그렇기에 이를 단순 테스트의 용도로 바라보거나 기능 구현에 편향된 모습을 보이며 테스트 작성이 오히려 불필요하다는 반론도 많다. 하지만 우리는 지금 당장이 중요한 것이 아니다. 서비스가 운영된다면 종료되기 전까지 성장할 것이다. 또한 사용자가 많아지고 서비스의 규모가 커질수록 우리 코드는 더 많은 상호 협력을 요구하기에 결합도가 커지기 마련이다.이에 따라 장애가 발생할 확률도 높다. 테스트를 작성할 때, 항상 고민하는 습관이 있어야 장애의 발생을 예방할 수 있다. 테스트를 단순 검증의 역할로만 바라보지 말고 문서의 역할까지 크게 바라보자. 그럼에도 비용은 무시할 수 없다. 비용과 비용에서 오는 이점을 고려하여 우리는 테스트를 다루는 것도 필요한 요소라고 생각한다. 

백엔드테스트테스트필요성테스트작성법

whffkaos007

워밍업 클럽 2기 BE 클린코드&테스트 - 회고 2회

 해당 회고는 박우빈님의 'Readable Code : 읽기 좋은 코드를 작성하는 사고법' 강의를 참조하여 작성했습니다. 2주차 회고인데 까먹고 이제야 씁니다 . . . 남은 기간에는 좀 더 열심히 참여해서 많이 얻어 가겠습니다!   기억하면 좋은 조언들능동적 읽기학습 내용을 빠르게 체득할 수 있는 방법은 직접 적용해 보는 것이다. 실습을 통해 이론으로 얻은 지식만의 부족함을 채울 수 있으며 결과를 직접 확인 가능하여 크게 와닿는다. 이처럼 클린 코드에 대한 견문과 견해도 직접 적용해 봐야 시야를 기를 수 있다.모든 것을 한 번에 보기는 어려우니 직접 하나하나 리팩토링 하면서 이해하기리팩토링을 통해 도메인 지식을 늘리고 작성자의 의도를 파악하도록 노력하기리팩토링을 무서워할 필요가 없다. git reset을 통해 언제든지 복구 가능하니 잘못된 코드를 작성하더라도 괜찮다. 결국 직접 시도해야지만 성장할 수 있다. 오버 엔지니어링모든 것에는 오버 엔지니어링이 생길 수 있다. 보여준 예시처럼 체스 게임을 구현했을 때, 너무 매달리지 않아도 된다. 체스란 게임은 몇 백년 간 변하지 않았다. 체스란 게임만 봤을 때, 끝없는 리팩토링과 효율성을 고려하는 것이 옳을까?보통 서비스는 발전하기에 우리는 추후 수월한 유지보수를 하기 위해 클린 코드를 고려해야 한다. 만약 단발성이나 지속 가능성이 없다면 적절한 타협점을 찾으면 된다.구현체가 하나인 인터페이스인터페이스 형태가 아키텍처 이해에 도움을 주거나, 근시일 내에 구현체가 추가될 가능성이 높다면 인터페이스를 적용할 의미가 있다.하지만 구현체를 수정할 때마다 인터페이스도 수정해야 한다.인터페이스이므로 코드 탐색에 영향을 주고 필요 이상으로 애플리케이션이 비대해질 수 있다.너무 이른 추상화정보가 숨겨지기 때문에 복잡도가 높아진다.후대 개발자들이 선대의 의도를 파악하기 어렵다.이처럼 클린 코드는 절대적인 법칙이 아니다. 우리는 필요에 의해 적용해야 한다. 이러한 견문은 경험에 따라 달라지니 부족하다면 열심히 적용해보자. 은탄환은 없다 클린 코드는 은탄환이 아니다. 실무 상황에서는 금전적 이익이 필수적이다. 그렇기에 고민에 빠진다.지속 가능한 소프트웨어 품질 VS 기술 부채를 안고 가는 빠른 결과물대부분의 회사는 돈을 벌고 성장해야 하고, 시장에서 빠르게 살아남는 것이 목표이다.이런 경우에도, 클린 코드를 추구하지 말라는 것이 아니라, 미래 시점에 잘 고치도록 할 수 있는 코드 센스가 필요하다. 결국은 클린 코드의 사고법을 기반으로 결정된다.이처럼 우리는 적정선을 찾을 수 있는 능력이 필요하다. 급하게 만들어 품질이 낮은 결과물에 대해서는 주석을 통해 추후 개선사항을 남기듯 상황에 맞는 합의점을 찾아야 한다.하지만 이는 클린 코드에 대한 이해와 경험이 충분해야 찾기 쉽다. 적정 수준을 알기 위해 극단적으로 사용해보는 것이 도움이 될 것이다. 예시로 망치만 쓰는 초보 목수는 모든 작업에 망치만 사용할 것이다. 망치밖에 쓸 줄 모르기 때문이다.망치와 톱을 다룰 줄 아는 숙력자 목수는 상황에 적절한 도구를 사용할 것이다. 나무를 자르는데 당연히 톱을 사용한다. 클린 코드도 마찬가지이다. 상황에 대한 판단이 가능한 숙력자가 되기 위해 극단적으로 숙력될 때까지 사용하자.   개선할 점실제로 리팩토링한 것과 강사님이 리팩토링한 부분과 차이를 보면서 보는 관점이 다르다는 것을 체감할 수 있었습니다. 제가 리팩토링하면서 익숙치 않아 옳은 리팩토링인가에 대한 의문은 있었습니다. 그래도 리팩토링에 대한 이유를 계속 생각하면서 하니 비교했을 때, 다시 개선해야 할 부분에 대해 인지할 수 있어 좋았습니다. 다른 말로는 오늘 리팩토링한 것을 내일 보라는 얘기를 해주셨는데 확실히 다음날 보니 생각치 못했던 부분에 대한 새로운 시야가 보여 마음에 와닿았습니다.많이 부족하지만 계속 연습해서 저만의 견해가 담긴 클린 코드를 작성할 수 있도록 노력하겠습니다. 

백엔드클린코드읽기좋은코드

채널톡 아이콘