-
Notifications
You must be signed in to change notification settings - Fork 227
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
3단계 - 테스트를 통한 코드 보호 #835
base: devfancy
Are you sure you want to change the base?
3단계 - 테스트를 통한 코드 보호 #835
Conversation
826715b
to
f68e084
Compare
- create 또는 update로 설정하면, Hibernate가 테이블을 자동 생성
- 자주 사용하는 메서드는 MenuFixtures 클래스를 활용 - 예외 처리에 대한 메시지 추가 - 작성된 테스트코드를 요구사항에 체크 표시로 반영
- null, 빈값, 공백에 대한 단위 테스트코드 수정
- 테스트코드에 작성된 내용을 기반으로 요구사항의 내용과 일치되도록 수정
- 프로덕션 코드에 예외 메시지 내용 추가
- 테스트 실행 후 DB의 상태를 초기화하기 위해 tearDown 메서드 사용(테스트 환경 초기화)
- 성공/실패 케이스에 대한 테스트코드 작성 - 자주 사용하는 메서드는 Fixtures 클래스에 선언하여 활용
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
일과 병행하시느라 바쁘실텐데, 잘 만들어주셨네요. 고생하셨습니다.
질문1)
리뷰어님께서는 테스트 코드의 범위를 어디까지 작성하는 것이 적절하다고 생각하시는지 개인적인 의견이 궁금합니다. 🙂
-> 보통 코드는 자산이 아니라 부채라고 하는데요. 이것은 상용 코드 뿐만 아니라, 테스트 코드도 마찬가지라고 생각합니다. 깨지기 쉬우면서 비지니스 가치가 없는 테스트 코드는 없는게 오히려 더 낫다고 생각합니다. 가치가 없는 테스트 코드라도 존재하는게 회귀 방지에는 도움이 될 수 있겠지만, 그것 보다 개발 생산성이 저하되는것이 더 치명적이라고 생각해요.
프로젝트별로, 또한 참여 구성원이 누구냐에 따라 테스트 코드의 범위가 달라지긴하지만, 아래 처럼 만들려고 노력합니다.
- 해피 케이스에 대한 인수 테스트
- 도메인 모델이나 중요한 비지니스는 대한 유닛 테스트
-> 편익이 가장 높기 때문에 웬만해서는 만드는 편입니다. - 단순한 crud는 통합 테스트 또는 테스트 안함
한번 유닛 테스트(블라디미르 코드리코프) 책을 읽어 보시는 것을 추천 드릴게요.
질문2)
테스트 격리를 위한 데이터 삭제
-> 테스트 컨테이너를 통해서 테스트를 실행할 때마다 컨테이너를 자동으로 생성하고 종료하도록 설정하는것은 어떨까요? 굳이 제안해주신 방법들 중에 골라야한다면, 저라면 테스트를 위해서 상용코드를 수정하지는 않을 것 같아요. 차라리 jdbcTemplate이나 entityManager를 사용해서 클렌징 작업을 해줄 것 같네요. 테스트 컨테이너 래퍼런스 : https://dev.gmarket.com/76
질문3)
이 부분은 저도 고민이었는데요. 현재는 도메인별로 픽스처 팩토리 클래스를 만들어두고 추상화되고 단순한 생성 메소드를 제공합니다. (예를 들어서 아이디 정도만 정할 수 있는)
만약에 예외 케이스를 테스트하기 위해서 픽스처의 세부적인 상태를 조절해야한다면, 팩토리 클래스보다는 해당 테스트 클래스에서 직접 메소드를 분리해서 만들어요. 팩토리 클래스에서 모든 케이스를 전부 커버할 수 있게 매번 메소드를 유지보수하고 제공하는것은 한계가 존재해서요.
|
||
@ActiveProfiles("test") | ||
@SpringBootTest | ||
public abstract class IntegrationTestSupport { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
테스트 컨테이너를 한번 사용해보는것도 좋을 것 같아요.
작업 내용
리뷰 받고 싶은 부분
이번 테스트코드를 작성하면서
{ClassName}.Fixtures
클래스를 만들어서 활용했고, 매 테스트 실행 후 DB를 정리하기 위해earDown()
메서드를 적용했습니다.아래는 제가 테스트코드를 작성하면서 궁금한 점들을 정리했습니다.
매번 상황에 따라 변화하는 소프트웨어에는 (방향은 있지만) 세부적인 정답은 없기에, 리뷰어님의 개인적인 의견을 주시면 정말 감사하겠습니다 ! 😊
테스트코드 작성시 참고했던 자료
질문1. 테스트코드 작성 범위
테스트 코드를 어디까지 작성하면 적절할지 리뷰어님의 의견이 궁금합니다.
현재
README.md
의 요구사항을 절반 이상 반영하여 테스트 코드를 작성했고, 반영한 부분에는 체크 표시를 해두었습니다.실제 업무에서는 이렇게 꼼꼼하게 테스트 코드를 작성할 시간이 부족한 경우가 많지만, 그래도 하루 최소 30분은 리팩터링과 테스트 코드 작성에 집중하려고 노력하고 있습니다. (하루 1-2개라도 작성하자 !)
특히, 비즈니스에 큰 영향을 주는 부분의 코드 커버리지를 우선적으로 신경 쓰고 있습니다.
예를 들어, 도메인이 커머스라면 정산, 결제와 같은 핵심 도메인의 테스트 코드를 더 집중적으로 작성합니다.
제 개인적인 기준은 비즈니스에 영향을 미치는 코드를 우선적으로 테스트하고, 시간이 허락하는 범위 내에서 우선순위에 따라 추가적으로 작성하는 것입니다.
테스트 코드가 많아질수록 유지 보수 비용도 증가한다고 생각하기 때문에, 모든 코드를 테스트하는 것보다는 효율적인 커버리지를 확보하는 것이 더 중요하다고 생각합니다.
리뷰어님께서는 테스트 코드의 범위를 어디까지 작성하는 것이 적절하다고 생각하시는지 개인적인 의견이 궁금합니다. 🙂
질문2. 테스트를 위한 연관 데이터 삭제, 프로덕션 코드 변경 vs 별도 Repository 추가 - 어떤 방법이 적절할까?
MenuServiceTest 클래스에서 tearDown() 메서드를 통해 매 테스트 실행 후 DB를 정리하고 있습니다.
테스트에서는 연관된 MenuProduct 엔터티를 먼저 삭제해야 하는데, 이때 두 가지 방법을 고려했습니다.
방법1. deleteAllMenuProducts() 메서드를 MenuRepository에 추가하는 방법
테스트에서만 필요한 기능이므로, 실제 운영 환경에서는 불필요한 코드가 될 수 있음
방법 2: MenuProductRepository를 별도로 만들어 deleteAllInBatch() 사용
고민 포인트 🤔
현재 두 가지 방법 중 어떤 것이 더 적절할까요?
실제 업무에서는 연관 관계를 최대한 단순화하고 직접 삭제하는 방식을 선호하는 경우가 많았습니다.
서비스 규모가 커질수록 JPA 연관 관계 복잡성이 증가하고, CascadeType.ALL을 사용할 경우 예상치 못한 삭제 문제가 발생할 가능성이 있기 때문입니다.
이에 대한 리뷰어님의 의견이 궁금합니다. 🙏🏻
질문3. Fixtures의 확장성을 고려할 때, 어떤 구조로 관리하는 것이 좋을까요?
현재 테스트 코드에서 Fixtures를 활용하여 객체 생성을 간소화하고 있습니다. 하지만 서비스 규모가 커질수록 Fixtures에 대한 의존성이 강해지고, 여러 테스트 클래스에서 무분별하게 사용될 가능성이 있어 고민이 있습니다.
특히, 각 도메인별로 Fixtures를 분리하여 관리하는 것이 적절할지, 또는 테스트 클래스별로 필요한 필드만 설정할 수 있도록 개별 Builder 패턴을 도입하는 것이 더 유지보수에 용이할지에 대한 고민이 있습니다.
이에 대한 리뷰어님의 의견이 궁금합니다. 🙏🏻