회고/일상 후기 회고

넥스트스텝 ATDD with Spring 수료 회고

민돌v 2023. 8. 21. 11:17

 

으아아아아아 수료했다아아아아🔥🔥🔥🎉🥳


 

약 2달전에 NEXTSTEP 에서 진행하는 "ATDD, 클린 코드 with Spring 7기" 라는 교육을 수강했다! (https://edu.nextstep.camp/)

1달 반정도 같이있었던 첫 개발 사회생활의, 첫 번째 사수님이 수강하셨고 추천해주셨던 강의인데,,
그때 당시 "단위 테스트도 잘 못하는데 무슨 인수테스트냐;;" 라는 생각에 꼭 나중에 들어봐야지 다짐하고 1년이 지난 지금 드디어 수강을했고, 수료를 했다

넥스트스텝은 다양한 주제의 시즌제(?) 강의들이 존재하는 교육 플랫폼이다. 
사수님 덕분에 알게되었지만, 큰 관심을 가지게된건 여러가지 복합적인 이유가 있지만 가장 큰건 catsbi 님의 회고글 이였다.
(신기하게도 catsbi 님도 리뷰어 중에 있었다! 물론 나는 리뷰를 못 받았지만?!)

되게 흥미롭게 읽었고, 한창 TDD 나 객체지향에 관심을 가지고 구글링을 해보면 양질의 자료는 NEXTSTEP이 출처인 경우가 종종 있었다.

 

catsbi 님의 회고글을 읽고 TDD → ATDD → 인프라공방 이 순으로 꼭 수강해야지! 했지만 가격이 상당히 쎄기에,,, TDD는 패스!

 

비싸!

 

 


 

자! 이제 약 6주간 ATDD 를 수강하면서 배운것을 짧막하게 정리하면서 회고글을 써보고자 합니다😄

 

[목차]

  1. ATDD 교육 소개
  2. 배운점
  3. try?

 

1. ATDD 미션 소개

교육은 약 6주간 매 주차의 미션을 수행하는 형식으로 진행된다.
강의는 매주 목요일마다 있었고, 해당 주차의 미션 리뷰, 질문, 피드백, 다음주차 미션 소개, 그 사이의 짤막한 지식, 키워드, 미션 힌트를 위한 강의 등을 알려주신다.

→ 근데 6주가 지났는데, 수강자들의 리뷰가 활발하다고 1주 더 빠른 리뷰 받을 수 있게 교육기간을 늘려주기도 했습니다.
괜히 유명한 교욱이 아니라는 생각이 들었다😂


1) ATDD 미션

미션의 베이스 목표는 지하철 노선도를 구현하는 것

1주차

 

2~3주차

 

4주차 

 

5주차 

 

📌 좋았던 점은, 미션 위주지만, 해당 미션을 수행하는게 목적이 아닌, 더 나은 방법으로 수행이 목적이였다.

5주차의 미션을 보면, RestDocs의 문서화가 주된 목적이지만,
미션세부사항에 "문서화를 위한 코드와 인수테스트를 위한 코드가 중복 해결" 등과 같은 실제 업무에서도 사용할 수 있을정도의 강도로 교육이 진행되었다.

 


 

2) ATDD 강의 후기

→ 사실 내가 생각했던 완전(?) 강의는 아니였다.
약간 학교나, 세미나, 혹은 지식 전달의 강의일줄 알았는데 "정보 공유의 장" 느낌이 나에게는 강하게 들었다.

 

강사님은 거의 모든 질문에 답변을 해주셨다.
실시간 질문뿐만 아니라 매 주차 강의 전에 구글폼으로 질문을 와장창 받으시고, 이걸 강의에 꼭 Q&A를 해주시는게 참 신기했다

 

