블로그

인프런 워밍업 클럽 2기 백엔드 클린 코드와 테스트 코드 3주 차 발자국

이번주 회고세 번째 주 인프런 워밍업 클럽2기 클린코드와 테스트를 진행하였습니다.강의에서 들은 내용을 실무의 테스트 코드에 적용하고 있습니다. 확실히 예전에는 함수명을 지을 때도 고민을 많이 했는데, 이제는 확실히 어떤 목적으로 함수명을 지으면 되는지 알고 있으니 작업이 수월해졌습니다.한 번만 듣고 끝낼 것이 아니라 여러 번 복습하면 더 도움이 될 것 같습니다.강의를 수강하면서 꼭 기록하고 싶은 내용Layered ArchitecturePresentation Layer, Business Layer, Persistence Layer 로 관심사의 분리를 기준으로 나눈 구조이다.유지보수가 용이해보인다. 통합 테스트여러 모듈이 협력하는 기능을 통합적으로 검증, 기능 전체의 신뢰성을 보장하기 위해 진행 라이브러리와 프레임워크의 차이리액트와 뷰의 차이와도 같다. Persistence Layer외부 세계의 요청을 가장 먼저 받는 계층, 파라미터에 대한 최소한의 검증을 수행- Data Access의 역할- 비즈니스 가공 로직이 포함되어서는 안 된다. Data에 대한 CURD만 집중할 것 CQRS Command / Read 를 의도적으로 책임 분리를 하여 서로 연관이 없게끔 한다.트랜잭션의 ReadOnly = true를 통해 Command와 Read를 분리할 수 있다.

이호준

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

강의 수강3주차에는 섹션 4. Drag and Drop 부터 섹션 6. 검색 페이지 구현까지 수강 했습니다.To-do 앱to-do 앱을 따라 구현해 보았습니다.js로 구현할 때랑 기능은 비슷했지만 상태 관리라든지 JSX와 같은 리액트만의 방법으로 어떻게 구현해야하는지 공부할 수 있었습니다.클래스로 구현하는 방법과 react hooks를 이용한 함수형으로 구현하는 방법에 대해서 배웠습니다.컴포넌트 간에 props를 이용해 데이터를 전달해주는 방법에 대해서 배웠습니다. Netflix 앱메인 페이지와 무비 모달 창까지 따라서 구현해 보았습니다.tmdb에서 제공하는 api를 어떻게 가공해야할지에 대해서 배울 수 있었습니다.video가 없을 경우 play 버튼을 누를 시 에러가 발생해서 커뮤니티에 있던 질문들을 참고해서 없을 경우 play 버튼이 생성 되지 않게 삼항 연산자를 이용하여 수정 해보았습니다.styled component를 이용해 css 스타일이 적용된 태그를 만들 수 있는게 앞서 배운 tailwind css 보단 개인적인 입장에서 훨씬 유용해 보여서 개발 할때 자주 이용할 것 같습니다.3주차 회고3주차는 정보처리기사 시험 준비로 인해서 학습에 많은 시간을 할당히 못해 많이 진행하지 못했습니다.워밍업 클럽의 스케쥴은 끝났지만 남은 학습과 프로젝트는 개인적으로 계속 진행할 생각 입니다

프론트엔드

[인프런 워밍업 스터디 클럽 2기 백엔드] 3주차

해당 글은 인프런 박우빈 강사님의 「Practical Testing: 실용적인 테스트 가이드」을 바탕으로 작성하였습니다.  3주차 요약 테스트의 필요성테스트란 본래 귀찮은 존재이지만, 꼭 거쳐야만 한다...!테스트 코드가 없으면 변화의 순간마다 모든 케이스를 고려해야만 한다.그 변화들에 대한 내용을 모든 팀원이 알고 인지하고 고민해야 한다.안정성 보장이 불가능해진다. 수동 테스트의 문제커버 불가능한 영역이 발생한다.경험과 감에만 의존한 코드가 되어버린다.피드백이 늦어진다.유지 보수가 어려워진다.⇒소프트웨어에 대한 전체적 신뢰도가 낮아진다. 엉망인 테스트 코드의 문제안정성 제공이 어려워진다. 테스트 코드 자체의 유지 보수가 어려워진다.잘못된 검증이 일어날 수 있다. 올바른 테스트 코드?자동화 테스트를 통한 빠른 버그가 발견 가능하다.수동 테스트에 드는 비용이 절약된다.소프트웨어의 빠른 변화를 지원한다.테스트 코드 작성할 때는 정말 오래 걸리고 번거로운 작업이지만, 멀리 보면 결과적으로 가장 빠른 길이 된다. 아무리 귀찮고 간단한 로직이라도 항상 무조건 테스트해야 한다. 단위 테스트작은 코드 단위(클래스/메서드)를 독립적으로 검증하는 테스트검증 속도가 빠르고 안정적이다. JUnit5단위 테스트를 위한 자바 진영의 테스트 프레임워크 AssertJ테스트 코드 작성을 원활하게 돕는 테스트 라이브러리풍부한 API, 메서드 체이닝을 제공한다. 테스트 케이스의 세분화암묵적이거나 아직 드러나지 않은 요구사항이 있는지 언제나 질문하는 것이 중요하다.해피 케이스와 예외 케이스의 경계 값으로 테스트를 한다. 테스트하기 어려운 파트를 구분하기현재 시간, 사용자의 입력 값 등 언제나 달라질 수 있는 값이나 외부 세계에 영향을 주는 코드는 외부로 분리한다.테스트 하고자 하는 영역을 잊지 않고 집중해야 한다.테스트 하기 좋은 함수는 순수함수다.같은 입력 값에는 항상 동일한 결과를 도출한다.외부 세계와 단절되어 있다.lombok@Data, @Setter, @AllArgsConstructor은 지양한다.@ToString은 JPA 양방향 관계 설정 시 순환 참조의 문제가 발생할 수 있어 DTO 외에서는 지양한다. TDD ★프로덕션 코드보다 테스트 코드를 우선적으로 작성해 테스트가 구현을 주도하도록 하는 방법론이다.레드 그린 리팩토링을 사용한다.레드: 구현부가 없어 실패하는 테스트 작성그린: 빠른 시간 내에 테스트를 통과하도록 최소한의 코딩리팩토링: 구현 코드를 개선하며 테스트의 통과를 유지피드백 (TDD 핵심 가치)복잡도가 낮은 테스트 가능한 코드를 구현 가능케 한다.테스트 자체의 누락 가능성이 낮아진다.잘못된 구현을 빠르게 발견할 수 있다.발견하기 어려운 엣지 케이스를 놓치지 않게 해준다.과감한 리팩토링이 가능해진다. 테스트는 또 하나의 문서기능을 설명하는 테스트 코드 문서이기 때문에 프로덕션 코드를 이해하는 시각과 관점을 보완해준다. displayName의 작성법'~~ 테스트' 같은 문장을 압축한 형식의 작명은 지양한다.최대한 도메인 용어와 결과까지 한 문장으로 작성해, 어느 누가 봐도 이해 가능하도록 작성한다.테스트는 메서드 관점이 아닌 도메인 정책의 관점으로 바라본다. BDD ★given / when / then 형식의 시나리오에 기반한 테스트 케이스 자체에 집중한다.개발자가 아닌 사람이 봐도 이해 가능할 정도의 추상화 레벨을 권장한다. Given: 시나리오 진행에 필요한 모든 준비 과정 (객체, 값, 상태 등) When: 시나리오 행동 진행 Then: 시나리오에 대한 결과 명시 / 검증  레이어드 아키텍쳐관심사의 분리로 별도 단위 테스트를 가능하게 한다.프레젠테이션 레이어 / 비즈니스 레이어 / 퍼시스턴트 레이어 로 구분된다. 통합 테스트A 모듈과 B 모듈을 융합한 결과가 AB일지 C일지 알 수가 없기 때문에 단위 테스트로는 부족하다.⇒ 통합 테스트의 필요여러 모듈이 협력하는 기능을 통합적으로 검증한다.기능 전체의 신뢰성을 보장한다.테스트는 풍부한 단위 테스트와 큰 기능 단위를 검증하는 통합 테스트의 모음이다. 스프링은 라이브러리 ? 프레임워크 ? 라이브러리는 내 코드가 주체, 프레임워크는 프레임워크가 주체가 된다. 이미 존재하는 프레임 안에 형식에 맞게 내 코드를 끼워넣는 것 이다.스프링의 3대 개념  제어의 역전(IoC)  의존성 주입(DI) AOP - 비즈니스 흐름과 관계없는 부분을 하나로 모아 다른 모듈로 분할  JPA(자바 퍼시스턴트 API) 자바 진영의 ORM이자 인터페이스이다.여러 구현체 중 하이버네이트를 주로 사용한다.편리하지만 쿼리를 직접 작성하지 않기 때문에 어떤 식으로 쿼리가 생성 후 실행되는지 명확한 이해가 필요하다.JPA를 한번 더 추상화한 스프링 데이터 JPA 제공한다.쿼리 DSL과 조합해 많이 사용한다. (타입 체크, 동적 쿼리) ORM(오브젝트 릴레이셔널 매핑)객체 지향 패러다임과 관계형 DB 패러다임과의 불일치하기 때문에 탄생한 매핑 개념이다.이전 개발자가 객체의 데이터를 하나하나 매핑하여 저장 및 조회를 실행해야 했다면, 현재는 ORM을 통해 개발자는 단순 작업을 줄이고 비즈니스 로직에 집중할 수 있다. Persistence Layer데이터와 직접 접근하는 레이어이다.비즈니스 가공 로직이 포함되면 안 된다.데이터의 단순 CRUD에 집중한다. Business Layer비즈니스 로직을 구현하는 레이어이다.Persistence Layer와 상호작용해 로직을 전개한다.트랜잭션의 보장이 필요하다. +α재고 감소나 데이터 추가 같은 부분은 동시성 이슈가 발생 가능성이 높기에, optimistic lock 이나 pessimistic lock 등의 방법을 통해 해결한다. ← 추가 학습 필요데이터 추가 같은 부분의 동시성 이슈가 발생했을 때, 사용자의 요청을 아예 무시할 수는 없다. 데이터 엔티티의 인덱스에 유니크 인덱스 설정을 하고 시스템 내에서 자동적으로 재시도를 n회 하는 등의 방식으로 해결 가능하다.  미션미션 4의 git repository미션 4는 Readable code 강의의 예제를 바탕으로 단위 테스트를 작성하는 과제였다. Practical testing 강의 내의 예제는 꽤나 간단했기에, 이번 과제는 단순한 과제라고 생각하고 가벼운 마음으로 접근했지만 역시나 만만치 않았다. 특히나 지뢰찾기 게임 프로젝트도 스터디 카페 프로젝트도 사용자의 입력에 관여하는 로직이 많아 mock 객체를 사용하지 않고 테스트하는 방법이 도무지 떠오르지 않아, 결과적으로는 내가 직접 접근이 가능한 부분에 대해서만 짧게 테스트 코드를 작성하는 것으로 마무리했다. 어떤 클래스에서도 모든 케이스에 대한 테스트를 진행하지 못한 것이 너무나도 아쉬웠다.😂

