7월 중순경 회사에 합류 하고나서 동료 개발자들과 같이 스터디를 하고 싶은 생각이 있었다. 이런 생각을 하게 된건 이전에 스터디를 통해 얻은게 많았었고, 서로 좋은 자극을 주면서 성장하는 경험을 했던 기억 때문이었다.

정비할 것들이 많았던 시기가 어느정도 지나간 후 9월 초에 스터디 투표를 했었고 TDD 를 해보는 것으로 방향이 정해졌었다.

다양한 주제가 있었지만 최종적으로 이 둘이 경합을...

다양한 주제가 있었지만 최종적으로 이 둘이 경합을...

같이 볼 책도 정했지만 책의 목차를 바탕으로 스터디를 진행하진 않았다.

자바와 JUnit을 활용한 실용주의 단위 테스트 - YES24

스터디 방식은 특정 사람이 발제를 하고 듣는식으로 하지 않고 테스트를 채워나가야 할 서비스 코드를 읽고 엔드포인트에 대한 동작을 검증하는 테스트부터 추가하는 방식을 택했다.

이렇게 시작된 테스트 관련 스터디는 매주 월요일 3달 정도 꾸준히 모이면서 작업을 이어나갔다. 그리고, 해가 바뀌기 전에 종료해도 될거 같아 스터디 회고를 각자의 관점으로 기록으로 남겨보려고 한다.


이안

처음 팀에 합류하고 파트를 셋업하는 위치에 있다보니 스터디를 통해 많은걸 해내려는 목적 보다는 새롭게 셋업되고 있는 파트원들간에 협력할 수 있는걸 이끌어내기 위한 방법으로 스터디를 활용하려는 목적이 더 많았다.

9월의 상황을 돌이켜보면 가장 오래된 파트원의 재직기간이 1~2년 정도인 두분이 있었고 공비서 서비스를 담당하는 백엔드 파트원이 나를 포함해서 5명이었다.

운영해야하는 서비스의 규모에 비해 서비스 히스토리를 잘 아는 분들이 적은 상황이었기 때문에 파트원들이 필요로 하는 스터디를 하되 서비스를 이해하고 개선하는데 도움이 될 만한 방법으로 진행하고 싶었다.

다행히 의견들이 잘 모아져서 CRM 서비스를 분석하면서 부족한 테스트를 붙여보는 방식으로 진행하게 되었고, 스터디가 진행되는 사이 3명이 더 충원이 되었다.

충원된 분들도 열심으로 참석해준 덕분에, 그리고 틈틈히 작업하던 테스트 코드 작업에 속도를 내고자 한 스프린트 정도는 주니어 개발자 분들과 일정 부분 테스트를 추가해본 덕에 전체 컨트롤러 중 1/3 까지는 테스트를 보완할 수 있었다.

나에게 있어서는 기존 시스템을 분석하고 코드를 읽어봐야 하는 시간을 반 강제로 할애할 수 있는 시간이어서 만족스러웠다. 부담이 되기 보다는 기다려지는 시간이었고 파이썬에 익숙한 상황에서 자바로 작성된 코드를 읽고 해석하는것은 레거시 코드의 안티패턴이 주는 불편함 보다는 재미로 다가온 부분도 있었다.

(물론 5년 정도 누적된 코드이다 보니 좋지 않은 구조를 가진 부분이 상당부분 이었지만 이건 다른 방법으로 개선해나가면 되기에..)

다음에 다른 주제로 스터디를 하게 된다면 좀더 밀도있는 진행을 위해 업무 시간을 일정부분 할애할 필요가 있겠다는 생각이 든다. 그리고, 3달 동안 함께하며 고생한 파트원들 에게도 감사하다는 말을 하고 싶다.


레이

헤렌에 입사하기 전 TDD 공부를 계속 해왔지만 아쉽게도 실제 서비스에 적용해본 적이 없었다. 입사 후 공비서 서비스를 개선해야 했는데, 먼저 레거시 코드를 보호하기 위해 테스트 코드를 작성 하기로 했다. 나 혼자 하는 것이 아닌 팀원들과 함께 해야하므로 모두가 TDD에 대해 기본적으로 알아야 한다고 생각했다. 그래서 스터디 주제 선정에서 TDD에 투표를 했다. 이후 TDD에 대한 내용을 스터디하며 실제 서비스 코드에 인수테스트를 작성했다. 스터디하면서 배운 것들을 적용하고 책에선 배울 수 없던 다양한 내용들을 경험할 수 있었다.

모킹도 제대로 해보면서 @Mock/@MockBean, @Spy/@SpyBean 의 차이도 알 수 있었다. Static 메서드에 대해서도 Mockito 라이브러리 버전을 업그레이드하여 MockStatic을 활용해서 진행할 수 있었다. 또 문자발송 레거시 코드를 호출하는 구간을 어댑터를 적용하여 테스트시에는 인터페이스를 모킹하는 것으로 대체하는 등 안정적인 테스트 코드를 작성할 수 있었다. (이전에는 테스트하면 실제 문자가 나갔었다니!?)