장점

  • 현업에서 일하시는, 굉장한 커리어를 가지시는 분이 모든 질문에 친절하게 눈높이를 낮춰서 답을 해주시고, 같이 답을 찾아나갈려고 하시니까 듣는 재미가 있었다.
  • 솔직히 이렇게 어떤 상황(미션 코드 or 주제)을 공유하면서, 모르거나 확신을 못가졌던 관점에 대해 물어볼 수 있는 기회가 생가보다 별로 없는데 이 부분은 너무 좋았다.
  • 또, 강의를 같이 수강하시는 분들이 대부분 현직자분들이다보니 수준이 상당히 높다고 느껴졌다.
    질문에 대해 같이 토론하시는데 답변들이 하나같이 굉장(?)했다.

 

단점

  • 이 교육이 매 주차의 미션위주이고, 강의또한 미션에 맞춰지기 때문에 어쩔수없이 다른 미션 진행자분들의 진행률에 따라 강의가 밀리는 느낌도 있었다.
  • 이 부분은 누군가에게는 장점일 수도 있고, 단점이 될 수도 있다 생각하는데,, 나는 너무 밀리는 느낌도 받지않았고 녹강도 제공해주셔서 솔직히 좋았다!

 


 

2. 교육기간동안 배운 것 정리

솔직히 너무 많아서 키워드만이라도 정리하자는 마음으로 적어봅니당

 

내가 배운거

  • 인수테스트란, 인수테스트 하는법, ATDD, TDD
  • 개발 프로세스
    • 요구사항으로 인수조건 도출 → 문서화 → 인수 테스트 → 로직 구현 →  단위테스트 → 로직 구현(반복) → 인수테스트 검증
  • 리뷰하는 법?
  • PR 보내는 방법 
  • 커밋 쪼개기 (작게, 작게)

 

그 외에 뭐 도메인 주도 아키텍쳐, 기술들 많이 배웠지 정리 잘하자 

  • 리치도메인
  • 도메인 주도 아키텍쳐
  • 패키지 의존성 개선
  • 직접 참조 vs 간접 참조
  • 책임연쇄 패턴의 적용
  • HandlerArgumentResolver (@AuthenticationPrincipa 구현체 Custom)

 


1. 인수테스트란

ATDD 란 Acceptance Test Driven Development 를 의미합니다.
Acceptance는 사전적인 의므로 "허락"을 뜻합니다. 즉 인수테스트란 마지막 허가를 위한 테스트로 저는 이해를 이했습니다.

 

1) Acceptance Test (in extreme programming)

✔️ 애자일(xp)에서의 인수테스트

  • 사용자 스토리를 검증하는 "기능 테스트" 를 인수테스트라 지칭합니다.
  • 사용자 스토리(기획)로 테스트할 시나리오를 지정 후 → 시나리오 기반의 요구사항을 테스트하는 과정을 거칩니다.

✔️ 원래 인수테스트 의미

  • 소프트웨어 이외 다른 분야에서도 사용되는 용어
  • 보통 마지막 단계에서 수행하는 테스트를 의미 → 승인을 위해 (👏🏻 마지막 단계에서 Accpetance 되기 전에 수행하는 테스트라고 추정)
  • 👏🏻 즉, 최종 단계에서 작업을 종료 시켜도 되는지 검증하는 테스트인수테스트 !!

 

📌 교육 미션 진행시에도 → 실제 운영환경과 유사한 테스트환경을 구현하여, 해당 기능이 동작했을때 의도했던데로 잘 동작하는지 E2E 테스를 작성하여 진행합니다.

  • 즉, 인수테스트 = 등대 테스트 = 수용 테스트 = 통합 테스트 = 인수 테스트
  • 어떤 관점으로 바라보는가, or 테스트의 목적이 무엇인가에 따라서 부르는 이름은 얼마든지 달라질 수 있다고 생각합니다.
  • 교육에서의 인수테스트는, 개발자가 아닌 기획자와 함께 바라볼 수 있게! 라는 목적도 포함하였습니다.
    (그래서 한글 메소드 사용 + 가독성 중시)

 