백엔드워밍업클럽백엔드

dd

발자국 3주 차

본 내용은 인프런 워밍업 클럽 스터디를 진행하면서 작성한 회고 글 입니다.강의: Practical Testing: 실용적인 테스트 가이드학습 정리테스트를 작성해야 하는 이유사람이 매번 테스트를 하는 게 비효율적이고, 실수도 발생할 수 있음.자동화된 테스트로 빠르게 변화하는 소프트웨어의 안정성을 보장할 수 있음.올바른 테스트 코드를 작성하며 개발하는 것이 장기적인 관점에서 가장 빠른 방법임.테스트는 귀찮지만 꼭 해야 한다.  단위 테스트클래스나 메서드 처럼 작은 코드 단위를 독립적으로 검증하는 테스트검증 속도가 빠르고 안정적임  TDD프로덕션 코드보다 테스트 코드를 먼저 작성하는 개발 방법론빠른 피드백을 얻을 수 있고, 과감한 리팩토링이 가능해짐개발하려는 내용의 케이스가 복잡해서 단순하게 접근하기 어려운 경우 활용하면 좋다. 학습 회고테스트를 왜 작성하는지 이유를 명확하게 알게 되었고, TDD라는 방법론을 실제 어떻게 적용을 하는지도 알게 되었다. 단위 테스트와 Persistance, Business Layer를 테스트 하는 것도 상세하게 나와있어서 나중에 실제 프로젝트에 적용하는 데 큰 어려움이 없을 것 같다.미션Day12 미션은 Readable Code강의에서 만든 두 개의 프로젝트 중 하나를 골라서 단위 테스트를 작성하는 것이었다. 나는 지뢰찾기 프로젝트를 선택했고, 이번 주에 배운 내용을 활용하여 @DisplayName과 BDD스타일을 적용하여 단위 테스트를 작성하였다. 미션 회고강의를 듣고 비슷하게 테스트를 작성해보니까 생각보다 어렵지 않았고, 테스트를 통해 정상 동작되는 걸 빠르게 확인할 수 있기 때문에, 이로 인한 이점이 정말 크다고 생각되었다.

dd 1개월 전

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

이전내용 : 클린코드[인프런 워밍업 클럽 백엔드 스터디 2기] 1주차 발자국[인프런 워밍업 클럽 백엔드 스터디 2기] 2주차 발자국오늘은 3주차 Practical Testing: 실용적인 테스트 가이드를 시작하는 한주로 강의에 대해정리하도록 하겠습니다.개인적으로 세션2 테스트는 왜필요한가? 라는 강좌가 제일 중요하다고 생각하였습니다. 테스트를 왜 해야 되는지?테스트 코드는 귀찮지만, 테스트 코드를 구현하지 않는 코드는경험과 감에 의존한다피드백이 늦다.유지보수가 어렵다.소프트웨어이 신뢰성이 떨어진다 라고 전달하였습니다.변화가 생기는 매순간마다 발생할 수 있는 모든 Case를 고려해야 한다.변화가 생기는 매순간마다 모든 팀원이 동일한 고민을 해야된다.빠르게 변화하는 소프트웨어의 안정성을 보장할 수 없다. 그렇다면 테스트 코드를 구현한 코드의 장점은빠른 피드백자동화안정감자동화 테스트를통해 비교적 빠른 시간 안에 버그를 발견하고, 수동 테스트에 드는 비용을 크게 절약할 수 있다.소프트웨어의 빠른 변화를 지원한다.팀원들의 집단 지성을 팀 차원의 이익으로 승격시킨다.가까이 보면 느리지만, 멀리 보면 가장 빠르다.이라고 전달하였습니다.저는 과거부터 현재까지 이어져 온 코드를 유지보수하고, 동시에 신규 개발도 진행하고 있습니다. 과거에 작성된 소스코드는 각 구성원들이 큰 책임을 가지고 유지하고 있어, 문제가 발생했을 때 사이드 이펙트나 우회하는 코드 등의 여러 요소를 신경 써야 하는 상황이 많습니다. 이로 인해 신규 입사자(신입, 경력자 모두)들이 코드를 수정하기가 매우 까다로워졌습니다. 그 결과, 작은 기능 하나를 추가할 때도 많은 비용이 소모되고, 신규 개발에 집중할 여유조차 없게 된 것입니다.이 문제를 해결하기 위해 저는 테스트 코드를 도입하자는 의견을 제시했습니다. "우리 소스는 현재 신규 입사자들이 접근하기에 허들이 너무 높기 때문에, 문서화와 프로젝트 히스토리를 테스트 코드로 대체하자"는 것이 제 의견이었습니다. 처음에는 팀원들이 함께 구현에 동참했지만, 곧 저 혼자 테스트 코드를 작성하게 되었습니다. 워낙 업무 속도가 빠르게 진행되다 보니, 테스트 코드 도입을 강요할 수는 없었습니다.그럼에도 제가 생각하는 테스트 코드는 코딩을 더 재미있고 확신 있게 할 수 있는 도구라는 것입니다. 신입 시절, 배포 전 문제가 생길까 긴장했던 경험이 많았고, 코드가 제대로 작동할지 확신이 들지 않았습니다. 그러나 테스트 코드를 도입한 이후에는 빠르게 피드백을 받을 수 있었고, 그로 인해 구현 과정이 훨씬 더 재미있어졌으며, 코딩에 대한 확신도 커졌습니다. 따라서 귀찮더라도 테스트 코드를 한번 작성해보고 재미를 느끼는 것도 좋다고 생각됩니다.@Display Named을 섬세하게테스코드를 구현하면서 제일 어려운 부분이 Display Name이라고 생각합니다. DisplayName을 상세하게 작성하지 않으면 미래에 내가 다시봐도 어떤것을 테스트하려고 하였는가 헷갈리고, 또한 문서 대신에 작성하는 테스트코드가 더 어렵게 느껴질 수 있습니다. 때문에 강의에서는 아래와 같이 예시를 들면서 전달하였습니다.음료 1개 추가 테스트 -> 음료를 1개 추가할 수 있다.[명사의 나열보다 문장 형태로 작성하려고 노력해야된다.]~ 테스트는 지양해야된다.음료를 1개 추가할 수 있다. -> 음료를 1개 추가하면 주문 목록에 담긴다.[테스트 행위에 대한 결과까지 기술하는게 좋다]특정 시간 이전에 주문을 생성하면 실패한다. -> 영업 시작 시간 이전에는 주문을 생성할 수 없다.[도메인 용어를 사용하여 한층 추상화된 내용을 담기]메서드 자체의 관점보다 도메인 정책 관점[테스트의 현상을 중점으로 기술하지 말 것 (~ 실패, 성공 등)] 지속하고 싶은 부분제가 생각했던 부분보다 좀 더 상세하게 디스플레이 네임을 녹일 수 있게 해봐야겠다.라고 생각하였고, 디스플레이 네임이 생각나지 않는다면 지금 작성하는 글을 되돌아봐야겠다고 생각하였습니다. 아쉬웠던 점현업이 오픈 시점이 점점 다가와서 직접 구현을 하면서 강의를 듣지 못하였지만, 그래도 강의를 보면서 어떻게 적용하면 좋을지 인사이트를 얻을 수 있어서 좋았습니다.시도해볼 점직접 구현해 보면서, 장점을 공유할 수 있게 습득하겠습니다.3주차 Practical Testing: 실용적인 테스트 가이드주요 학습 내용:테스트의 필요성테스트 코드 미구현 시 문제점테스트 코드 구현의 장점@DisplayName 작성법명사 나열 대신 문장 형태로 작성테스트 행위와 결과 모두 기술도메인 용어 사용 및 추상화테스트 현상보다 도메인 정책 중심으로 기술가장 인상 깊었던 두 가지 개념:테스트 코드의 실질적 가치문서화와 프로젝트 히스토리 대체 가능코딩을 더 재미있고 확신 있게 만드는 도구@DisplayName의 중요성미래의 자신과 동료를 위한 명확한 설명테스트 의도와 결과를 명확히 전달개선 및 실천 계획:지속할 점더 상세하고 명확한 DisplayName 작성테스트 코드 작성 시 현재 작성 중인 코드 되돌아보기아쉬웠던 점현업 일정으로 인한 실습 부족시도해볼 점직접 구현을 통한 테스트 코드의 장점 습득팀 내 테스트 코드 장점 공유

워밍업클럽스터디

spacebar

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

