강의를 들으며 제일 강조하시는게 "요구사항 충족" 이라고 생각했습니다. 처음부터 아키텍처를 정해놓지 않은 상태로 요구사항 충족을 목표로 달리는 형태로 설명해주셔서 TDD의 의미나 철학을 이해하는데 도움은 많이 됐습니다! 궁금한 것은 현업에서도 새로운 프로젝트를 시작할때 이와 같은 방식으로, 아키텍처를 특별히 정해놓지 않고 개발하는것이 일반적인가요? 테스트 표면을 통해 아키텍처를 유연하게 변경 가능하다고 하신 말씀도 이해를 했는데 서비스 기획 및 설계 단계에서 서비스의 성격/특성에 맞추어 아키텍처정도는 어느정도 정하고 가는것도 괜찮지 않을까 생각하여 여쭤봅니다!!
안녕하세요, 강사님! Spring Boot TDD 강의 정말 잘 듣고 있습니다. 강의 내용 중 궁금한 점이 생겨 질문드립니다. 보통 Spring에서 개발할 때 Controller-Service-Repository 구조의 레이어드 아키텍처를 많이 사용하는데요, 강의에서는 컨트롤러가 직접 리포지토리의 save 같은 메서드를 호출하면서 비즈니스 로직을 처리하는 경우가 있는 것 같습니다. 혹시 이것이 강의의 핵심 내용에 집중하기 위해 코드를 단순화 하신 것인지, 아니면 강사님께서 실제로 선호하시는 개발 스타일 이신지 궁금합니다. 만약 후자라면 어떤 장점이 있는지 그 이유에 대한 의견을 여쭙고 싶습니다. 더불어, "TDD를 잘하려면 인터페이스를 많이 사용해야 한다"는 것이 일종의 오해라는 말씀에 크게 공감했습니다. 그런데 왜 개발자들 사이에서 이런 오해가 생겨나게 된 것인지 그 배경이 궁금합니다. 마지막으로 추후에 비즈니스가 복잡해지면 테스트가 깨졌을 때 어디가 문제인지 파악이 어려울 것 같은데요 이에 따른 문제를 어떻게 해결하시나요? 단위테스트를 추가로 작성하시는지도 궁금합니다.
안녕하세요, 강사님. TDD 관련 강의 항상 잘 듣고 있습니다. 강의 내용을 따라 실습을 진행하던 중, 테스트 격리 전략에 대해 궁금한 점이 생겨 질문 남깁니다. # 강의에서 다뤄주신 상황 강의에서처럼 여러 테스트 메서드에서 동일한 이메일 값을 사용하니, 테스트 클래스 전체를 실행했을 때 JPA의 유니크 제약 조건 위반 에러가 발생했습니다. 이로 인해 개별 테스트는 성공하지만 전체 테스트는 실패하는 상황에서 궁금증이 생겼습니다. # 제가 먼저 생각한 해결책: @Transactional 을 이용한 롤백 저는 강의를 들여면서 이 문제를 해결하기 위해, 각 테스트 메서드에 @Transactional 애너테이션을 붙여 테스트가 끝나면 자동으로 롤백시키는 방식을 먼저 떠올렸습니다. 이 방법으로 각 테스트가 독립적인 트랜잭션 내에서 실행되고, DB 상태를 다음 테스트에 영향을 주지 않는 상태로 유지할 수 있다고 생각했습니다. ##강사님의 방식(임의 데이터 generator)에 대한 질문## 그런데 강사님께서는 강의에서 롤백 방식을 사용하지 않으시고, UUID 등을 활용해 매번 고유한 이메일 주소를 생성해주는 데이터 제너레이터 방식을 사용하셨습니다. 강의에서도 @Transactional 을 성능 등 여러가지 이유로 인해 사용하지 않았다고 하셨는데요. @Transactional 을 이용한 롤백 방식도 충분히 좋은 해결책이라고 생각했는데, 강사님께서 UUID 생성 방식을 선택하신 특별한 이유나 설계 철학이 궁금합니다. 혹시 제가 생각한 롤백 방식에 비해 UUID 생성 방식이 갖는 실용적인 장점(ex. 롤백을 하지 않으니 디버깅의 용이성(?))이 있을까요? 두 방식의 장단점과 어떤 상황에서 어떤 전략을 선택하는 것이 실무에서 더 좋을지에 대한 강사님의 고견을 듣고 싶습니다. 감사합니다!
강의를 들으면서 내부 설계에 의존하는 테스트라는 것이 무엇인지 조금 헷갈려서 질문 드립니다. 강의 초반에는 테스트가 내부 설계에 의존해서는 안된다고 말씀 주셨습니다. 내부 설계에 의존하게 되면 테스트가 깨지는 등의 부작용이 발생할 수 있기 때문이라는 점도 함께 말씀 주셨는데, 이번 강의에서는 내부 설계에 의존해야 하는 케이스를 설명 해주셨습니다. 다만 왜 이런 케이스에는 내부 설계에 의존해야 하는지를 확실하게 이해를 하지 못했습니다. 조금 더 자세한 질문을 드리자면 내부 설계의 의미 내부 설계에 의존해야 하는 이유 이 두가지를 잘 이해하지 못한 것 같습니다. 내부 설계라는 것이 클라이언트가 실제로 사용하는, 외부로 공개된 인터페이스를 제외한 모든 부분을 말하는 것일까요? 이번 강의에서 내부 설계에 의존해야 하는 이유는 클라이언트는 어떤 방식으로 암호화를 하는지 알 필요가 없다. 하지만 현재 공개된 인터페이스로는 실제 비밀번호가 평문으로 저장이 되었는지, 아니면 정말 암호화가 이루어져 저징이 되었는지를 확인할 수 있는 방법이 없다. 그러므로 실제 암호화 로직을 테스트 해야한다 (내부 설계에 의존해야 한다) 정도로 이해했습니다만 제가 맞게 이해한 것인지 감이 오질 않습니다. 요약하자면 내부 설계란 외부로 드러난 인터페이스 외적인 것들을 말하는 것인지 왜 내부 설계를 의존해야만 하는 상황이 발생하는지 정도일 것 같습니다. 감사합니다.
테스트와 코드간 성장 헙력 관계를 보면서 문득 궁금증이 들었습니다. 테스트 시나리오는 작성하면서 시나리오의 순서 역시도 중요하지 않을까? 하는 의문이 들었습니다. 단순한 기능들은 (예시로 들어주신 회원가입)은 테스트 시나리오의 순서에 큰 영향을 받지 않을 것 같으나 좀 더 복잡한 로직, 예를 들면 금액 계산과 같은 로직은 테스트 시나리오를 작성함에 있어서 순서를 신경 써야 할까요? 좋은 예시가 떠오르지는 않지만 예약 시스템을 만들면서 테스트 시나리오를 짠다고 했을 때 테스트 시나리오의 순서대로 코드가 성장이 된다고 가정하면 테스트 시나리오를 작성하는 순서 역시도 중요한 부분 중 하나일 수 있겠다는 생각이 들었습니다. 강사님은 테스트 시나리오를 작성 하실 때 순서를 크게 신경 쓰지 않으시나요? 아니면 로직의 흐름을 미리 어느정도 파악해 두시고 시나리오를 그 흐름에 맞춰 작성하시나요? 두서 없는 질문이라 정말 죄송합니다.
섹션 2 강의를 듣고 난 후 퀴즈를 푸는데 다음과 같은 문제가 나왔습니다. 소프트웨어 테스트에서 코드의 실제 문제는 있지만 테스트 결과는 성공으로 나타나는 오류 유형은 무엇일까요? 문제를 읽다보니 거짓 음성과 거짓 양성이 헷갈리기 시작했습니다. 시스템에 문제가 있으나(코로나 양성) 테스트(코로나 검사)는 시스템에 문제가 없다(코로나 음성)라고 나왔으니 거짓 음성이다. 라고 이해하면 되는 것일까요?
실무에 바로 적용하는 프런트엔드 테스트 - 2부. 테스트 심화: 시각적 회귀・E2E 테스트
안녕하세요 e2e 테스트는 비용이 많이 들어서 어떻게 관리를 하는지 궁금합니다. - 파이프라인에서 매번 CI 에서 돌리기에는 서버나, 시간이 개발 생산성을 잡아 먹을 것 같은데요. 점점 e2e 테스트가 쌓여 나갈떄 어떤 전략을 취할 수 있는지 궁금해요. GPT로 리서치하니까 보통 2가지를 병행해서 스케줄러 + 온디맨드 실행 같이 관리 한다고 하는데, 실제 현업에서는 어떻게 활용하고 계신지, 제가 리서치한 내용 말고 더 효율적이거나, 추천할만한 전략 , 이외의 고려사항 소개해주실 수 있으면 알려주시면 감사하겠습니다. 스케줄 실행 (Nightly/주말 풀스윗) EventBridge → ECS Fargate RunTask (Spot 가능) → Playwright 러너 대상: 스테이징(or PR 프리뷰 URL) b. 산출물: 트레이스/비디오/리포트 S3 업로드, Slack에 요약/링크 온디맨드 실행 (PR 코멘트/수동 트리거) Bitbucket Pipeline에서 aws ecs run-task 호출(또는 ChatOps 슬래시 커맨드) 태그/폴더/샤드 인자 넘김 → 필요한 부분만
"이 간단한 정규식을 사용하면 지금까지 테스트는 모두 통과할 것 같긴 한데 사용자 이름 정책에서 허용되지 않은 문자들은 걸러지겠지만 허용이 되는 문자들이 정규식에 반영되지는 않습니다" -> 그렇기 때문에 기존 테스트는 유지하면서 새로운 테스트케이스를 추가한다로 진행이된다. 부분에서 추가되는것이 이해가 안되어 질문드립니다. 이전 "email속성이 올바른 형식을 따르지 않으면 400 상태코드를 반환" 에선 누락된 부분을 기능을 수정하는 방식으로 해결해왔는데 왜 "username 속성이 올바르지 않은 형식을 따르지 않으면" 에서도 테스트케이스 추가가아닌 기능을 수정해서 해결해야하는것 아닌가? 또 기존의 "올바르게 요청하면 204 반환" 의 케이스와 의미가겹쳐 중복된 테스트케이스 추가 즉 잘못된 케이스추가가 아닌가? 라고 생각됩니다 어떻게 생각하시는지 여쭤보고싶습니다! 초반부이지만 최고의강의 잘듣고있습니다. 감사합니다
안녕하세요. 강사님. 강의를 보고 개인 웹사이트를 만들었는데요. https://mirihomepage.com/ 로그인이 안됩니다;;; superuser도 있고, 카테고리/google 사이트 등록까지 분명 다 했는데, https인증 받고, 도메인 연결하고 그러는 사이에 뭔가 달라진건가싶습니다...
학습 관련 질문을 남겨주세요. 어떤 부분이 고민인지, 무엇이 문제인지 상세히 작성하면 더 좋아요! 먼저 유사한 질문이 있었는지 검색해 보세요. 서로 예의를 지키며 존중하는 문화를 만들어가요. Business Layer 테스트(1)의 13:32초 즈음에서 OrderCreateRequest가 Product의 id값이 아니라 productNumber를 요청 dto로 받았는데 그 이유가 있나요? 저라면 id를 받도록 설계할거같은데 이유가 궁금합니다. 실무에서는 보통 저렇게하나요?
스프링부트 강좌를 신청했습니다. 전에 듣기론 이강좌이후에 포토폴리오 강좌가 출시된다고 하셨던것같은데...확실하지않아서 다시 질문올립니다. 이강좌가 마지막인가요? 아니면 이후 한번더 새로운강의가 출시되는건가요??? 만약 포토폴리오 강좌가 출시예정이라면 현재 이강좌와 어떤 차별화된 점이있는지도 궁금하고 출시예정일도 궁금합니다. 강의분량은 대략 어느정도될지도 궁금해요
강의: 섹션 14 - 69. 테스트 격리 과도한 테스트 격리의 문제점 중 '부적절한 설계 왜곡'의 예시로 1) new 연산자로 직접 만들어도 좋은 클래스 인스턴스를 굳이 주입, 2) 클래스 의존을 인터페이스 의존으로 변경, 3) private을 public으로 변경 을 들어주셨는데 다음과 같은 상황을 말씀하시는게 맞는지 궁금합니다. 1) new 연산자로 직접 만들어도 좋은 클래스 인스턴스를 굳이 주입 & 2) 클래스 의존을 인터페이스 의존으로 변경: 테스트 대상을 완벽히 격리하기 위해 '단순하거나 변경 가능성 없이 구현체가 하나뿐인 의존 클래스'도 직접 생성 대신 주입받도록 변경해 mock으로 대체함. 3) private을 public으로 변경: 다른 기능들에서 사용되는 private 메서드를 단독으로 테스트하기 위해 public으로 노출시킴. 강의 잘 듣고 있습니다. 감사합니다.
안녕하세요. 강의를 듣다 아래와 같은 내용에 대해 개인적인 생각이 있고, 이 생각에 대해 강사님의 생각이 궁금하여 질문 글 올립니다. "오해: 단위 테스트와 통합 테스트를 잘 분리해야한다." 저 또한, 단위 테스트와 통합 테스트를 분명하게 구분하기에는 모호한 부분이 있다고 생각합니다. 하지만, 저는 이를 분리해서 테스트를 진행하고자 합니다. 명확한 합의는 없으나, 팀 내 혹은 저에게 있어 단위 테스트와 통합 테스트를 아래와 같이 구분하고자 했습니다. 단위 테스트 : 외부의 영향이 존재 하지 않고 가장 작은 단위로써 해당 부분 내에서만 테스트를 진행. 통합 테스트 : 외부의 영향까지 반영하여 테스트. 스프링부트 테스트, JPA 테스트 등 이렇게 분리해서 테스트를 진행하고자 하는 이유는 다음과 같습니다. 테스트에 대한 빠른 피드백 테스트 할 때 빠른 피드백과 빠른 수정이 필수라고 생각합니다. 단위 테스트의 경우 외부 영향 없이, mock을 통해 빠르게 내가 목록화한 테스트를 진행하며, CI 환경에서도 빠르게 피드백을 받을 수 있습니다. 반면, 통합 테스트의 경우 비교적 시간 소비가 많이 됩니다. 스프링부트 테스트의 경우 비교적 적은 시간이 소비되지만, JPA 테스트와 같이 디비에 대한 테스트 혹은 다른 플랫폼( 예 : 키클락 등)을 진행하기 위해서는 테스트 컨테이너와 같은 도구를 활용할 수 있다고 생각합니다. 이러한 도구를 사용함에 있어서 많은 시간이 소비가 될 가능성이 크다고 생각합니다. 특히 저희 회사의 경우 테스트 환경이 많이 좋지 않아 시간이 훨씬 더 많이 걸리게 됩니다. 그래서 저는 단위 테스트랑 통합 테스트를 분리하여 개발 환경에서는 단위 테스트를, 운영 CI 환경에서는 단위 + 통합을 함께하여 테스트를 진행하고 있습니다. 이렇게 분리해서 진행하는 것은 나름 장점이 보이고 있다고 생각하는데 이 부분에 대해 강사님의 의견과 잘못된 부분이 있다면 피드백 부탁드립니다.
안녕하세요. 양질의 강의 덕분에 제한된 시야에서 새로운 인사이트를 얻을 수 있었습니다. 섹션 18 - 안정감 있는 아키텍처 개선 챕터를 수강하고 있으며, 현재까지 강의를 들으면서 궁금 했던 내용 두 가지를 여쭈어보고 싶습니다. 질문 1. " TDD를 사용해 만들어진 먹구름 아키텍처를 어느 시점에서 개선 해야 할까요? " 질문을 하게 된 계기는 전형적으로 많이 사용되는 레이어드 아키텍처를 첫 기능 구현 단계에서 부터 차용하여 개발을 진행 해왔는데, 왜 이 아키텍처를 사용했을까? 란 의문이 없었거든요. 강의에서는 흔히 말해 스마트 UI 패턴으로 요구사항을 충분히 충족 해오며 점진적으로 개선 해왔습니다. 그러다 모종의 이유로 내부 아키텍처를 개선 하면서 진행이 되었는데, 아키텍처를 개선 해야겠다고 느끼는 요소가 무엇인지 궁금합니다. 요구사항이 추가 되었을 때 개발 비용을 최소화 하여 충족 시킬 수 있는가? 라고 생각을 하고 있는데, 현재 까지 불편함을 느낄 정도의 확장성을 강요 받아본 적 없어서 감을 못 잡는 것 같습니다. 질문 2. " 어떤 영역을 대상으로 테스트를 작성해야할까? " - 테스트 코드 작성 범위 고민 위 질문 내용과 답변을 보고 무언가 감이 오는 듯 하나, 아직 정리되지 않는 느낌입니다. API 계층의 동작이 가볍다 또는 무겁다의 판단 기준 API 계층의 동작이 가벼운지 무거운지에 대한 판단은 어떻게 하시는지 궁금합니다. 해당 강의에선 API 계층의 동작이 가벼웠기 때문에 API 스펙에 인수테스트를 진행 한 것 같습니다. 서비스 대상으로 테스트를 많이 실행하고, API 는 간단한 성공 경우에 테스트를 한다 . 이 케이스에선 아래와 같은 테스트 시나리오가 있다고 가정한다면 테스트를 어떻게 하면 좋을까요? - username 속성이 null 이거나 공백이라면 HasUsernameNullOrEmpty 예외를 반환한다 - username 속성이 올바른 형식을 따르지 않으면 InvalidUsername 예외를 반환한다 - username 속성이 올바른 형식을 따르면 User 객체를 생성한다 서비스 테스트에서 위 3가지 케이스에 대해 검증 인수 테스트에서 username 을 정확히 입력한 경우 상태코드와 유저에 대한 정보를 반환 하는지 검증 이렇게 테스트를 구성한다고 이해 했는데 제대로 이해한걸까요? 다시 한 번 질문을 빌미로 감사 인사를 드리면서 고견 부탁드리겠습니다. 항상 건강하세요!
일반적인 JpaRepository를 사용할 경우 Entity -> Domain model 객체로 변환하는데 보통 상세 조회, 목록 조회 시에는 QueryDSL를 사용하고, 또한 조회 시 Projections을 이용하여 Dto로 반환하는데요. 이 때, 조회된 Dto는 User와 마찬가지로 UserDetail, UserList(목록 Dto 명칭이 마땅히 생각나질 않네요.) 와 같은 도메인 모델을 추가로 만들어서 사용하는 건가요? 위와 같은 질문을 드리는 이유는 만약 User가 Team라는 도메인과 연관 관계가 있을 때 Team 정보를 포함하여 응답할 경우 User 따로 조회, Team 따로 조회 하여 응답 dto로 변환해야 할 것같은데 그럼 성능적인 이슈가 생기지 않을까 해서 질문드립니다. (위 예시는 간단해서 성능적 이슈는 크게 없지만 복잡한 도메인에서는 여러 도메인의 정보를 조회해와야 하기 때문에 충분히 성능적 이슈가 있을걸로 판단됩니다.)
강사님 안녕하세요. 전에 독립적인 환경에서 실행하면 병렬처리가 된다고 하셨던 것 같은데, 그렇다면 생성하는 코드 후 id 비교를 할 때 다른 테스트 코드에서 상품이 등록되어 반환되는 리스트가 달라질 수 있다고 생각됩니다. 그렇다면 이런 경우에는 이 테스트가 진행될 때는 다른 테스트가 동작하지 않게 처리하던가 하는 방식이 있나요? 예를 들어 최신 리스트를 반환한다고 할 때 테스트 리스트를 넣고 act 하기 전에 다른 테스트에서 arrange 단계에 추가 코드가 동작되면 act에서 리스트 조회할 때 반환할 때 다른 곳에서 추가한 값이 반환되어 테스트 실패 이렇게 될 것 같아 질문드립니다. 좋은 강의 감사드립니다.