2) ATDD를 하는 이유

  • 구현전에 인수 테스트를 수행하는 경우 팀의 생산성이 2배가 되는 것을 확인했다. - 제프 서덜런드
    • 개발 자체의 기간은 늘어날 수 있다. (솔직히 작업량이 꽤 생기는거 같음)
    • 단, 요구사항을 명확하게 인지하면서 개발하기 때문에 → 불필요한 수정 과정을 줄일 수 있다.
  • ATDD는 작업의 명확한 시작과 끝을 제시한다. → 테스트가 성공되는 순간. 작업이 끝나는 것.
  • TDD의 부족한 부분 보완 가능
    • TDD는 도메인도 개발해나가면 단위테스트로 기능의 수행을 검증하는데 매우 뛰어나지만
    • 전체적인 흐름이나 시나리오를 놓치게되는 경우가 생김
  • 빠른 피드백
    • 구현한 기능을 배포하지 않고 테스트로 확인 가능

 

→ 인수테스트가 결국 E2E 테스트이기때문에 메모리 디비(H2) 로 내가 수행할려는 상황을 먼저 세팅해주어야 하기 때문에 이부분이 상당히 귀찮았다.
→ 하지만, 그럼에도 불구하고 통합테스트시, post-man 으로 내가 확인하는거보다 코드상으로 남기고, 확인하는게 편할때도 있었다.
→ 📌 코드로 남긴다는게 중요한거 같음 


 

3) ATDD (인수테스트 주도 개발) 프로세스

✔️ 요구사항 분석 인수조건 도출 → 문서화 → 인수 테스트 → 로직 구현 →  단위테스트 → 로직 구현(반복) → 인수테스트 검증

(예시)

인수 조건 정의

  • 사용자 스토리 (누가/무엇을/왜)
  • 인수 테스트가 충족해야하는 조건
  • 인수 조건을 표현하는 시나리오 기반 표현 방식 사용(ex. Given/When/Then)
  • 인수 조건 작성 방법
    1. 검증하고자 하는 when 구문 먼저 작성
    2. 기대 결과를 의미하는 then 구문 작성
    3. when과 then에 필요한 정보를 given을 통해 제공
/**
 * Feature: 지하철 경로 검색 
 * Scenario: 두 역의 최소 시간 경로를 조회 
 * Given 
 * 지하철역이 등록되어있음 And 지하철 노선이 등록되어있음 And 지하철 노선에 지하철역이 등록되어있음 
 * When 
 * 출발역에서 도착역까지의 최소 시간 기준으로 경로 조회를 요청
 * Then 
 * 최소 시간 기준 경로를 응답 And 총 거리와 소요 시간을함께 응답함 And 지하철 이용 요금도 함께 응답함
 */

인수 테스트 작성

  • 인수 조건을 검증하는 테스트
  • 실제 요청/응답 환경과 유사하게 테스트 환경 구성
@DisplayName("두 역의 최소 시간 경로 조회")
@Test
void findPathByDuration() {

    //given
    교대역 = 지하철역_생성_요청("교대역").jsonPath().getLong("id");
    강남역 = 지하철역_생성_요청("강남역").jsonPath().getLong("id");
    양재역 = 지하철역_생성_요청("양재역").jsonPath().getLong("id");
    남부터미널역 = 지하철역_생성_요청("남부터미널역").jsonPath().getLong("id");

    이호선 = 지하철_노선_생성_요청_후_id_추출("2호선", "green", 교대역, 강남역, 10, 30);
    신분당선 = 지하철_노선_생성_요청_후_id_추출("신분당선", "red", 강남역, 양재역, 10, 10);
    삼호선 = 지하철_노선_생성_요청_후_id_추출("3호선", "orange", 교대역, 남부터미널역, 2, 20);

    지하철_노선에_지하철_구간_생성_요청(삼호선, createSectionCreateParams(남부터미널역, 양재역, 3, 30));
    
    // when
    var response = 두_역의_타입에따른_경로_조회를_요청(교대역, 양재역, PathType.DURATION.name());

    // then
    assertThat(response.jsonPath().getList("stations.id", Long.class)).containsExactly(교대역, 강남역, 양재역);
    assertThat(response.jsonPath().getInt("distance")).isEqualTo(20);
    assertThat(response.jsonPath().getInt("duration")).isEqualTo(40);
    assertThat(response.jsonPath().getInt("fare")).isEqualTo(DEFAULT_FARE + 200);
}

 

