We will find a way, we always have.

-interstellar

우아한테크코스

[우테코] 방탈출 예약 관리 미션 회고

Redddy 2024. 5. 13. 03:49

레벨 2의 첫번째 미션 방탈출 예약 관리 미션은 페어 감자🥔, 리뷰어 오리 🦆 와 함께 했다. 

 

웹 개발 경험으론 스프링을 배운 상태였지만 로컬 서버에만 띄어보고 배포해본적은 없었다. 대신 파고(파이썬 장고)로는 해본적 있었다.

 

레벨 1 끝날 즈음에 레벨 2엔 어떤 미션을 하게 될지 기대가 많이 됐었다. 이전 기수들을 보면 레벨2의 첫번째 미션은 레벨 1 때 했던 미션을 스프링 버전으로 변경하는 미션이었어서 이번에도 그렇게 될 줄 알았는데, 완전 다른 미션이 주어졌다. 

 

방탈출 예약 관리 미션으로 예약을 추가하고, 예약 시간을 추가하는 미션이었다.

 

1~3단계는 스프링으로 Hello World!, 4~6단계는 DB 적용!, 7~9단계는 요구사항 변경! 이런 느낌이었다.

 

대부분 1~3단계로 step1, 4~9단계로 step2를 진행하였지만, 짧게짧게 가는게 피드백 반영하기 좋을 거 같다고 생각해 오리에게 dm으로 step2는 나눠서 진행하겠다고 전달했다.

 

step3로 나눠 진행

 

조급해하지만 않는다면 이렇게 나눠서 가는것도 각 단계별로 꼭꼭 씹어 먹으면서 갈수 있어서 좋은 거 같다.

 

 

ResponseEntity vs @ResponseBody

레벨2에서 꽤 고민하였던 부분이었고 작성했던 의 계속 추가하고 있다.

내가 내린 결론은 최대한 @ResponseBody를 사용하고 필요한 경우엔 ResponseEntity를 사용하자! 이다.

 

테스트

 

스프링과 DB를 사용하면서 테스트 작성에 대해 고민이 많아졌다.

 

예를 들어 내가 ReservationRepository 클래스의 save() 라는 메서드를 테스트 하고픈 상황이다.

방탈출 예약을 하려면 저장되어 있는 시간중에 하나를 골라 이름과 날짜를 입력하여 예약을 하는 시스템인데, save() 메서드를 호출하기 위해서는 시간이 저장되어 있어야 한다.

 

즉 전처리 과정이 있어야 하는데 3가지 방법 정도를 본거 같다.

 

1. TimeRepository 활용

시간을 저장하기 위해 ReservationRepositoryTest 클래스에 TimeRepository 필드에 추가하여 @Autowired 해주고 saveTime()를 활용하는 것이다.

 

장점: 테스트를 위해서 추가로 sql을 작성하지 않아도 된다. 

 

단점: ReservationRepository만을 테스트 하고 싶은데 TimeRepository에도 의존하고 있다. 만약 테스트가 터진다면 애초에 테스트하고 싶었던 reservationRepository.save()이 잘못된 것인지 아니면 timeRepository.save()에서 잘못된 것인지 쉽게 알 수가 없다.

 

2. jdbcTemplate 활용

jdbcTemplate를 활용하여 sql 작성후 테스트 전에 시간을 저장하는 것이다.

 

장점: 전처리 과정을 쿼리로 작성하여 테스트하고픈 메서드만 사용하여 테스트할 수 있다. 테스트하고자 하는 메서드 실행후 db의 변동사항도 jdbcTemplate으로 select 쿼리를 날려 확인 가능하다.

단점: 테스트 코드에 쿼리문이 수두룩 빽빽해진다. 물론 @Sql을 사용하여 쿼리문을 숨기는 것보다 아예 테스트코드 쪽에 쿼리를 명시하는 것을 선호하는 사람도 있는 듯 하다.

 

3. @Sql 활용

jdbcTemplate는 테스트 메서드 혹은 테스트 클래스안에서 직접 sql을 작성해야 하지만 @Sql 애노테이션을 활용하면 테스트 메서드/클래스 실행 전후에 원하는 sql 파일을 실행시킬 수 있다.

 