3주차 학습내용Practical Testing : 실용적인 테스트 가이드 강의를 학습하며 작성한 내용입니다. 단위 테스트테스트케이스 나누기 해피 케이스 (모든 게 올바르게 동작) 예외 케이스 테스트 하기 어려운 영역 구분하고 분리하기 (외부로 분리할수록 테스트 가능한 코드가 많아짐)외부에서 들어오는 값에 의존하는 코드 (현재 날짜/시간, 랜덤 값) 외부에 영향을 주는 코드 (표준 출력, 메시지 발송)  TDD: Test Driven Development: 프로덕션 코드보다 테스트 코드를 먼저 작성해서 테스트가 구현 과정을 주도하도록 하는 개발 방법- 복잡도가 낮은(유지보수가 쉬운), 테스트 가능한 코드로 구현할 수 있다.- 쉽게 발견하기 어려운 예외상황을 놓치지 않게 해준다.- 과감한 리팩토링이 가능하다. 테스트는 [ ]다DisplayName을 섬세하게@DisplayName("음료 1개를 추가") 보다는 @Display("음료를 1개 추가하면 주문 목록에 담긴다.") 처럼 테스트의 행위에 대한 결과까지 기술하기"~테스트"라는 표현 지양하기, 문장으로 작성 도메인 용어를 사용해서 좀 더 추상화된 내용 담기테스트의 현상 중점으로 기술하지 말 것주문을 생성하면 실패한다(x)주문을 생성할 수 없다. BDD (Behavior Dirven Development) 스타일로 작성하기 : TDD에서 파생된 개발 방법 필수 단위 테스트에 집중하기 보다 시나리오에 기반한 "테스트 케이스" 자체에 집중한다. given / when / then  💻미션 - 테스트코드 작성 minsweeper에 대한 테스트 코드를 작성했봤는데 사실 어떤 부분을 어떻게 테스트해야할지 감이 오지 않았다. 간단한 게임이라도 내부 동작에 대해 작성할 테스트 코드가 많다는 건 알겠는데 @DisplayName과 bdd스타일 따르는 것만 신경 쓰고 정작 단위 테스트의 본질적인 목적을 잊고 작성한 것 같아서 아쉽다. 강의를 다 들은 후 다시 강의 내용을 가이드삼아 찬찬희 케이스를 나눠 작성해보고 싶다. 그리고 studycafe에 대해서도 단위 테스트 작성을 연습해봐야겠다. Spring&JPA 기반 테스트 Persistence Layer repository layer에 대한 테스트 @DataJpaTest 사용 가능 -> rollback 관련 작업 설정 필요 없음 Business Layer 재고라는 개념 도입 재고 차감 예외 테스트 assertThatThrownBy(() -> stock.deductQuantity(quantity)) .isInstanceOf(IllegalArgumentException.class) .hasMessage("차감할 재고 수량이 없습니다.");Stock에서 체크 후 예외를 던지는 것과 OrderService에서 체크 후 예외를 던지는 것은 다르다. (같은 상황이지만 발생할 수 있는 상황이 다르기 때문에 메시지도 다르다.) Service에서는 메시지가 사용자단까지 갈 수 있기 때문에 사용자 친화적인 메시지로 작성한다.Presentation Layer 외부 세계의 요청을 가장 먼저 받는 계층 파라미터에 대한 최소한의 검증을 수행한다.MockMvc테스트 -> @WebMvcTest 사용  전체 빈 컨텍스를 다 띄우는 게 아니라 컨트롤러 레이어만 떼서 사용직렬화하기 위해 ObjectMapper 주입    💬3주차 회고 테스트 코드의 중요성은 알지만 제대로 작성해 본 적은 없어서 하나씩 따라하면서 적용시켜봐야 겠다는 생각으로 강의를 들었다. 듣다보니 테스트 코드 작성에 대한 내용 말고도 아직 스프링과 자바에서도 익숙하지 않은 개념, 헷갈리는 내용들이 많다는 걸 깨달았다. 특히 Layer별 테스트 부분은 강의가 길고 내용이 많아 힘들었지만, 테스트 작성에 대한 부분 말고도 스프링에서의 Validation 적용에 대해 다시 한 번 공부할 수 있어서 좋았다. 리팩토링 강의에서 계속 들었던 책임 분리가 테스트 코드 작성에서도 중요하다는 걸 느꼈다.그리고 앞으로 작은 프로젝트를 하더라도 기능과 서비스의 확장을 염두한 개발을 해야겠다고 생각했다.    

백엔드

Jiyeon Hwang

[인프런 위밍업 클럽 2기 디자인] 3주차 발자국 및 회고

일주일간의 학습에 대한 회고 2주차의 연장선으로 네비게이션 컴포넌트와 베리어블 다크모드 개념에 대해 익힐 수 있었습니다. 로컬 베리어블에 값을 입력하면 상황에 따라 변경이 되는 점이 정말 흥미로웠고, 이에 따라 피그마 베리어블의 작업 효율성을 칭찬하는 이유를 이해할 수 있게 되었습니다. 이후 반응형, B2B 이커머스 어드민 페이지를 만드는 과정에서 컴포넌트를 조합하는 시간에, 기존에 만들었던 컴포넌트의 문제점을 발견하게 되었고, 당황스럽고 수정은 어떻게 하는지 혼란스러운 시간을 경험했습니다.ㅠㅠ 생각보다 컴포넌트를 만들 때 정교한 기획이 필요하다는 점과 문서화 정리가 얼마나 중요한지 배웠습니다. Assets에서 컴포넌트를 검색할 때, 같은 항목이 왜케 많이 나오는 이유도 저의 실수에서 비롯된 것임을 깨달았습니다. 일주일 동안 잘한 점 시간이 늦어도 매일 강의를 수강한 점 아쉬웠던 점 본업으로 인해 미션을 제출 날짜를 맞추지 못한 점 컴포넌트 문서화를 더 잘하고 싶습니다. 보완하고 싶은 점 강의 중 그룹화하고 오토 레이아웃을 반복적으로 다루는데, 아직 개념으로 잘 이해하지 못하고 있습니다. 이해하지 못한 부분을 복습으로 채워나가고 싶습니다. 컴포넌트 문서화와 함께 variant property 보기 쉽게 순서를 정리 할 것입니다. 다음 주에는 마지막 주에는 그동안 해왔던 것보다 더 열정적으로 작업해 보겠습니다. 아직 제출하지 못한 미션뿐만 아니라 앞으로 있을 미션까지 최선을 다할 것입니다.

UX/UI디자인시스템피그마베리어블

ykm8864

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