4) ATDD 테스트 도구

Spring Boot Test

  • 테스트에 사용할 ApplicationContext를 쉽게 지정하게 도와줌 → 실제 어플리케이션에 등록된 빈을 테스트 환경에서도 쓸 수 있게 해준다.
  • 기존 @ContextConfiguration 의 발전된 기능
  • SpringApplication에서 사용하는 ApplicationContext 를 생성해서 작동
  • 참고 : [Spring] 테스트 환경 격리 시키기

RestAssured

  • REST-assured는 Rest API 의 테스트 도구
  • 지금까지 MockMvc만 썻는데, RestAssured가 가독성과 문서화에서의 중복제거면에서는 훨씬 좋았다.

JsonPath

  • RestAssured랑 같이 사용하면 불필요한 Response 객체를 만들 필요성이 사라짐

 

2. 관리 의존성 vs 비관리 의존성

관리 의존성

  • 의존하는 대상이 어플리케이션 내부에서만 접근할 수 있는 경우
  • 내 어플리케이션이 관리할 수 있기 떄문에 관리 의존성 !

비관리 의존성

  • 의존하는 대상이 내부 뿐만 아니라 외부에서도 접근이 가능한 경우 → 비관리 의존성의 경우 테스트가 매우 힘듬
  • 👏🏻 강의에서는 비관리 의존성은 대체(mocking)을 관리 의존성은 실제 협력객체를 추천한다고 함

 

의존성 테스트 방법

  1. 실제 외부 의존성 사용
    • 비관리 의존성은 실제 외부 의존성을 사용할 경우 속도도 느리고, 외부 동작에 의존적인 테스트가 됨
    • 실제 의존이 불가능 하기도 함 → 결제 테스트
  2. Fake
    • ex 깃허브 로그인
      • 깃허브 로그인 시 호출하는 외부 API를 실제 깃허브에 보내지 않음
      • 테스트용 properties를 이용하여 테스트 서버에 요청 보내게 하기
  3. Stub

 

 


3. 리팩토링의 원칙

  • 인수테스트가 있으면 → 리팩토링 하다가 hot fix 처리건이 와도 안전하게 인수테스트가 성공했던 시점의 커밋으로 언제든 돌아올 수 있다.
  • 인수테스트가 없다면 → 인수테스트를 작성하고 → 리팩토링 하고자하는 프로덕션 코드의 단위테스트를 수정해야한다.
    1. 프로덕션 코드를 보호하는 단위테스트를 유지하기 위해 (복붙) 을 추천

 

TDD 사이클

  1. 구조를 설계하기
    • 요구사항에 맞춰 구조를 설계하는게 먼저이다. (테스트 전에 요구사항 기반으로 설계가되어야한다.)
    • 그런 다음 확장성을 고려하여 구조를 설계하는데 → 이때 TDD 가 큰 도움이 된다.
  2. 새로운 테스트 만들기
    • 기존 프로덕션 코드와, 테스트 코드를 두고 새로운 테스트 코드를 만든다.
  3. 기능 구현하기 (테스트 성공 후 리팩터링)
    • 새로운 테스트코드를 먼저 작성하고 → 테스트에 성공하는 코드로 리팩토링한다

 


4. 커밋 작게 쪼개기

미션을 진행하면서, 리뷰어님의 리뷰를 받기위해 반나절~하루를 기다려야하기 때문에
한번 받을때 알차게(?) 리뷰를 받고싶었습니다

 

📌 커밋에 대해서 크게 신경써본적이 없어서 그냥저냥 커밋 컨벤션만 맞춰서 작업이 끝나면 일괄적으로 파일만 나눠서 아래처럼 커밋을하는 버릇이 있었는데

 