TDD는 단순히 테스트를 작성하는 것이 아닌 RED-GREEN-BLUE의 사이클을 돌면서 테스트 작성-피드백-리팩토링을 반복하는 것이 요점이다. 이번 테스트 스터디에서 인수테스트를 작성한 것은 기존 레거시 코드를 보호하기 위함이었기 때문에 완벽한 TDD라고 볼수는 없을 것 같다. 하지만 스터디를 통해 얻은 테스트 코드 작성 경험을 바탕으로 추후 신규 기능 개발할 때, 기존 테스트가 존재하는 레거시 코드를 개선할 때 TDD를 적용해 볼 수 있을 것 같다.


소니

스터디를 하기 전 TDD의 실효성을 실무적으로 경험하고 싶었다. 그래서 현재 서비스 중인 "공비서 CRM 코드에 테스트 작성을 해보자"라고 제안했었고 테스트 작성에 앞서 레거시 코드를 파악하기 위해 같이 한줄 한줄 읽어가며 주석을 남겼고 그 후 테스트를 작성하였다. (레거시 코드 파악이 쉽지는 않았다...😭)

그 과정에서 Mocking 을 위해 @Mock @Spy @InjectionMocks 사용하였고 또한 MockedStatic 을 사용하여 static 메서드를 Mocking 하면서 각각의 차이점과 활용법을 어느 정도 알게 되었다 . 비록 내가 목표했던 STUB에 대한 개념과 사용법, 통합 테스트 외 단위 테스트, MVC 테스트 Repository 테스트 등의 다른 테스트 전략은 같이 못 해보았지만 개인적으로 더 공부해볼 생각이다.

나아가 다음 프로젝트에서는 공부한 내용을 바탕으로 TDD 개발 프로세스를 적용하여 개발 전 먼저 테스트 케이스를 작성해보도록 하겠다.


우디

TDD??

헤렌에 입사 후 처음으로 TDD를 접하였다. 처음 TDD에 대해 간략하게 찾아 보고 든 생각은 ‘과연 테스트 코드 작성에 투자한 시간 만큼 보답을 해줄까?’ 라는 의문이 들었다.

스터디를 시작하다.

스터디는 TDD를 실무에 적용 가능하도록 방향을 잡고 레거시 코드를 개선하고 생산성이 높은 코드로 만들기 위한 과정을 진행하였다. 그 과정은 ‘레거시 코드 분석 및 주석 → 테스트 코드 작성’ 이다. 개인적으로 위 과정은 지루한 면이 컸다. 지금 생각해보면 익숙하지 않은 TDD 방법론에 필요성을 몰랐기 때문이지 않았을까 생각한다. ( 익숙함의 무서움... )

실무에 적용하다.

새로운 기능 개발을 진행하게 되어 TDD 방법론으로 실무에 적용할 기회가 생겼다. 테스트 코드를 작성하고 개발을 진행하였으며, 기획 정책 기준에 맞춰 단위 테스트 코드를 작성하였다. 익숙하지 않은 방식으로 진행하니 ‘이렇게 하는게 맞나?’, 라는 의심이 많이 들고 어색함은 끝까지 이어갔다. 기존 방식 보다 테스트 코드 작성에 시간만 추가되었다..

드디어 의문이 깨지다.

과연 TDD의 방식이 좋은가 라는 의문이 깨진 상황이 드디어 나타났다!! 그 의문이 깨진 순간은 기존 코드에 대한 변경이 필요한 상황 이였다. 기존 코드에 대한 수정이 필요할 때 수정된 부분에 대한 검증이 이보다 편하고 정확할 수 없었다. 테스트 코드 작성을 기획 정책 기준으로 작성하여 더욱 크게 느껴 졌는지 모르지만, 수정한 코드에 대한 검증은 물론, 의도치 않은 오류에 대한 대비할 수 있었다. 더 나아가 내가 개발을 진행한 기능이라도 테스트 코드로써 다른 개발자도 해당 기능에 대한 코드 수정이 가능하며, 보다 확실하고 빠르게 영향도를 검증을 진행 할 수 있겠구나 라고 느꼈다.

내가한게 과연 TDD? 반성하자.

제가 TDD 방법론으로 나름 실무에 적용하였지만 과연 TDD가 맞는가? 이해는 하였는가? 라는 질문을 한다면 No..이다. 아직도 부족함이 많고 이해하려면 더욱 노력을 해야 한다. 그리고 테스트 코드도 아직 완벽하게 작성하지 못한다. 보다 더 나은 코드를 위해 발전해 가야 할 것 같다.. 갈 길은 멀다..

TDD 지식을 나눠주신 팀원들 감사합니다😊


밤둘

TDD 작성의 중요성은 늘 들어왔고, 프로젝트를 진행 시 적용해 보겠다고 생각만.. 하고 있었다. 그러다가 테스트 코드 스터디를 통해 TDD를 배울 수 있는 기회가 생겼고, 회사에서 사용하는 레거시 코드의 테스트 코드를 작성하는 방향으로 스터디를 진행하기로 했다.