워밍업 클럽 백엔드 스터디 2기 3주차 발자국 입니다.본격적인 TDD 가이드에 대하여 배우기 시작했습니다.테스트는 왜 필요할까?테스트 = 귀찮다?프로그램이 커지면 수동테스트의 정확도가 어떨까?사람이 할거야?변화가 생기는 매순간마다 모든 팀원이 동일한 고민을 해야한다면 소프트웨어의 신뢰도가 낮아질 가능성이 높다. 올바른 테스트 코드자동화 테스트로 비교적 빠른 시간 안에 버그를 발견할 수 있고, 수동 테스트에 드는 비용을 크게 절약할 수 있다.소프트웨어의 빠른 변화를 지원한다.팀원들의 집단 지성을 팀 차원의 이익으로 승격시킨다.가까이 보면 느리지만, 멀리 보면 가장 빠르다.단위테스트란작은 코드(클래그 or 메서드) 단위를 독립적으로 검증하는 테스트단위테스트는 검증속도가 빠르고 안정적이다.우리는 JUnit5 와 AssertJ 를 사용하여 테스트 코드를 작성해보았다. 테스트 케이스 세분화하기질문하기 : 암묵적이거나 아지 드러나지 않은 요구사항이 있는가? 해피케이스와 예외케이스에 대하여 테스트 케이스를 세분화 해야한다.-> 경계값 테스트라는 개념을 배웠다.어떠한 정수가 있는데 정수가 3이상일 때, A라는 조건이 성립한다면?⇒ 테스트를 4나 5로 테스트 하는게 야니고 3에 대하여 테스트를 작성하는게 맞다.⇒ 예외 케이스는 2나 1이나 -1과 같은 경계값보다 아래의 경우의 수로 예외케이스를 짜는게 맞다. 테스트하기 어려운 영역 분리하기외부세계에 관련된 도메인은 테스트하기 어려우니 분리하여 가능한 것에 집중한다.input 과 output이 외부세계에 영향을 주거나, 외부세계에 영향을 받는 경우에는 테스트하기 어렵다.ex) 표준출력, 메시지발송, 데이터베이스에 기록하기 등.. 강의에서는 "현재시간" 은 테스트를 돌리는 시간이 바뀜에 따라 매번 결과값이 달라질 수 있으므로 정확한 테스트가 어려워 프로덕트 코드에는 현재시간을 매개변수로 넣고, 테스트할 때는 테스트 하고자 하는 시간을 매개변수로 세팅하여 분리한다. 즉, 테스트 어려운 조건이 생기면 테스트 어려운 영역을 외부로 분리하여 조치한다.TDD프로덕션 코드보다 테스트 코드를 먼저 작성하여 테스트가 구현 과정을 주도하도록 하는 방법론RED - GREEN - REFACTOR위 과정으로 TDD가 이루어진다. 실패케이스를 먼저 짜고, 통과를 위한 통과 케이스를 짜고, 리팩토링하고 이를 반복한다.선기능 구현, 후 테스트의 문제점테스트 자체의 누락 가능성(아 테스트 짤 시가니 없네)특정 테스트 케이스만 검증할 가능성(해피케이스만 생각)잘못된 구현을 다소 늦게 발견할 가능성 테스트는 [문서]다.언어가 사고를 제한한다.프로덕션 기능을 설명하는 테스트 코드 문서다양한 테스트 케이스를 통해 프로덕션 코드를 이해하는 시각과 관점을 보안해피케이스와 예외케이스를 생각하여 더 깊게 이해할 수 있다.어느 한 사람이 과거에 경험했던 고민의 결과물을 팀차원으로 승격시켜서, 모두의 자산으로 공유할 수 있다.테스트케이스를 통해 고민의 결과를 공유하여 소스코드를 관리할 수 있다.  DisplayName을 섬세하게테스트 하고자 하는 내용을 명확하게 기술하자문장형태로 작성하자!테스트 행위에 대한 결과까지 기술한다.도메인 용어를 사용하여 한층 추상화된 내용을 담기테스트의 현상 중점 기술: "특정 시간 이전에 주문을 생성하면 실패한다."여기서는 "실패한다"는 구체적인 현상을 강조한다. 테스트가 어떤 상황에서 실패하는지를 중심으로 표현한 것이다. 하지만 이 표현은 테스트가 도메인의 규칙이나 의도를 명확하게 설명해주지 못할 수 있다. 실제 비즈니스 로직의 핵심 규칙보다는 실패 여부에 집중하게 되는 문제가 있게된다.도메인 관점에서의 기술: "영업 시작 시간 이전에는 주문을 생성할 수 없다."이 표현은 현상보다는 도메인의 규칙을 명확하게 기술. "영업 시작 시간 이전에는 주문을 생성할 수 없다"는 표현은, 해당 비즈니스 로직이 적용되는 이유나 규칙을 이해하는 데 도움이 되며, 비즈니스 도메인에서의 규칙을 중심으로 설명하는 방식이다. 레이어드 아키텍쳐와 테스트Presentation Layer - Business Layer - Persistence Layer관심사의 분리를 위해 레이어를 분리한다.기본적인 JPA 엔티티를 설계하고 테스트하고자하는 레이어를 분리하였다.Persistence Layer 테스트기본적인 CRUD를 구성한 후 데이터베이스와의 연동테스트를 하였다.EnableJpaAuditing을 통하여 테이블의 상태를 트랙킹하고 H2 테이버베이스 콘솔과 비지니스 구현 로직이 정상 작동하는지 확인하였다.Business Layer 테스트비지니스 로직을 구현하는 역할 Persistence Layer와의 상호작용(data를 읽고 쓰는 행위)를 통해 비지니스 로직을 전개시킨다. 트랜잭션을 보장해야한다.도메인 로직에 대한 테스트 코드를 작성하였다. 이때 트랜잭션에 대한 관리가 중요했다.상품을 주문할 때, 제고차감에 대한 로직에서 트랜잭션 관리의 중요성을 느꼈는데 기본적인 테스트코드에서의 @Transactional 개념은 이러하다.트랜잭션 관리: @Transactional을 사용하면, 해당 테스트 메서드가 실행될 때 자동으로 트랜잭션이 시작된다. 그리고 테스트가 완료되면, 해당 트랜잭션은 롤백처리.데이터 정리: 트랜잭션이 롤백되므로, 테스트 중 데이터베이스에 삽입되거나 수정된 데이터는 테스트가 끝나면 모두 사라집니다. 따라서, 별도의 정리 작업이 필요 없게된다.. 테스트 격리성: 트랜잭션 범위 내에서 테스트가 실행되고, 롤백을 통해 테스트 이전 상태로 되돌아가므로, 테스트 간의 데이터 격리성이 자연스럽게 유지된다.이렇게 보면 무조건 트랜잭션 어노테이션을 사용하는 것이, AfterEach를 통한 수동 삭제보다 이점이 크다는 생각이 들지만, 테스트코드에만 트랜잭션이 잡혀있고 실제 프로덕션 코드에는 트랜잭션이 안 잡혀있을 수 있는 위험성이 있으므로 팀원 내부적인 공지나 개발자의 인지가 필요하다.이런 점을 놓치면 심각한 상황이 발생할 수 있다. 테스트코드는 통과했지만 실제 운영에는 버그가 생기는 것이다. 예를 들어, 주문을 생성하고 주문에 포함된 상품이나 재고를 업데이트하는 작업이 순차적으로 실행될 때, 중간에 예외가 발생하면 앞서 실행된 작업은 롤백되지 않아 장애가 있을 것이다. 3주차 회고Keep (만족했고, 앞으로도 지속하고 싶은 부분)테스트 코드의 기본적인 Given When Then 방식이 익숙해짐을 느꼈다. 더불어 JPA와 Spring Data JPA에 대한 개념을 다시 한번 다지는 기회도 갖을 수 있었다. 또한, 단위테스트와 통합테스트에 대한 개념이 실무에서는 어떻게 적용되어야 하는지 인지할 수 있었다..Problem (아쉬웠던 점)기본적으로 JUnit 과 AssertJ의 메서드에 아직 친숙한 느낌은 아닌 거 같다. 그러다보니 강의를 들으며 도메인을 따라가면서 코드까지 신경쓰는 것이 어려운 부분이 있었다. 천천히 다시 한번 강의를 들으며 다시 학습하는 과정이 필요해보인다. Try (다음에 시도해볼 점)세부적으로 여러가지를 알려주셔서 좋았다. 다음에는 개인프로젝트로 동시성문제에 대해서 좀 더 고찰해보는 시간을 가지고 싶다. 지나가면서 말씀해주신 ptimistic lock / pessimistic lock 에 대해서도 공부해보고 싶다.

백엔드워밍업클럽2기몰입하는개발자백엔드테스트코드TDD

정재원

인프런 워밍업 클럽 스터디 2기 BE 클린코드 & 테스트 과정- 3주차 발자국

3주차 발자국 회고테스트는 왜 필요한가? 테스트 코드 작성에 대한 지식이 없었을 적 불편했던 일들이 코치님이 말하시는 테스트를 작성하지 않았을 때 발생하는 상황과 굉장히 유사했기에 크게 공감하며 이해할 수 있었다. 단순히 알고리즘 문제를 풀 때만 해도 특정 케이스에 대해 잘 못 작성된 코드를 수정하게 되면 올바르게 고쳐졌는지 확인하기 위해 해당 케이스 뿐만이 아니라 기존의 모든 테스트 케이스를 반복해서 돌려봐야 하는 경우가 생긴다. 여러 도메인의 연관 관계가 존재하는 프로젝트에서는 어떠한 영향을 끼칠지 빠른 피드백과 안정성이 필수적이라는 점은 인상 깊게 기억에 남았다.테스트하기 어려운 영역 관측할 때 마다 다른 값에 의존하는 코드가 존재하고 그러한 코드를 테스트 하는 것의 어려움을 이해하고 분리해나가는 과정은 단순히 파라미터 하나 혹은 전역 변수 하나라도 그 위치의 중요성을 고민하게 만들었다. 코드를 작성하는데 있어 단순한 전역변수 하나가 테스트 케이스 구성을 어렵게 만들 수 있다는 것은 신중한 코드 작성 그리고 TDD 방식의 필요성을 직관적으로 이해할 수 있게 도와주었다.Spring & JPA 기반 테스트 Business Layer에 대한 테스트 코드를 작성하는 것은 생각보다 어려움이 많았다. 테스트를 구성하고 해당 테스트가 제대로 동작하기 위해 구체적인 코드를 작성하면서 그에 따라 발생하는 Persistence Layer 테스트를 캐치 하고 새로운 테스트를 작성하는 것은 TDD 방식에 익숙하지 않아 유연하게 따라가기 어려웠던 것 같다. 그렇지만 그렇게 발생한 테스트 코드의 중요성은 깨달을 수 있었던 것 같다. 강의 : Practical Testing: 실용적인 테스트 가이드 (박우빈)

백엔드

[BE 클린코드/테스트코드 스터디] 3주차 회고

3주차 동안 무엇을 공부했는가?목차3주차 동안 학습한 목차는 다음과 같다.단위 테스트TDD테스트는 []다.Spring & JPA 기반 테스트 각 목차 별 본인이 생각하는 중점을 요약하자면 다음과 같다.단위 테스트작은 코드 단위를 독립적으로 검증하는 테스트TDD선 테스트 작성 후, 기능 구현테스트는 []다테스트는 단순히 테스트의 용도만 있는 것이 아니다..Spring & JPA 기반 테스트@SpringBootTest 와 @DataJpaTest의 차이테스트에서 @Transaction은 신중히 고려해야할 사항이다. 미션미션 4. 지뢰찾기 게임 테스트코드 작성하기테스트코드를 작성하는데에 본 강의에서 중요하게 다룬 경계 테스트를 집중하였다.다만, 여태까지 중요하다고 생각한 부분에만 테스트코드를 작성해왔던 터라 "테스트를 작성해야하는 부분"을 선정하는게 어렵게 느껴졌다.값의 변경이 생기고 해당 부분이 외부에 노출되는 코드들을 최대한 테스트 코드를 작성하려고 노력하였다. 3주차 이후, 생각..테스트가 익숙하지 않다보니, 생각보다 쉽지 않았던 것 같다.정말 중요하다는 것은 잘 알지만, 구현에 반해 테스트 코드는 노동이라는 생각이 오랜 시간 자리 잡았던 것 같다.다음 강의부터 Mock, Spring dosc와 같은 내용들이 준비 되어있으니, 테스트 코드의 즐거움을 찾기위해 노력해봐야 할 것 같다.

성규

[워밍업 클럽 스터디 2기 :: BE 클린코드 & 테스트] 3주차 발자국

