Spring에 테스트를 넣는 방법을 알려드립니다! 더 나아가 자연스러운 테스트를 할 수 있게 스프링 설계를 변경하는 방법을 배웁니다.
이런 걸
배워요!
Spring에 테스트를 넣는 방법
테스트에 필요한 개념
자연스러운 테스트를 하는 방법
Mockito 없이 테스트하는 방법
의존성과 Testability
헥사고날 아키텍처(Hexagonal Architecture)와 설계
프로젝트 설계를 발전시키는
테스트의 본질을 짚어드릴게요!
테스트에 대한 올바른 의견을 전달해 드리려면, 결국 아키텍처로 끝나야 한다라는 생각을 했기 때문입니다.
테스트에 대한 기본적인 개념을 배우고, Spring(스프링)에 테스트를 어떻게 넣어야 하는지 배웁니다. 더 나아가 자연스러운 테스트를 할 수 있게 스프링 설계를 변경하는 방법을 배웁니다.
테스트가
필요한 이유
테스트에 대한
기본 개념
Spring에
테스트를 넣는
방법
Spring 설계를
진화시키는
방법
클린
아키텍처
헥사고날
아키텍처
다른 회사 다니는 친구는 시대의 요구에 발맞춰서 테스트를 꾸준히 넣어가며 차근차근 성장하고 있습니다. 그런데 우리 회사는 테스트를 넣지 않아요. 뒤처지고 싶지 않습니다. 공부할 의지도 있습니다. 그런데 도저히 이 레거시 시스템에 테스트 코드를 어떻게 넣어야 할지 감이 안 옵니다.
H2를 이용한 테스트는 너무 느리고 DB에 지나치게 종속적입니다. 모든 테스트가 H2를 이용하고 있습니다. 테스트를 돌리기는 부담스럽고, 테스트들이 h2를 공유하다 보니 데이터가 뒤엉켜서 어떨 때는 테스트가 성공하고, 또 어떨 때는 실패합니다.
우리 팀은 사람이 그렇게 많지도 않고, 배포하면서도 그다지 불안함을 느낀 적이 없습니다. 요구사항은 시시각각 변합니다. 근데 TDD를 어떻게 하나요? 테스트는 개발 속도만 늦출 뿐이라고 생각합니다.
시중에 나와 있는 테스트 관련 책이나 세미나를 찾아보면 대부분 그냥 테스트의 장점, 테스트 코드 짜는 법, JUnit, Mockito 정도만 얘기하고 끝납니다. 예제는 딱 입문자의 입맛에 맞을 만큼 간단한 예제 뿐이고요. 그래서 마지막에 가서 책을 덮을 때면 이런 생각이 듭니다.
혼란스러웠습니다. H2를 이용한 JPA 테스트... 뭐 좋습니다. 그런데 ElasticSearch나 Cassandra처럼 테스트용 DB가 없으면 어떻게 테스트하라는 걸까요? 게다가 H2를 이용한 테스트는 정말 치명적일 정도로 느렸습니다. 하루에도 여러 번 돌리기 부담스러웠고요. 테스트는 자주 깨지고 DB 테이블이라도 변경되는 날에는 관련된 테스트도 싹 다 수정해야 해서 시간 낭비 같다는 생각이 들기 일쑤였습니다.
그러던 중 저의 고민들은 아키텍처와 DDD를 공부하기 시작하면서 모두 해결됩니다. 알고 있습니다. TDD는 항상 핫하죠. 그런데 TDD는 정말 매력적이면서도 어려운 방법론입니다. TDD를 해본 적 없는 조직에서 TDD가 유행이니 이제부터 TDD로 개발하려고 하면 그게 될까요? TDD는 생각보다 시작하기 전에 알아야 할 선수 지식과 공감대를 정말로 많이 필요로 합니다.
그래서 TDD를 공부하려면 TDD부터 공부하면 안 됩니다. 테스트를 먼저 공부해야 합니다. 미적분을 하려면 방정식부터 다룰 줄 알아야 하는 것처럼 말입니다.
테스트의 필요성이 느껴지지 않는다면, 아직 프로젝트의 규모가 그리 크지 않거나 테스트가 없어도 될 만큼의 훌륭한 개발 능력과 문화를 갖추신 것 같습니다. 테스트는 정답이 아닙니다! 테스트가 없던 시절에도 훌륭한 프로젝트들이 많이 개발되었습니다. 테스트는 좋은 소프트웨어를 얻기 위한 도구이기 때문에 그 자체가 목표가 아닙니다.
테스트를 하는 방법에만 너무 치중해서 공부하신 것 같습니다. JUnit 사용법, Mockito 사용법, h2를 연동하는 방법을 공부하는 것은 분명 의미가 있는 공부지만 그게 테스트의 본질은 아닙니다. 테스트를 왜 해야하고, 어떤 목표가 있고 그 목표를 달성하기 위해 어떻게 실천해야 하는지를 익혀야 합니다
테스트 프레임워크에 대한 질문 역시 이전 질문과 같은 대답입니다. 만약 여러분이 Typescript
+ Nest.js
를 쓰는 환경에 있다면, 어떻게 테스트하실 건가요? Mockito, H2 같은 테스트 프레임워크 없이도 테스트하는 방법을 익혀야 합니다.
이 원리를 기반으로 한 지식은 다른 프레임워크에서도 통용되는 지식들입니다. Nest.js를 사용하시던, Swing UI를 사용하시던, Gin을 사용하시던... 어디에서든 적용될 수 있는 지식이라 생각합니다.
종장에 가서는 설계에 대한 강의로 이어집니다. 테스트의 가치를 최대한으로 설명해 드리기 위해선 설계에 대한 내용이 빠져선 안 된다 생각했기 때문입니다.
적어도 제가 찾아보기론 국내의 스프링에 테스트를 넣는 법을 알려주는 책이나 강의는 못 본 것 같습니다. 모두 @Mock
, @Spy
이런 어노테이션을 이용하여 mocking하고 의존성 주입 받아 테스트를 작성합니다. 하지만 만약 이런 Mock 라이브러리가 존재하지 않는 환경이라면 어떻게 테스트 하실 건가요? 본질적으로 이러한 어노테이션이 없어도 테스트하는 방법을 알아야 합니다! 그리고 테스트해야 할 대상이 무엇인지도 구분할 수 있어야 합니다.
테스트의 필요성을 알게 됩니다.
프레임워크 없이도 스프링에 테스트를 넣는 법을 알게 됩니다.
스프링을 사용하는 더 나은 방법을 알게 됩니다.
레이어드 아키텍처에서 헥사고날 아키텍처로 변화하는 방법을 이해하게 됩니다.
오리엔테이션
테스트를 추가하고 싶은 조직에서 TDD를 도입할 때 실패하는 이유를 살펴봅니다. 일반적으로 내가 하는 TDD는 왜 실패하는지 살펴봅니다. 테스트에 대한 제대로 된 이해 없이 테스트를 무작정 넣기 시작했을 때 발생하는 문제점들을 같이 살펴봅니다.
테스트에 대한 이론
기본적인 테스트 지식을 공부합니다. 테스트의 필요성에 대해 공감하고 테스트와 설계의 상관관계를 파악합니다. 테스트를 만들면서 개발자는 어떤 고민을 해야하는지 이해합니다. 최종적으로 자연스러운 테스트를 위해 Testability를 높이는 작업에 대해 같이 살펴봅니다.
1부 - 토이프로젝트 기반 테스트 적용
앞으로 사용할 토이 프로젝트를 같이 살펴봅니다. 그리고 토이 프로젝트에 어거지로 테스트를 넣어보며 최대한 테스트를 넣어 커버리지 100%를 달성해봅니다. 이 과정에서 h2, MockMvc, PowerMock같은 외부 라이브러리들을 사용합니다.
최종적으로 만들어진 테스트들을 같이 살펴보며 회귀 버그만을 커버하기 위한 테스트에는 어떤 문제가 있는지 살펴봅니다.
방향성 탐색
우리의 토이 프로젝트에 테스트를 넣은 게 그다지 좋은 방향이 아닌 이유를 같이 살펴봅니다. 더불어 전통적인 레이어드 아키텍처의 문제점에 대해 같이 살펴봅니다. 그리고 어떤 식으로 개선할 것인지, 강연자의 의견을 들어봅니다.
1부 실기에서 무작정 테스트를 넣기 위해 고군분투했다면, 2부에서는 Mockito 같은 외부 라이브러리 없이도 자연스럽게 Mock하는 방법을 익힙니다. 2부 실기를 위해 미리 어떻게 코드를 바꿀지 같이 살펴봅니다.
2부 - 토이프로젝트 구조 설계 개선
앞선 방향성 탐색을 통해 얻은 인사이트를 우리의 토이 프로젝트에 도입합니다. 이 과정에서 구조적인 변화를 줘가며 설계를 개선합니다. 그리고 이 과정에서 아래와 같은 기법들이 사용됩니다.
진화하는 아키텍처
테스트와 설계의 상관관계를 통해 아키텍처를 진화시키는 방법에 대해 같이 살펴봅니다. 레이어드 아키텍처가 어떻게 헥사고날 아키텍처로 변하는지 살펴봅니다. 관심사를 분리하면서 개발자가 도메인에 집중하는 방법을 배웁니다.
현재 카카오에서 일하고 있고, 만드는 것을 좋아해서 퇴근 후에도 항상 무언가를 개발하고 있습니다. "거인의 어깨 위에 선 난쟁이"라는 말이 있습니다. 저 역시 한낱 작은 난쟁이일 뿐이지만, 올라탄 거인의 성장에 도움이 될 수 있도록 지식의 대물림을 위해 노력하고 있습니다. 다수의 주니어 개발자 분들을 멘토링한 경험이 있어서 여러분의 성장을 도와줄 수 있을 거예요.
Q. JUnit이나 Mockito 사용법은 안 알려주시나요?
네, 아쉽게도 해당 강의는 JUnit과 Mockito 사용법에 대한 내용을 다루지 않습니다. 이유는 아래와 같습니다.
Context) 수강생 개인마다 처한 상황이 다릅니다. 이미 몇 번 테스트를 짜본 사람이 있다면, 라이브러리를 다루는 숙련도가 다를 수 있습니다. 회사에서 사용하고 있는 라이브러리가 JUnit이나 Mockito가 아닐 수도 있고. 버전이 달라서 제공하지 않는 인터페이스가 존재할 수도 있습니다. 대표적인 예로 JUnit4에서는 @ParameterizedTest를 지원하지 않습니다. 게다가 앞서 언급 드린 라이브러리들의 사용법이 그렇게 어렵지 않고 관련된 좋은 자료가 이미 너무 많습니다. 하다못해 Github README 파일을 읽거나 공식 가이드를 읽는 것만으로도 충분히 사용법을 익힐 수 있다고 생각합니다. 따라서 사용법은 중요한 내용이 아니라고 생각했습니다.
Test Design) 특정 라이브러리가 제공하는 특정 기능을 이용하여 테스트하는 법을 익히는 것은 그 라이브러리가 없으면 해당 테스트를 할 수 없다는 의미입니다. 도구나 프레임워크보다 테스트를 어떻게 설계하고, 어떻게 테스트 가능한 구조로 바꾸는지가 더 중요합니다. 따라서 이 강의는 도구에 집중하지 않습니다. 테스트는 개발 프로세스의 한 부분입니다. 그러므로 요구사항 분석, 설계 및 배치, 유지보수 같은 맥락에서 고려되어야 할 점을 점검하는 것이 더 중요하다고 생각했습니다.
Q. 이전 강의와의 차이점은 어떤 것이 있나요?
커리큘럼을 보시면 아시겠지만, 이전 강의와 중복되는 내용이 다소 있습니다. 이래야 한다는 것만 덩그러니 설명해 드리기에는 설득력도 부족하고 맥락을 이해시켜드리지 못하기 때문에, 독립적으로 해당 강의도 수강할 수 있도록 강의를 구성하였습니다. 그러니 반드시 목차를 확인해보시고 겹치는 내용이 있는지 확인해 봐주세요.
솔직한 이야기로 이전 강의를 제대로 이해하셨다면 굳이 중복해서 수강할 필요는 없다고 생각합니다. 이전 강의가 구조적으로 왜 이렇게 되어야 하는지를 설명하는 강의였다면, 이번 강의는 실제로 코드 레벨에서 어떻게 풀리는지를 다루는 강의라고 보시면 됩니다.
Q. 수강 전 알아야 할 사항이 있나요?
해당 강의는 스프링이나 JPA를 알려드리는 강의는 아닙니다. 수강자가 대략적인 Spring과 JPA를 다룰 수 있다는 것을 전제로 강의를 진행합니다. 아울러 스프링에 테스트를 넣는 법을 알려드리고 있지만 본질적으로는 의존성을 어떻게 풀어내는지에 대해 초점을 맞춰 진행하였고, 꼭 언어나 프레임워크에 구애받는 내용은 아니라고 생각합니다. 덧붙여, 전공 지식은 필요로 하지 않습니다 :)
💾 수강 전 확인해주세요!
학습 대상은
누구일까요?
Spring에 테스트를 넣고 싶은 분
Spring에 테스트를 어떻게 넣어야 할지 막막하신 분
내가 개발한 Spring 프로젝트가 올바른 설계 구조인지 헷갈리는 분
테스트를 넣어보려 했지만 실패했던 분
H2 같은 테스트 DB가 없는 NoSQL에 테스트를 넣고 싶은 분
선수 지식,
필요할까요?
Java 코드를 이해하실 수 있으신 분
Spring 기본 (Controller / Service / Repository가 무엇인지 아시는 분)
JPA를 사용해보신 분
현재 카카오에서 일하고 있고, 만드는 것을 좋아해서, 퇴근 후에도 항상 무언가를 개발하고 있습니다.
"거인의 어깨 위에 선 난쟁이"라는 말이 있습니다. 저 역시 한낱 작은 난쟁이일 뿐이지만, 올라탄 거인의 성장에 도움이 될 수 있도록 지식의 대물림을 위해 노력하고 있습니다. 다수의 주니어 개발자분들을 멘토링 한 경험이 있어서 여러분의 성장을 도와줄 수 있을 거예요.
깃허브 > https://github.com/kok202
블로그 > https://kok202.tistory.com
전체
25개 ∙ (6시간 20분)
가 제공되는 강의입니다.
내가 하는 TDD는 왜 실패하는가?
16:19
테스트의 필요성과 테스트 3분류
10:42
테스트에 필요한 개념
09:13
의존성과 Testability (1)
06:10
의존성과 Testability (2)
10:35
실기 전 사전 탐색
13:00
토이 프로젝트 살펴보기
09:37