처음에는 레거시코드에 대한 테스트를 작성하기 위해 코드를 한땀한땀 따라가며 해당 기능에 대한 이해가 필요했고, 코드의 복잡도가 높아 단위 테스트하는 게 쉽지가 않아 인수 테스트를 진행하는 것으로 결정했다.

인수 테스트를 진행하면서 실제 문자 전송이 되는 부분을 Mocking해야 했는데, TDD 스터디를 진행하기 이전에는 Mocking에 대해 정확히 이해하지 못했다. 막연하게 가짜 객체를 만드는 구나 정도로만 이해 했었는데, 테스트 코드를 작성하면서 Mocking에 대한 필요성을 이해했고, @MockBean/@Mock 어노테이션을 어떤 상황에 각각 사용하는지 이해할 수 있었다. Layer 별 단위 테스트를 진행하지 못한 점이 아쉬웠지만, 나중에 짬짬히 진행해볼 생각이다!


워니

헤렌에 입사하면서 얼마되지 않아 TDD 스터디에 참여하게 되었습니다. 이전부터 TDD의 중요성에 대해서 이야기를 많이 들어봤던터라 스터디하며 실무에 적용해볼 수 있는 기회가 되어 부푼 기대를 안고 참여하게 되었습니다.

mock 객체들을 사용해서 테스트 코드를 작성해보았는데 특히 기억에 남는 부분은 이미지 업로드 테스트를 할 수 있는 S3Mock까지도 사용해봤던 것인데 테스트해보기 위해 사용할 수 있는 리소스들이 정말 많다는 것도 이번 스터디를 통해 알게 되었습니다.

TDD에 대해 아는 것이 전혀 없었던 상태여서 헤매기도 했지만 가이드를 주시는 동료분들이 계신 환경이어서 다행이었습니다. 특히 페어 프로그래밍으로 진행해보면서 많이 배웠는데 함께 참여했던 파트원분들께 이 자리를 통해 감사의 말씀을 드립니다.

개인적으로 아직은 공부해야할 부분이 많기때문에 이번 스터디를 계기로 스터디 진행하면서 미진하게 이해했던 부분, 놓쳤던 부분들이나 새로 배워가야할 부분은 지속적으로 공부하면서 실무에서도 잘 적용해볼 수 있었으면 좋겠습니다. 🙂


혀니

입사 첫날 스터디의 주제도 모르고 참가했을 때, TDD 관련 스터디란 것을 알고 바로 스터디에 함께하고 싶었습니다. 평소 TDD에 관심은 많았지만 테스트 코드를 짜는 것도 아직 익숙하지 않았기 때문에 좋은 기회라고 생각했기 때문입니다.

우선 단위 테스트가 아닌 인수 테스트를 작성하기로 했는데 그 이유는 테스트 코드가 없는 레거시 환경이었기 때문에 리팩토링하기 전에 인수 테스트를 작성하여 기존 코드를 보호하기 위해서였습니다. 단위 테스트 밖에 작성해 본 경험이 없었기 때문에 인수 테스트를 작성해 볼 수 있어서 그 점도 만족 스러웠습니다.

인수 테스트를 작성하기 전에 먼저 레거시 코드를 분석하여 주석을 달기로 했습니다. 기존에 일감을 처리했을 때도 레거시 코드를 분석할 때 이해가 되지 않는 코드나 사용하지 않는 코드들이 있었기 때문에 분석하기 위한 시간이 꽤 소요 됐었는데, 스터디를 진행하면서 팀원 분들이 분석하시는 방법을 보고 많이 배웠고 스터디를 하기 전보다 분석하는 시간도 짧아져서 개인적으로 많은 도움이 됐습니다.

스터디를 통해 테스트 코드에 더 관심을 가지게 되면서 한 메소드를 테스트하기 위해 많은 의존성 주입이 필요하고 mocking 할 것들이 많다면 테스트 대상의 책임이 너무 많고, 그 코드는 테스트 코드를 짜기 어려운 코드라는 것을 알게 되었습니다. 때문에 코드를 작성할 때 어떻게 해야 좀 더 안정적이고 좋은 구조인지 다시 한번 생각해 볼 수 있었던 것 같습니다.

이번 스터디에서는 레거시 코드를 분석하는데 많은 시간을 소요했다는 점이 가장 아쉬웠고, TDD의 장점을 아직 직접적으로 체감해 보지 못했기 때문에 앞으로 TDD를 실무에 적용해 보면서 TDD의 장점을 체감해 보고 싶습니다.


저희와 함께 하고 싶은 분들은 헤렌의 채용 담당자 에게 커피챗을 요청해 보세요! 헤렌은 현재 다양한 개발 직군을 적극적으로 채용하고 있습니다 🚀

헤렌 채용 │ HERREN CAREERS

https://hits.seeyoufarm.com/api/count/incr/badge.svg?url=https://0909.notion.site/7a2ad038118c40e29d2ee75ee06da644](https://hits.seeyoufarm.com/api/count/incr/badge.svg?url=https://0909.notion.site/7a2ad038118c40e29d2ee75ee06da644](https://hits.seeyoufarm.com/api/count/incr/badge.svg?url=https://0909.notion.site/7a2ad038118c40e29d2ee75ee06da644))