통합 테스트일반적으로 작은 범위의 단위 테스트만으로는 기능 전체의 신뢰성을 보장할 수 없다.풍부한 단위 테스트 & 큰 기능 단위를 검증하는 통합 테스트SpringLibrary내 코드가 주체!!외부에 있는 기능을 끌어 옴Framework이미 동작 할 수 있는 환경내 코드가 수동적SpringIOCDIAOPJPAORM : Object-Relational Mapping객체 지향 패러다임과 관계형 DB 패러다임의 불일치단순 작업을 줄이고 비지니스 로직에 집중 할 수 있다.JPA인터페이스 이고 여러 구현체가 있지만 보통 Hibernate를 많이 사용한다.편리하지만 어떤 식으로 쿼리가 만들어지고 실행되는지 명확하게 이해하고 있어야 한다.Sping Data JPAJPA 를 한번 더 추상화한 Spring Data JPA 제공QueryDSL과 조합하여 많이 사용한다. (타입체크, 동적 쿼리)※ @AllArgsConstructor 를 지양하시는 이유빌더 패턴은 빌더 패턴의 장점이 별도로 있기 때문에 사용하는 것이고, @AllArgsConstructor 를 사용하지 않는 이유는 별개의 이유입니다.@AllArgsConstructor는 편리하게 모든 필드를 가진 생성자를 만들어 주지만, 필드의 순서가 변경되는 경우 치명적일 수 있습니다.예를 들어 어떤 객체가 2개의 String 타입을 필드로 가지고 있고, 이에 대한 생성자를 외부에서 사용하고 있다고 가정해 봅시다.해당 객체의 필드 순서가 실수로 변경되어도 컴파일 에러가 발생하지 않고, 추후 인지하지 못한 치명적인 버그가 발생할 수 있는 여지가 됩니다.그럼 @RequiredArgsConstructor를 사용해도 final 키워드만 붙었지 마찬가지 아닌가, 싶으실텐데요. 맞습니다. AllArgs~와 동일한 문제를 안고 있지만, 저는 그래도 편의성을 위해 @RequiredArgsConstructor정도는 인지하고 사용하자는 편입니다.이유는 다음과 같은데요.사용자가 final 키워드를 붙이면서 필수 파라미터에 대한 인지를 하고 필드를 선언한다는 점스프링에서는 객체의 생성자만 만들어두면 스프링에서 알맞은 타입과 이름의 빈을 찾아서 주입해주기 때문에, 필드 순서가 바뀌거나 해도 타입+이름 기반으로 동작하니 @RequiredArgsConstructor 를 사용해도 큰 무리가 없음다만 스프링의 Bean이 아닌 사용자가 직접 만들고 사용하는 일반 객체라면, 위 문제를 방지하기 위해 @RequiredArgsConstructor 대신 그냥 생성자를 사용해보는 것을 고려해볼 수 있습니다.※ 패키지 구성애그리거트(Aggregate) 기준으로 패키지를 나누고 하위에 domain, sub-domain, service, repository 등을 위치시켜 컨텍스트를 나누는 방식으로도 사용할 수 있습니다. Persistence LayerData Access 의 역할비지니스 가공 로직이 포함되어서는 안된다. Data에 대한 CRUD에만 집중한 레이어데이터를 담당하는 부분으로서 꼼꼼하게 확인을 해둬야하는 부분Business Layer비지니스 로직을 구현하는 역할Persistence Layer와의 상호작용을 통해 비지니스 로직을 전개시킨다트랜잭션을 보장해야 한다.트랜잭션에 대한 이해를 해야 운영에서 문제 없이 돌아 갈 수가 있다.Presetation Layer외부 세계의 요청을 가장 먼저 받는 계층파라미터에 대한 최소한의 검증을 수행한다.

임원기

인프런 워밍업 스터디 클럽 2기 - 백엔드(클린코드, 테스트코드) 3주차 발자국

개요테스트는 소프트웨어의 품질을 보증하는 작업 중 하나이다.테스트 코드를 작성하는 것을 통해 버그를 조기에 발견하고 견고한 소프트웨어를 만들 수 있으며 반대로 테스트 코드를 작성하지 않으면, 변화가 발생할 때마다 모든 케이스를 고려하는 번거로움이 생기며 유지보수가 어려워진다.Practical Testing 강의에서 테스트 코드를 작성하는 방법과 접근법을 알아보는 시간을 가진다.테스트하기 어려운 코드3주차에는 테스트 프레임워크인 JUnit5을 이용해 자동화된 테스트, 테스트 케이스 세분화(해피케이스와 예외 케이스)하는 작업부터 시작한다.우빈님이 강의에서 가장 중요하다고 언급한 '테스트하기 어려운 영역 분리'가 가장 기억에 남는데, 현재 날짜와 시간, 랜덤한 값, 전역변수, 사용자 입력과 같이 관측할 때마다 '다른 값에 의존하는 코드'와 표준출력, DB 기록, 메시지 발송과 같이 '외부에 영향을 주는 코드'와 같이 어려운 영역을 분리하는 것이다.코드에서는 메서드 내에 선언한 LocalDateTime 때문에 특정 시간에만 성공하고 나머지는 실패하게 되는데, LocalDateTime을 파라미터로 받도록 외부로 분리하는 과정을 통해 이를 알아봤다.핵심은 테스트 하고자하는 영역을 확실히 구분하고, 이를 구분하는 시야를 길러야 한다는 것!계층형 아키텍처에서 테스트계층형 아키텍처는 역할과 관심사에 따라 분리한 아키텍처로 각 계층은 애플리케이션에서 화면 표시나 비즈니스 로직, DB 작업 등 관심사에 따라 분리된다.3주차 권장 진도가 Business Layer에서 멈춰 흐름이 끊기는 느낌이어서 Presentation Layer까지 학습했다.흔히 사용되는 아키텍처로 각 계층별 역할과 어떤 테스트를 해야하는지 알아봤는데클라이언트 요청을 받는 순서대로 정리해봤다.'Presentation 계층'은 사용자의 요청을 받아 처리하는 레이어로 주로 HTTP 요청/응답과 관련된 로직을 포함한다. 때문에 클라이언트가 보내는 HTTP 요청을 실제로 테스트하고 엔드포인트가 의도대로 동작하는지 확인'Business 계층'은 도메인 객체를 활용한 다양한 처리 과정을 포함하며 데이터 접근 및 처리 로직을 포함하지 않으며, 트랜잭션을 보장해야 한다. 비즈니스 로직을 독립적으로 테스트하며 데이터 접근 레이어인 Repository나 외부 API는 Mocking하여 순수한 비즈니스 로직이 예상대로 작동하는지 검증'Persistence 계층'은 Database나 외부 API와의 통신 등을 처리한다. 테스트에서는 쿼리 메서드가 올바르게 동작하는지, 데이터 저장 및 조회가 정상적으로 수행되는지 확인미션 Day12미션에서는 Readable code에서 다뤘던 코드 중 하나인 스터디 카페 이용권 시스템으로 테스트 코드를 작성하게 되었다.코드를 작성하는데 큰 어려움은 없어서 미션을 제출하고 다른 지원자들이 작성한 코드를 살펴봤는데 Mock을 사용한 코드도 있었다. 개인적으로 classicist 쪽에 가깝기 때문에 실제 객체 사용이 어렵지 않다면 테스트 더블을 사용하지 않는 쪽인데 다양한 관점을 볼 수 있어 많이 배울 수 있었다.맺음테스트 코드의 중요성은 말해 입아프다. 이제 한 주 남았는데 완주 이상으로 얻을 수 있도록 노력해야겠다.러너들 화이팅~ 

zooxop

인프런 워밍업 스터디 클럽 2기 백엔드(클린코드&테스트코드) 발자국 - 3주차