리뷰할떄 내 개발흐름을 보여줄 수 있으면 리뷰어님들도 리뷰하기 편하지 않을까?
더 좋은 리뷰를 받을 수 있지 않을까? 라는 생각에 커밋 잘하기를 시도해 보았습니다.

  1. 커밋을 작은 단위로
  2. 작업 끝 커밋이 아닌 → 개발 도중도중 커밋
  3. 내 개발 흐름을 알 수 있도록 번호 붙히기

 

👏🏻 훨씬 깔끔하고 보기 좋은 커밋이 된거 같습니당
점진적으로 커밋을 작게 → 흐름을 알 수있도록 개선해 나갔는데
"커밋 내역에 따라, 더 자세하고 소프트적인 리뷰를 받을 수 있었습니다 (느낌적인 느낌?)"

 

 

+ PR 잘보내기

미션이 진행되고 과제가 어려워질수록 좋은 리뷰를 받기위해, PR 도 신경써서 보내게 되었습니다.

  1. 처음에는 "PR 후 → 리뷰를 받으면 궁금한 점 질문" 이런식이여서 답답한감이 있었습니다.
  2. 그래서 추후에는 → PR 자체가 하나의 리포트인 것처럼 먼저 궁금한 부분이나 봐줬으면 좋겠다 싶은 부분에 코멘트를 남겨놓았습니다

 

ㅋㅋㅋㅋ,,,, 초반의 PR

 

후반 부 PR

 

+

 

❗️추가적으로 ATDD 교육의 장점 중 하나가 같은 요구사항을 수행하는 다른 개발자분들을 PR 훔쳐보기(?) 인데

취준때 같이 스파르타 부트캠프를 진행했던분의 PR 을 보고 많은 반성을 하게 되었다.(링크)
이런 PR 을 받으면 진짜 리뷰할 맛 나고,,, 너무 좋을거같다는 생각이 들었고,, 이런게 같이 일하고싶은 개발자겠구나 생각이 들었다.. 배우자

 


 

3. 회고 KPT

Keep

  1. 이 교육이 시작한다고 떴을 때. 여유로운 상황이 아니였기 때문에 할까말까 망설이다 냅다 결제부터 했는데, 참 잘한거 같다
    • 망설이다가 또 못들었으면 다음 교육도 못들었을거라는 확신이 든다.
    • 역시 무서워도 도전해야, 죽이되든 밥이되든 결과가 나오는 것 같다.
    • 아무것도 하지않으면 아무일도 일어나지 않으니,, 앞으로도 냅다 갈겨버리자!

지노형 사랑해

 

 

2. 솔직히 미션하다가,, 나쁜마음 계속 들었는데, 그래도 계속 계속 조금씩 커밋했다. 

  • 끝까지 해서 수료하니까 얻어갈 수 있는게 참 많이 생겼다.
  • ex) "이거 리뷰 다 반영해야할까..? 귀찮은데... 어려울거같은데.. 내가 한 방법도 리뷰어님이 틀린건 아니라고 했는데,,"

 


 

Problem

  • 없다! 열심히 했고 재밌게 했다!
  • 굳이 아쉬운 점을 뽑자면, 매주 배운것을 정리하지 못했다는 점?
  • 하지만 체력이 안되었던 걸!

 


 

Try

  1. 기억은 금방 사라진다. 잊기 전에 블로그에 잘 정리하자 꼭!
  2. 인수테스트는 도구일 뿐! 내 코드에 필요한 부분 잘 생각해서 적용해보자, 안 써도 문제는 없지만 썻을 때 편한점도 느꼈잖아?!
  3. 커밋 쪼개는 습관 앞으로도 잊지말고 들이자
  4. 돈 많이 벌어서 인프라공방도 수강하자~~ 끝! 

 

 

 

2023-06-26(월) ~ 2023-08-09(수) 꽉 채워 겨우 수료해서 받은 나의 수료증! 야호

🔥🔥🔥