장점: 테스트 코드에선 정말 테스트하고자 하는 메서드정도만 보일 수 있고, 중복되는 sql을 줄일 수 있다. 저장 혹은 삭제 테스트는 다른 테스트에도 영향을 줄 수 있는데, @Sql을 활용하면(init하고 truncate하고) 매 테스트마다 동일한 db를 만들 수 있다.

단점: init.sql의 데이터를 수정했을 때 터지는 테스트의 수를 예측할 수 없다. 다시 말해 sql을 살짝만 변경해도 터지는 테스트가 수두룩 빽빽하다. 

 

 

나는 이 세가지 방법중 @Sql 애노테이션을 활용한 방법으로 했다. 

 

우선 단위 테스트에선 테스트 하고자 하는 메서드만 테스트 할 수 있도록 만드는 것이 좋다고 생각한다.

 

예를 들어 예약 삭제 테스트 안에 예약 저장 메서드까지 포함되어 버리면 위험하다는 이야기이다. 검증을 해야하는 테스트에서 아직 검증되지 않은 메서드를 활용하여 테스트를 하고 있는 것이다. 

 

jdbcTemplate를 활용하는 것도 좋은 방법이라고 생각한다. @Sql 애노테이션을 활용하면 초기 데이터를 세팅해줄 순 있지만 저장 이후 검증을 위해선 findById() 나 findByAll() 메서드를 사용해야 한다. 

 

스키마 변경

 

각 단계마다 요구사항이 슉슉 변경되었고, 특히 스키마가 변경되는 일도 잦았다.

 

이해를 돕기 위해 이번 미션 요구 사항을 간단하게 작성해보면,,,

 

1~3단계

  • 이름, 날짜, 시간 받아 예약 생성, 삭제, 조회 기능 구현

4~6단계

  • 1~3단계서 진행한 기능을 db로 구현

7~9단계

  • 예약 시간 생성, 삭제, 조회 기능 구현
  • 예약 생성할 때 등록된 예약 시간 활용

 

큼직 큼직한 요구 사항 변경으로 각 단계마다 밀어내는 코드가 많았고, 리팩터링 할 때마다 깨지는 테스트들도 많았다.

레벨 1에서는 TDD를 한다고 실패하는 테스트를 작성하고 그 뒤 프로덕션 코드를 수정하여 테스트를 통과하게 했다면 이번 미션에선 변경된 요구사항에 따라 프로덕션 코드 먼저 수정하고 그 뒤 실패하는 많은 테스트들을 보고 노가다로 수정해주었다.

 

한번 해보니 이렇게 하는 것은 비효율적인거 같다. 프로덕션 코드 다 만들어두고 거기에 맞춰 테스트 코드를 수정한다면 무슨 의미가 있을까 싶기도 하였다. 

 

앞으론 요구 사항이 변경되어도 레벨 1을 기억하며 테스트 코드먼저 수정해보아야겠다. 

 

페어 회고

 

레벨2 들어와서 데일리조에서 페어가 도는게 아니라 밖으로 돌았다. 그래서 한번도 대화를 나눠본적 없는 크루인 감자와 페어가 됐는데 금방 친해진 거 같다. 

칭찬을 해줘야 힘이 난다고 페어 프로그래밍 시작하기 전에 말해주어 나름 긍정적인 말을 하면서 했던 거 같다. (그렇다고 평소에 부정적인 말만 하면서 하는건 아니다🤗) 

 

이렇게 감자처럼 자신의 치얼업 포인트를 공유하는 것도 좋아보였다. 나의 치얼업 포인트는 무엇일까 고민해보았는데 토론인거 같다. 상대방이 나와 반대되는 의견을 내면 같이 debate 하는게 재밌고 힘이난다. 감자랑 하면서도 토론하자!!!를 외치면서 했었다. 

 

아쉬웠던 점은 1~3단계 끝나고, 이후 단계에 대해 같이 많은 이야기를 나눠보지 못한 것이다. 감자가 되게 일찍 오는 편이라 페어프로그래밍 할 때에는 출입문 앞 명당에 자리를 잡아 그곳에서 같이 페어프로그래밍을 했었다. 그러나 끝나고 나선 그자리에 조조였나 미아를 앉힌다고 쫓아냈다ㅋㅋㅋ 그래서 다시 구라운조가 있는 굿샷 강의장으로 가서 하였다.

 

 

 

📃코드

1~3단계 pr

4~6단계 pr

7~9단계 pr