인프런 워밍업 클럽 2기, 백엔드(클린코드&테스트코드) 과정에 참여하고 있습니다.이번 3주차에는 테스트에 대한 이론적인 내용과 TDD, 실용적인 테스트 방법등을 학습했습니다.강의 링크: Readable Code: 읽기 좋은 코드를 작성하는 사고법 [학습 요약] 테스트의 필요성왜 작성해야 할까?사람이 수동으로 직접 테스트하는 데에는 한계가 있다.테스트 코드 작성을 통해 얻는 이점빠른 피드백자동화안정감테스트 코드를 작성하지 않는다면..변화가 생기는 매순간마다 발생할 수 있는 모든 Case를 고려해야 한다.변화가 생기는 매순간마다 모든 팀원이 동일한 고민을 해야한다.빠르게 변화하는 소프트웨어의 안정성을 보장할 수 없다.테스트 코드가 병목이 된다면..프로덕션 코드의 안정성을 제공하기 힘들어진다.테스트 코드 자체가 유지보수하기 어려운, 새로운 짐이 된다.잘못된 검증이 이루어질 가능성이 생긴다.올바른 테스트 코드는,자동화 테스트로 비교적 빠른 시간 안에 버그를 발견할 수 있고, 수동 테스트에 드는 비용을 크게 절약할 수 있다.소프트웨어의 빠른 변화를 지원한다.팀원들의 집단 지성을 팀 차원의 이익으로 승격시킨다.가까이 보면 느리지만, 멀리 보면 가장 빠르다.테스트는 귀찮다. 귀찮지만, 해야한다! 단위 테스트작은 코드 단위를 독립적으로 검증하는 테스트작은 코드: 클래스 or 메서드검증 속도가 빠르고, 안정적이다.외부에 의존을 하지 않기 때문에JUnit5단위 테스트를 위한 테스트 프레임워크XUnit - Kent BeckSUnit(SmallTalk), JUnit(Java), NUnit(.NET), DUnit(Delphi)AssertJ테스트 코드 작성을 원할하게 돕는 테스트 라이브러리풍부한 API, 메서드 체이닝 지원테스트 케이스 세분화하기항상 질문하기: 암묵적이거나, 아직 드러나지 않은 요구사항이 있는가?해피 케이스와 예외 테스트를 도출해낼 수 있어야 한다.경계값 테스트경계값?: 범위(이상, 이하, 초과, 미만), 구간, 날짜 등테스트하기 어려운 영역을 구분하고 분리하기테스트하기 어려운 영역을 갖고 있는 코드가 추가된다면, <u>전체 테스트가 망가질 가능성</u>이 생긴다.예시)LocalDateTime.now() 를 사용하는 기능을 테스트할 때, 테스트를 실행하는 시간에 따라 성공할수도, 실패할수도 있게 됨.이 때, LocalDateTime.now() 를 사용하는 코드가 곧 테스트하기 어려운 영역이 된다.이 때, 테스트가 어려운 영역을 외부에서 주입받도록 변경하면 테스트 하기 수월해진다.외부로 분리할수록, 테스트 가능한 코드는 많아진다.테스트하기 어려운 영역 코드 예시관측할 때마다 다른 값에 의존하는 코드현재 날짜/시간, 랜덤 값, 전역 변수/함수, 사용자 입력 등외부 세계에 영향을 주는 코드표준 출력, 메시지 발송, 데이터베이스에 기록하기 등테스트하기 쉬운 영역 코드 예시순수 함수같은 입력에는 항상 같은 결과 반환외부 세상과 단절된 형태 (전역 변수를 변경하지 않는) TDD프로덕션 코드보다 테스트 코드를 먼저 작성하여 테스트가 구현 과정을 주도하도록 하는 방법론[Red - Green - Refactor] 3단계 구조로 순환하며 진행Red: 실패하는 테스트 작성의도적으로 실패하게 테스트를 작성하라는게 아니다.도메인적 지식을 기반으로, 테스트가 통과해야만 하는 조건으로 테스트 코드를 작성하라는 의미.ex) 테스트에서는 10 이라는 값이 나올것을 기대하지만, 구현이 미완성이라서 0이 리턴되는 경우에 기대값을 변경하지 않고 그대로 두는 것을 말한다.Green: 테스트 통과, 최소한의 코딩최대한 빠르게 테스트 통과만을 위한 코딩을 수행.TDD 방법론에서는 하드코딩도 허용.Refactor: 구현 코드 개선, 테스트 통과 유지구현부 코드를 변경한 다음에도 테스트가 통과 된다 -> 구현이 올바르게 되었다 라고 판단할 근거가 된다.피드백TDD가 제공하는 핵심 가치테스트 코드를 통해 내가 구현한 프로덕션 코드에 대해서 자주, 빠르게 피드백을 받을 수 있다.기능 구현 후 테스트 작성 vs. 테스트 작성 후 기능 구현선 기능 구현, 후 테스트 작성 케이스테스트 자체의 누락 가능성특정 테스트 케이스(해피 케이스)만을 검증할 가능성잘못된 구현을 다소 늦게 발견할 가능성선 테스트 작성, 후 기능 구현복잡도가 낮은, 테스트 가능한 코드로 구현할 수 있게 한다.복잡도가 낮다?: 유연하고, 유지보수하기 쉽다쉽게 발견하기 어려운 엣지(Edge) 케이스를 놓치지 않게 해준다.구현에 대한 빠른 피드백을 받을 수 있다.과감한 리팩토링이 가능해진다.TDD: 관점의 변화TDD 이전의 관점: 테스트는 구현부 검증을 위한 보조 수단TDD 이후의 관점: 테스트와 상호 작용하며 발전하는 구현부TDD는 클라이언트 관점에서 피드백을 주는 Test Driven 도구이다. 테스트는 "문서"다테스트는 "문서"다. 왜?프로덕션 기능을 설명하는 테스트 코드 문서다양한 테스트 케이스를 통해 프로덕션 코드를 이해하는 시각과 관점을 보완어느 한 사람이 과거에 경험했던 고민의 결과물을 팀 차원으로 승격시켜서, 모두의 자산으로 공유할 수 있다.우리는 항상 팀으로 일한다 DisplayName을 섬세하게명사의 나열보다 문장으로 작성하자테스트 행위에 대한 결과까지 기술하기before: 음료 1개 추가 테스트after: 음료를 1개 추가할 수 있다.도메인 용어를 한층 추상화된 내용을 담기메서드 자체의 관점보다, 도메인 정책관점으로 생각하자.테스트의 현상을 중점으로 기술하지 말 것before: 특정 시간 이전에 주문을 생성하면 실패한다.after: 영업 시작 시간 이전에는 주문을 생성할 수 없다.BDD, Behavior Driven DevelopmentTDD에서 파생된 개발 방법함수 단위의 테스트에 집중하기 보다, 시나리오에 기반한 테스트케이스(TC) 자체에 집중하여 테스트한다.개발자가 아닌 사람이 봐도 이해할 수 있을 정도의 추상화 수준(레벨)을 권장Given / When / ThenGiven: 시나리오 진행에 필요한 모든 준비 과정 (객체, 값, 상태 등)When: 시나리오 행동 진행Then: 시나리오 진행에 대한 결과 명시, 검증 Spring & JPA 기반 테스트 레이어드 아키텍처와 테스트Layered Architecture 는 관심사의 분리를 위해 수행한다!책임을 나누고, 유지보수하기 용이하게 만들자Spring & JPA 기반 애플리케이션에서 일반적으로 사용하는 레이어 구조User <-> [Presentation Layer] <-> [Business Layer] <-> [Persistence Layer] <-> DB통합 테스트여러 모듈이 협력하는 기능을 통합적으로 검증하는 테스트일반적으로 작은 범위의 단위 테스트만으로는 기능 전체의 신뢰성을 보장할 수 없다.풍부한 단위 테스트 & 큰 기능 단위를 검증하는 테스트Spring / JPA 훑어보기스프링은 Library? Framework?라이브러리는 내 코드가 주체가 된다.프레임워크는 말 그대로 이미 프레임이 짜여있고, 그 프레임에 짜맞추는 방식으로 코드를 작성하게 됨.Spring IoC(Inversion of Control)DI(Dependency Injection)AOP(Aspect Oriented Programming)ORM (Object-Relational Mapping)객체 지향 패러다임과 관계형 DB 패러다임의 불일치이전에는 개발자가 객체의 데이터를 한땀한땀 매핑하여 DB에 저장 및 조회 (CRUD)ORM을 사용함으로써 개발자는 단순 작업을 줄이고, 비즈니스 로직에 집중할 수 있다.JPA (Java Persistence API)Java 진영의 ORM 기술 표준인터페이스이고, 여러 구현체가 있지만 보통 Hibernate를 주로 사용한다.반복적인 CRUD SQL을 생성 및 실행해주고, 여러 부가 기능들을 제공한다.편리하지만 쿼리를 직접 작성하지 않기 때문에, 어떤 식으로 쿼리가 만들어지고 실행되는지 명확하게 이해하고 있어야 한다.Spring 진영에서는 JPA를 한번 더 추상화한 Spring Data JPA 제공QueryDSL과 조합하여 많이 사용한다.타입 체크, 동적 쿼리JPA 에서 주로 사용되는 어노테이션들@Entity, @Id, @Column@ManyToOne, @OneToMany, @OneToOne, @ManyToMany@ManyToMany: 일대다 - 다대일 관계로 풀어서 사용한다. [후기]본격적으로 테스트 코드에 대한 학습을 시작한 주간이었다. 개발자로 일을 한지 꽤 오래되었지만 테스트를 작성해본 적이 많지 않아서 테스트를 작성하는것에 언제나 애를 먹었었는데, 기초적이고 이론적인 내용부터 자세히 공부하고 예제로 따라해보니 지금까지 잘 모르고 지금까지 완벽하게 이해하지 못하고 넘어갔었던 내용들을 어느정도 해소할 수 있었던 것 같아 좋았다.

백엔드워밍업클럽백엔드테스트클린코드

한나

✏️[인프런 워밍업 클럽 2기] 프로덕트 디자인 3주차 🐾

이번 3주차는 유독 어렵게 느껴지던 다크모드 구현에 대한 부분을 직접 미션을 통해 구축해보며 많은 이해를 하게 되어 스스로 느끼기에 배리어블에 대한 이해도가 높아졌다고 느껴진 한 주였습니다. 👩‍💻먼저는 다양한 네비게이션 컴포넌트를 만드는 과정을 배웠고 텍스트 링크, 브레드크럼프, 네비게이션 탭, 모바일 하단 네비게이션, 페이지네이션 등 실무에서 자주 사용되는 요소들을 직접 구현해보며 각 컴포넌트의 특성과 사용자 경험에 미치는 영향을 깊이 이해할 수 있었습니다.개인적으로 느끼기에는 다크모드 구현이 3주차의 하이라이트(?) 였던 것 같습니다. 😆 평소에도 다크모드용 색상 변수 설정이 꽤 까다로웠는데, 이번에 웹 접근성 지침(WCAG)의 AA 기준을 고려한 색상 대비 설정 방법을 배우면서 전체적인 프로세스를 명확히 이해할 수 있었습니다. 이 과정에서 배운 내용을 토대로 앞으로 실무에서 다크모드를 구현하는 부분이 자신감이 많이 생길 것 같습니다.이번 주 학습을 통해 사용자 경험을 고려한 네비게이션 설계의 중요성과 접근성을 고려한 디자인 시스템 구축의 가치를 다시 한번 깨달았습니다. 특히 다크모드 구현 과정에서 배운 체계적인 접근 방식은 실무에서 바로 적용해 볼 수 있을 것 같아 매우 기대됩니다. 이런 경험들이 쌓여 더 나은 디자이너로 성장해나가고 싶습니다.📈📌배움네비게이션 컴포넌트 만들기배리어블 다크모드 개념 익히기배리어블 모드 활용과 원리 배우고 구현해보기컴포넌트를 조합해 B2B 이커머스 어드민 페이지 만들기->다크모드, 반응형 멀티브랜드 구현하기📌미션다크모드 배리어블 구현과 B2B 이커머스 어드민 페이지 구현 경험을 통해 색상 대비와 웹 접근성의 중요성을 체감했고, 실제 프로젝트에 적용할 수 있는 실용적인 지식을 얻었습니다. B2B 이커머스 어드민 페이지를 만들면서는 복잡한 정보를 효율적으로 구조화하는 방법과 사용자 편의성을 고려한 UI 설계의 중요성을 깨달았습니다. ❗이건 꼭 알아두자! ꙳꒰ ੭⑅•͈ ·̮ •͈꒱੭다크모드 구현의 핵심 원칙 : 웹 접근성 기준을 고려한 색상 대비 설정 / 배리어블 활용을 통한 효율적인 테마 전환 방법 / 가독성과 사용자 경험을 고려한 생산 선택네비게이션 컴포넌트 설계 시 고려사항들컴포넌트 재사용과 조합의 중요성B2B 이커머스 어드민 페이지 설계📌회고스스로 칭찬하고 싶은 점강의를 반복적으로 시청하며 제대로 이해하고 미션을 진행할 수 있도록 노력했습니다. 특히 다크모드 구현 부분에서 여러 번 복습하여 개념을 확실히 잡을 수 있었습니다.배리어블과 함께 반응형에 대해서도 많이 이해하고 실무에서도 적용해보았습니다. 아쉬웠던 점미션이 당일에 달성하다 놓친 부분이 있어 아쉬움이 있었고 시간관리를 더 효율적으로 관리해야겠다고 느꼈습니다.실무에서 접근성을 많이 고려하지 못했던 것 같아 이번 주차 공부 후 다시 검토를 해나가고 있습니다.보완하고 싶은 점웹접근성을 고려한 디자인을 실무에서도 제대로 적용을 해보고 싶었고 주요 페이지들을 다시 검토해나가고 있습니다.B2B의 특징을 이해하고 기업 니즈나 브랜드에 맞는 인터페이스를 구현해내고 싶습니다. 성공적인 B2B 플랫폼들의 UI/UX 사례를 조사하고 분석하여 다음 주차 미션과제에도 추가적으로 적용해볼 예정입니다.다음 주 계획남은 미션들을 미리 만들어보고 따로 추가적인 구현을 더 해보려고 합니다.그동안의 미션들을 검토하고 놓친 부분이나 이해가 덜 된 부분을 체크하고 추가적으로 공부를 더 해보려고 합니다.

