
Readable-code 학습 회고 3주차
Readable-code 학습 회고
목차
1. 강의 수강
일주일간 강의 요약 정리
일주일간 강의 회고
다음 주에 학습목표
2. 미션
미션을 해결하는 과정
어떤 관점에서 접근했는지
문제를 해결하는 과정
왜 그런 식으로 해결했는지
미션 해결에 대한 간단한 회고
강의 수강
강의 요약
TDD
레드 - 그린 - 리팩토링이라는 방식으로 매번 순회하여 코드를 작성하는 방법입니다.
TDD 장점
클라이언트가 필요한 정보만 전달한다고 생각하며 테스트를 작성할 수 있습니다.
빠르게 이미 테스트 코드가 작성되어있어 상호 작용으로 메서드와 테스트 코드가 서로 윈윈하게 됩니다.
DisplayName
1. @DisplayName("음료 1개 추가 테스트")
2. @DisplayName("음료 1개를 추가하면 주문 목록에 담긴다.")
아무것도 모르는 상태에서 테스트 코드에 추가된 정보를 보고 확인할 수 있어야합니다.
Persistence layer 역할
데이터 접근의 역할이 있습니다.
비즈니스 가공 로직이 포함되어서는 안됩니다. 데이터를 수정, 삭제, 추가하는 것에 집중합니다.
DAO, SQLMapper, QueryDSL을 사용하면 비즈니스 로직 작성이 침투할 수 있습니다.
데이터 접근 계층은 데이터에 접근하는 역할만 가져야합니다. 테스트도 마찬가지로 CRUD에 집중하는 레이어 계층이 되어야합니다.
Business layer 역할
비즈니스 로직을 구현하는 역할입니다.
데이터 접근으로 읽어온 데이터를 가공(비즈니스 프로세스)을 하는 계층
트랜잭션을 보장해야한다.
비즈니스 계층은 기능을 구현하는 로직이 들어옵니다.
가장 중요한 역할로 트랜잭션을 보장하는 것입니다.
예외가 발생하면 롤백을 할 수 있도록 작업 단위의 원자성을 가지고 있습니다.
테스트는 언제나 테스트를 작성하는 목적이 있어야합니다.
강의 회고
이미 테스트 코드 강의는 모두 본 상태였습니다.
그래서 복습한다고 생각하면서 보는 중에 readable-code
에서 말씀하신 부분이 나왔습니다.
테스트 코드는 내가 작성한 코드가 예상한 결과대로 동작하는지 확인하기 위해서 작성됩니다.
그리고 다른 개발자가 내 테스트 코드를 보고 어떤 목적으로 테스트 코드를 작성했는지 가독성이 높여야 한다고 생각이 들었습니다.
테스트 코드에서 DisplayName
은 객체지향 프로그래밍의 메서도 명과 동일하다고 생각이 됩니다.
그것을 보는 개발자는 테스트를 실행하여 테스트 결과 목록을 보면서 추상화된 이름을 보고 어떤 목적으로 테스트를 했는지 확인할 수 있게 작성해야한다고 생각이 변했습니다.
기존에 테스트 코드 강의만 봤을 때에는 도메인? 실패/성공이 키워드로 들어가면 안된다 라고 말씀해주신게 이해가 되지 않았습니다.
테스트 코드가 결국 누군가에게 보여지는 문서로 활용될 수 있으려면 DisplayName
만 보더라도 테스트의 목적을 알 수 있어야하고
given when then
으로 문맥을 개행으로 나누며, 어떤 것을 테스트 하는지 사고의 흐름에 맞춰 추상적인 흐름이 보이도록 작성해야된다고 생각이 들었습니다.
예를 들어 단순히 테스트 준비를 Order.create(모든 파라미터)
로 테스트를 준비하면 다른 개발자가 보기에 여기서 중요하게 봐야하는 필드가 무엇인지 한 눈에 들오지 않습니다.
이 부분을 우리가 확인하려는 필드만 파라미터로 보여준다면 this.createOreder('모델명','이름','가격')
만 보더라도 테스트에서 어떤 필드가 사용되는 구나라고 한눈에 보이게 됩니다.
미션
Day 11
테스트 작성하게된 목적을 먼저 나열해보겠습니다.
InputHandler
테스트 코드 작성 목적 : 사용자의 요청에 따라 어떤 결과가 나와야하는지 올바르게 확인되어야 뒤에 있는 로직이 신뢰하고 실행될 수 있기 때문입니다.
@Test
@DisplayName("사용자는 콘솔에 1을 입력하면 시간 이용권이 선택된다.")
void selectByStringOne() {
// given
final String userInputAction = "1";
InputHandler inputHandler = createInputHandlerFor(userInputAction);
// when
StudyCafePassType userActionCafePassType = inputHandler.getPassTypeSelectingUserAction();
// then
Assertions.assertThat(userActionCafePassType).isEqualTo(StudyCafePassType.HOURLY);
}
StudyCafePassOrder
테스트 코드 작성 목적 : 사용자가 선택한 결과에 따라 올바르게 결과가 출력되는지 확인되어야합니다. 실제 비즈니스 로직에서 사용자의 요청과 비용이 다를 경우에는 상상하기 싫습니다.
@Test
@DisplayName("할인이 없고, 고정 이용권과 사물함 이용권을 선택하면 두 이용권의 가격을 합산한 가격이 나온다.")
void calculatePrice() {
// given
final StudyCafePassType userActionPassType = StudyCafePassType.FIXED;
final double discountRate = 0.0;
StudyCafeSeatPass studyCafeSeatPass = createSeatPassFrom(userActionPassType, 200, discountRate);
StudyCafeLockerPass lockerPass = createLockerPassFrom(userActionPassType, 100);
StudyCafePassOrder passOrder = StudyCafePassOrder.of(studyCafeSeatPass, lockerPass);
// when
int price = passOrder.getTotalPrice();
// then
Assertions.assertThat(price).isEqualTo(300);
}
StudyCafeSeatPass
테스트 코드 작성 목적 : 이벤트에 따라 할인된 결과가 예상한 결과와 동일해야하는 것을 매번 확인해야합니다. 실제 돈 거래로 예상한 금액과 다를 경우 머리가 복잡해지는 것을 경험할 수 있습니다.
@Test
@DisplayName("할인율이 1이면 할인되는 금액은 이용권 금액과 같다")
void calculatePrice() {
// given
final StudyCafePassType userActionPassType = StudyCafePassType.FIXED;
final double discountRate = 1;
int passPrice = 100;
StudyCafeSeatPass studyCafeSeatPass = StudyCafeSeatPass.of(userActionPassType, 30, passPrice, discountRate);
// when
int discountPrice = studyCafeSeatPass.getDiscountPrice();
// then
Assertions.assertThat(discountPrice).isEqualTo(passPrice);
}
미션 회고
강사님이 OT때 말씀하신 내용이 기억납니다.
AI에게 도움을 받을 수 있지만 판단력과 지혜와 같이 사람이 결정해야하는 부분에서 능력을 기르는 것이 중요하다.
테스트 코드도 마찬가지라고 생각이듭니다
단순한 테스트 코드 작성은 AI가 손 쉽게 작성하게 해줍니다.
다만 이 테스트 코드를 목적에 맞게 AI가 작성했는지, 테스트 코드를 작성하는 목적이 올바른지 확인해야하는 것은 사람의 몫이라고 생각이 들었습니다.
그리고 추가로 중간평가에 알려주신 다른 사람들과 코드를 비교해보라고 말씀해주신게 정말 도움이 많이 되었습니다.
20줄 남짓한 코드 리팩토링이 사람마다 다르고 어떤 목적으로 리팩토링을 했는지 확인할 수 있는 부분이 많았습니다.
그러면서 제가 놓치고 있던 부분도 확인할 수 있었습니다.
총 3개의 코드를 비교해보았습니다.
매직 스트링
예외 상황에 대한
try-catch
검증을 메소드 체이닝으로 처리
이렇게 다양한 방식으로 검증을 하는 것으로 제 20줄의 코드가 처음과 많이 달라져있었고
그 사이에 다른 개발자분들이 작성한 코드를 보면서 다른 인사이트도 많이 얻었습니다.
출처
강의 링크
댓글을 작성해보세요.