UX/UIUXUI피그마프로덕트디자인볼드UX

vin

[인프런 워밍업 클럽 BE 2기] 백엔드 프로젝트 - 3주차 발자국

이번 주차에서는 포트폴리오 사이트 화면과 어드민 기능을 개발하며, 사이트의 삽입, 수정, 조회 API 구현과 인터셉터 설정을 완료하였다. 타임리프와 부트스트랩을 활용한 뷰 템플릿 구성, 데이터 처리, 예외 관리 등 다양한 기능을 학습하며 웹 개발의 전체적인 흐름을 이해할 수 있었다. 포트폴리오 사이트 화면 개발하기 1RestController와 Controller의 차이점RestController: JSON 데이터를 반환하며, 주로 RESTful API를 구현할 때 사용. HTML 뷰 템플릿을 반환하지 않음.Controller: HTML 등 뷰 템플릿을 반환하기 위해 사용.부트스트랩과 타임리프 프래그먼트 사용부트스트랩 템플릿 적용: 부트스트랩 사이트에서 템플릿을 다운로드하여 프로젝트에 적용.타임리프 프래그먼트 사용: head, footer, navigation 등의 공통 영역을 분리하여 프래그먼트로 구성.th:fragment: 프래그먼트의 이름을 지정해 원하는 곳에서 재사용.th:replace: 프래그먼트를 뷰 파일에 포함할 때 사용.타임리프 문법 활용th:each: 컨트롤러에서 전달된 모델 데이터를 반복하여 출력.th:text: 서버 데이터를 HTML 요소에 텍스트로 삽입.target="_blank": 링크 클릭 시 새 탭에서 열리도록 설정.포트폴리오 사이트 화면 개발하기 2동적 콘텐츠와 레이아웃 처리th:fragment에 파라미터 전달: 프래그먼트에 파라미터를 전달해 동적 콘텐츠를 처리.th:block 사용 이유: 불필요한 태그 없이 블록을 형성해 th:each와 조건부 렌더링(th:if)을 함께 사용하기 위함.d-inline 태그: 인라인 요소로 배치하여 레이아웃 조정을 쉽게 함.레이아웃 작업: 공통 레이아웃을 th:fragment로 정의해, 수정 시 모든 페이지에 자동 반영되도록 구성.인터셉터의 역할과 설정인터셉터: 컨트롤러보다 앞단에서 동작하며, 여러 컨트롤러의 요청을 잡아 공통적인 처리를 수행.addInterceptors 오버라이딩: WebMvcConfigurer에서 인터셉터를 등록할 때 사용.모든 경로를 대상으로 하며, 정적 자원 경로(CSS, JS 등)는 제외.presentationInterceptor의 HandlerInterceptor 추가:preHandle: 컨트롤러에 도달하기 전 실행.postHandle: 컨트롤러의 응답 후 실행되나, 예외가 발생하면 동작하지 않음.afterCompletion: 예외 발생 여부와 상관없이 항상 실행.HttpInterface 사용: 클라이언트 정보를 수집해 기록.어드민 공통 기능 개발하기클래스 생성 및 관리admin 패키지: 컨트롤러, 데이터 처리, 예외 처리, 인터셉터, 보안 관련 클래스를 구성.예외 처리와 로깅Throwable: 모든 오류의 최상위 클래스.Error: 복구할 수 없는 오류.Exception: 애플리케이션이 복구 가능한 오류.Checked Exception: 컴파일 시점에 예외가 검출됨.Unchecked Exception: 런타임 시점에 발생.ControllerAdvice: 인터셉터와 유사하게 동작하며, 예외 처리를 담당.@ExceptionHandler: 특정 예외를 처리하는 메소드.Logger 사용: LoggerFactory.getLogger를 활용해 로그를 기록.DTO 개발companion object: 클래스 내부에서 정적 메소드와 변수를 정의할 때 사용.vararg: 가변 인자를 받아 여러 파라미터를 전달할 수 있도록 함.filterings: 데이터에서 제외할 필드를 관리.classInfo: 클래스의 메타데이터와 정보를 담음.인터셉터 추가postHandle 오버라이딩: 메뉴 데이터를 modelAndView에 추가해 특정 페이지에 전달.addInterceptors 설정: admin 경로에 인터셉터를 추가하며, 정적 자원(CSS, JS 등)은 제외.데이터 조회 기능 개발하기조회 기능 구현context 패키지: 화면과 관련된 설정을 서버에서 관리.orElseThrow: 데이터가 없을 경우 예외를 발생.@field: 필드 유효성 검사를 수행.@PathVariable: 경로 변수를 통해 데이터를 전달.@RequestBody: 요청 본문 데이터를 객체로 변환.@Validated: 입력 데이터의 유효성을 검사.데이터 삽입, 수정, 삭제 기능 개발하기DTO와 데이터 처리form 패키지: DTO 역할을 하는 클래스들을 생성해 데이터 전달에 활용.ifPresent 사용ifPresent: 값이 존재할 때만 특정 동작을 수행하도록 처리.[미션4] 조회 REST API 만들기이번 미션에서는 제품, 브랜드, 카테고리, 재고에 대한 조회 API를 개발하고, 각 경로(/api/products, /api/brands, /api/categories, /api/stocks)에 대해 테스트 코드를 작성하였다.이번 미션에서는 조회 API 개발 및 테스트 코드 작성을 통해 RESTful API의 기본 구조를 익히고, Null 처리와 영속성 관리를 경험하였다. 특히 **?.let {}**과 ?: 엘비스 연산자를 활용해 null-safe한 코드를 작성하는 방법을 익혔으며, 서비스 계층 분리를 통해 더 효율적인 설계를 계획하게 되었다.ProductDTO에서 발생한 Null 처리 이슈와 해결조회 API를 구현하는 과정에서 ProductDTO 내의 brand와 category가 null일 경우 NullPointerException이 발생하는 문제가 발견되었다. 이를 해결하기 위해 ?.let {} 구문을 사용해 null-safe하게 처리하였다.?.let {}의 역할?.let {}: 객체가 null이 아닐 때만 코드 블록 내부를 실행한다.예시:brand = product.brand?.let { BrandDTO(it) }product.brand가 null이 아닐 경우에만 BrandDTO를 생성하고, 그렇지 않으면 실행되지 않음.엘비스 연산자(?:) 사용조회 로직에서는 **엘비스 연산자 ?:**를 사용하여, 값이 null일 경우 대체 동작을 수행하도록 하였다.?: 연산자: 왼쪽의 값이 null이면 오른쪽 값을 반환한다. product = stock.product ?: throw IllegalArgumentException("제품정보를 찾을 수 없습니다..")만약 stock.product가 null이면 IllegalArgumentException을 던지도록 처리.영속성 설정: Cascade = PERSIST재고와 관련된 엔티티를 영속성 컨텍스트에 포함시키기 위해, cascade = PERSIST 옵션을 사용하였다. 이 설정은 엔티티가 함께 영속화될 수 있도록 보장하며, 이를 통해 테스트 코드가 문제없이 성공적으로 실행되었다.재고 수량 설정과 서비스 계층 분리 계획현재 재고 테이블의 재고 수량(stockCount) 설정은 Stock 엔티티의 메서드를 통해 처리하고 있다.하지만, 이 로직을 추후 삽입 및 수정 API에서 더 깔끔하게 관리하기 위해 서비스 계층으로 분리할 계획이다.

웹 개발백엔드워밍업클럽백엔드프로젝트웹개발

vin 1개월 전
유진

인프런 워밍업 클럽 BE 2기 - 클린코드 / 테스트코드 발자국 3주차

강의 출처 Practical Testing: 실용적인 테스트 가이드 학습 내용단위 테스트JUnit5AssertJ(assertThat(actual).isEqualTo(expected)..)테스트 케이스 세분화 하기해피 케이스 (항상 통과하는 테스트)예외 케이스 -> 경계값 테스트 (범위, 구간, 날짜 등)테스트 하기 어려운 영역은 구분하고 분리해야 한다. (테스트 내부에 있는 값을 파라미터, 상수로 분리)현재 날짜/시간, 랜덤한 값, 전역변수/함수, 사용자 입력 등 표준 출력, 메시지 발송, db에 기록하기 등TDD : Test Driven Development프로덕션 코드보다 테스트 코드를 먼저 작성하여 테스트가 구현 과정을 주도하도록 하는 방법론실패하는 테스트 작성(RED) -> 테스트를 통과하는 최소한의 코딩(GREEN) -> 구현 코드 리팩토링(REFACTOR)TDD의 핵심가치 - 피드백DisplayName문장 : A이면 B이다. / A이면 B가 아니고 C이다.테스트 행위에 대한 결과까지 기술도메인 용어를 사용하여 추상화 된 내용 담기테스트의 현상을 중점으로 기술 X특정 시간 이전에 주문을 생성하면 실패한다.(X)영업 시간 이전에는 주문을 생성할 수 없다.(O)BDD : Behavior Driven DevelopmentTDD에서 파생된 개발 방법Given : 시나리오 진행에 필요한 모든 준비 과정(객체, 값, 상태 등)When : 시나리오 행동 진행Then : 시나리오 진행에 대한 결과 명시, 검증 미션Readable Code 강의의 지뢰찾기 프로젝트로 단위 테스트 작성하는 미션. CellSnapshotTest(셀의 상태 - 빈 셀, 지뢰 셀, 숫자 셀, 열지 않은 셀), CellPositionTest(Cellposition 생성 - 해피 케이스, 0 미만의 인덱스 Cellposition 생성 불가 - 경계값 테스트), GameBoardTest(지뢰 셀을 오픈하면 게임상태 Lose로 변경), ConsoleInputHandlerTest(사용자가 1을 입력하면 셀 오픈). 총 3개의 테스트 클래스와 8개의 테스트를 작성했다. GameBoardTest와 ConsoleInputHandlerTest는 테스트에 실패 했는데, GameBoardTest의 경우는 검증하고자 하는 메소드에서 값을 제대로 불러오지 못하여 실패했다. ConsoleInputHandlerTest는 Scanner를 테스트 해야 했는데 NoSuchElementException이 발생해 테스트에 실패했다.  회고평소에 테스트에 대한 고민이 많았었는데, 강사님의 라이브 코딩으로 테스트 하는 법을 배울 수 있어서 좋았다. 무엇을, 어떻게 테스트 해야 하는지는 아직 어려움이 있어서 꾸준한 노력이 필요할 것 같다. 다음 주에는 강의 완강을 목표로 끝까지 최선을 다해야겠다.

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

허수빈

[인프런 워밍업 클럽 2기 클린코드 & 테스트 코드] 3주차 발자국

해당 글은 [인프런 워밍업 클럽 2기 클린 코드 & 테스트 코드]에 참가하여 박우빈님의 <Readable Code: 읽기 좋은 코드를 작성하는 사고법> 강의를 듣고 작성한 글입니다. ✍ 이번주 강의 요약테스트는 왜 필요할까?테스트 코드를 작성하지 않는다면안정성 보장 X유지 보수 어려움테스트 코드로 작성하면 소프트웨어의 빠른 변화에 유연하게 대처 가능! 단위 테스트간단한 카페 키오스크 프로그램을 만들어 수동 테스트와 자동 테스트 비교하기JUnit5를 사용하자해피 케이스와 예외 케이스 모두 검증해야 한다. -> 경계값 테스트로! TDD : Test Driven Development실패하는 테스트 작성 -> 구현부 없는 프로덕션 코드최소한의 코딩으로 테스트를 통과하게끔 구현리팩토링 테스트는 [ ]다.테스트는 문서다.테스트 코드는 프로덕션 기능을 설명하는 문서가 될 수 있다.@DisplayName을 이용하여 코드를 설명하자BDD -> Given, When, Then을 이용한 시나리오 기반 테스트 5-1. Spring & JPA 기반 테스트 : Persistance Layer여러 모듈이 협력하는 기능은 통합 테스트를 진행한다.Persistance Layer는 데이터베이스와 상호 작용하는 부분이다.JPA 코드를 테스트하는데, 단위 테스트와 유사하다. 🏃 미션Day12Readable Code에서 진행했던 StudyCafe 프로그램을 기반으로 단위 테스트를 작성했다. 뭘 테스트하는게 좋을까... 고민했는데 일단 가장 중요한 건 돈💸이니까 주문 금액을 테스트해야겠다고 생각했다! 이용권별(시간권, 주간권, 고정권) 로 합계를 계산하는 로직을 테스트하기로 결정!BDD를 이용하여Given : 각 시간 또는 주간을 기준으로 SeatPass를 생성하고 (고정권은 LockerPass도 같이) 이를 기반으로 Order 객체를 생성했다.When : getTotalPrice()를 실행시켰다.Then : totalPrice의 값이 계산 결과와 맞는 지 확인했다.그 다음엔 파일에서 이용권 목록을 읽어왔을 때, 각 이용권 타입에 맞는 이용권 목록을 제대로 추출하는 지 테스트 했다.BDD를 이용하여Given : seatPass 파일을 읽어와서 리스트에 담았다.When : findPassBy()를 실행시켰다.Then : 각 이용권 타입과 일치하는 지 확인했다.마지막으로 이용권의 할인된 가격을 제대로 계산하는 지 테스트했다.BDD를 이용하여Given : 할인율이 존재하는 seatPass를 생성했다.When : getDiscountPrice()를 실행시켰다.Then : discountPrice의 값이 계산 결과와 맞는 지 확인했다. 🗒️ 회고이번주는 제법 부지런히 강의를 들어서 뿌듯했다👍👍미션 구현 자체는 그렇게 어렵지 않았는데 내 테스트 코드가 맞는 건지는 모르겠다......ㅜㅜㅋㅋㅋㅋ 아무튼 제출의 의미를 두는 걸로...클린 코드 강의보다 테스트 코드 강의가 더 재밌다. 매번 프로젝트 할 때마다 테스트 코드 쪽은 손도 못대서 그런지 더 많이 제대로 알고 싶은 마음이 든다. 완강까지 화이팅! 

웹 개발워밍업클럽

Yoo Seung Hwan

[인프런 워밍업 클럽 2기 백엔드 프로젝트 과정] 3주차 발자국

I. 3주차 학습 내용  1일차 - 포트폴리오 사이트 화면 개발부트스트랩  템플릿 수정2일차 - 어드민 공통 기능 개발0) 오류의 종류자바 계열에서 오류는 크게 Error와 Exception으로 나뉜다Error는 애플리케이션에서 대응할 수 없는 오류로 - Stack OverFlow Error와 같이 개발자가 해결할 수 없는 오류이다.Exception은 애플리케이션에서 대응할 수 없는 오류로 - RuntimeException 과 같이 개발자가 대응하는 코드를 작성할 수 있는 오류이다.  1) 예외 처리 RuntimeException : 실행시점에 발생하는 예외 처리를 위한 클래스예외는 다양한 경우가 있을 수 있다. 하지만 모든 예외에 대응할 수 없으므로 그 외의 오류에 대응하는 코드를 작성해주어야 한다. Exception을 통해 예외를 정의해주고 Advice의 @ExceptionHandler를 통해 예외에 대한 처리를 지정해준다 2)DTO2-1 공통 Api 응답 포맷Api 응답의 공통 포맷 작성companion object: 클래스의 메서드를 각 클래스의 인스턴스 없이 호출할 수 있게 해줌 수정, 삭제, 저장 성공시에 대한 포맷을 작성해줌 2-2 폼 DTO공통 폼 요소 정의사용자 입력폼을 정의 포맷, 강의에서는 타입별로 text, date, select로 나눔 나는 개인 프로젝트에 date는 필요 없어서 text, checkbox, select 타입 포맷을 지정함 3) Interceptor요청과 응답 사이에서 특정 작업을 수행하는 역할interceptorConfiguration을 통해 admin 하위에 경로가 adminInterceptor에 영향을 받게 함addIPathPatterns - 특정 경로를 인터셉터 처리에서 포함excludePathPatterns - 특정 경로를 인터셉터 처리에서 제외 3일차 - 데이터 조회, 삽입 수정, 삭제 기능 개발  II. 3주차 미션 - 조회 API 개발하기3주차 미션강의 계획대로 진행하다 보니 과제가 조회 api 개발이 presentation을 통해 Json 포맷으로 웹 페이지의 결과를 띄우는건줄 알았는데 아니였나 보다 이번주 마지막 강의를 들어보니 조회 api는 따로 있었다. 망했다일단 Json을 통해 presentation 페이지에 띄우는건 어려운점이 크게 없었다. 사용자 정보를 저장하는 엔티티 이름을 User로 지정해서 SQL 예약어와 겹쳐서 User로 지정된 변수명과 연결된 클래스를 전부 UserInfo로 바꿔야 하는 문제 외에는 없었다. 조회 api 개발은 아직 진행 중이다. 연결된 엔티티가 정보 전체를 받아오는 문제, 리포지토리를 통해서 조회를 다시해야 하는 문제가 있어 엔티티, 리포지토리 코드를 전체적으로 수정하고 있다. 선택된 책 엔티티가 유저 엔티티 자체를 인자로 받다 보니 api를 개발할때 넘겨줄 인자가 없어 조회 코드를 작성하지 못해 userid만을 참조하도록 하고 selecbook repository에 getbyuserId를 추가하는 작업을 추가하는 중이다. 3주차에서 완주를 결국 실패하게 됬지만 모든 과정을 꾸준히 지속해 나갈 생각이다.     III. 3주차 회고3주차 미션은 지금까지의 미션 중에서는 가장 어려웠다. 지금까지는 전체적인 아키텍쳐 구조를 잘 몰라도 어느정도 따라할 수 있었는데 테스트 코드가 까지 통과해야 하는 코드를 작성해야하다 보니 기존에 잘못 쓴 코드들을 다 들어내고 작업해야 하는 경우도 있었다. 처음 하는 작업이다 보니 설계단계에서부터 실수가 많이 보여 시간을 많이 들이고 있는 중이다. 그래도 이 부분을 잘 정리해서 다음부터는 좀 더 삽질을 덜 하게 되도록 노력하겠다. 경험 덕분에 클린 코드에 대한 새로운 관점이 생겼고 아키텍쳐에 대해 자세히 공부해야 겠다는 생각이 들었다. 코드 설계단계의 중요성도 새로 깨닫게 되었다.지금은 그저 미션을 위해서 끄적여 놓은 코드에 불과하지만 추후 과정이 끝나고 여유가 생겼을 때 코드를 좀 더 다듬고 이번 경험을 토대로 프로젝트 전체를 재설계하여 좀 더 완성도 높은 프로젝트로 완성하고 싶은 욕심이 생겼다.

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

채널톡 아이콘