inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

Spring Boot TDD - 입문부터 실전까지 정확하게

테스트 격리에서 테스트 랜덤 실패 이유

해결된 질문

101

3831568

작성한 질문수 15

0

69강 테스트 격리에서 테스트가 랜덤으로 실패하는 이유가 뭔가요?
싱글톤때문에 발생하는 문제인건 알겠는데 조회할 때 Exception이 생기는 이유를 모르겠습니다. ㅠㅠ

tdd spring-boot 아키텍처 junit

답변 2

1

이규원

안녕하세요. 강의 수강해주셔서 고맙습니다.

69번 수업이면 많이 진행하셨네요. 꼭 끝까지 완료하세요. :)

 

해당 수업에서 실패하는 테스트가 달라지는 정확한 이유는 저도 모르겠습니다. 그래서 프로그래밍이 어렵다고 말씀드린 것인데요.

분명한 것은 README.md 파일 내용에 따라서 JUnit이 테스트를 실행하는 순서가 달라진다는 점입니다. 그래서 서로 맥락을 공유하는 테스트 중 먼저 실행되는 테스트는 성공하고 나중에 실행되는 테스트는 실패하는데, 이 순서가 테스트와 무관한 파일의 내용에 영향을 받다 보니 우리 입장에서는 말씀하신 것처럼 '랜덤으로' 실패하는 것처럼 느껴지는 것입니다.

 

혹시 설명이 부족하다면 말씀해주세요!

1

3831568

답변 감사합니다. 그래도 제가 조금 더 확인을 해봤는데요

- POST /seller/products
- GET /seller/me
- GET /shopper/me

이렇게 세 개를 동시에 실행할 때 문제가 생기더라구요

저는 200번이랑 500번 에러가 랜덤으로 발생했는데요


testFixture를 사용할 때 Interceptor에 인증정보가 들어있어서 authenticated는 통과되는데
shopper 테스트를 진행할 때 interceptor에 있는 인증정보가 seller이거나 그 반대일 때는 findById에서 데이터를 찾을 수 없어서 500번이 뜨고,
interceptor에 있는 인증정보와 테스트의 엔티티가 같을 때는 200번이 뜨는 것 같아요

그래서 각 테스트마다 interceptor를 초기화하는 방식을 생각해봤습니다.

@AfterEach
void tearDown(@Autowired TestFixture fixture) {
    fixture.client().getRestTemplate().getInterceptors().clear();
}

 

이것을 POST /seller/products 에 추가하고 재실행하니까 에러없이 완료되더라구요

이렇게 해도 되는걸까요?

1

3831568

생각해보니 이 방식으로 하면 모든 테스트마다 interceptor 초기화 코드를 추가 해야해서 번거로울 수 있을 것 같네요

1

이규원

문제를 해결하는 방법은 여러가지가 있을 수 있고 각 상황에 따라서 가장 적합한 방법을 선택하면 된다고 생각합니다. :)

0

인프런 AI 인턴

안녕하세요, 인프런 AI 인턴입니다. 3831568님.

테스트가 랜덤하게 실패하는 상황은 주로 테스트 간의 격리가 제대로 이루어지지 않을 때 발생할 수 있습니다. 특히 Java의 Spring Framework에서는 각 테스트가 독립적으로 실행되어야 하며, 동일한 상태나 컨텍스트를 공유하지 않도록 주의해야 합니다. 아래에 가능한 원인과 해결 방법에 대해 설명드리겠습니다.

테스트 격리 문제의 원인:

  1. 상태 공유: 싱글톤 빈이나 공유된 리소스가 여러 테스트에서 동일하게 사용될 때 문제가 발생할 수 있습니다. 이러한 싱글톤 객체는 인스턴스 변수에 상태를 저장할 수 있으므로, 하나의 테스트 케이스에서 변경된 상태가 다른 테스트 케이스에 영향을 미칠 수 있습니다.

  2. 컨텍스트 재사용: Spring Framework에서는 테스트 간에 애플리케이션 컨텍스트를 재사용합니다. 특별히 컨텍스트를 초기화했거나, 깨끗하지 않은 상태가 남아 있을 경우, 다른 테스트에 영향을 미칠 수 있습니다.

  3. 데이터베이스 상태: 테스트 중 데이터베이스에 대한 변경 사항이 롤백되지 않거나 지속되면, 이후 테스트가 예상과 다른 결과를 얻을 수 있습니다. 테스트 데이터가 정확히 초기화되지 않았을 때 발생합니다.

해결 방안:

  • 테스트 메서드 간 상태 분리: 각 테스트 메서드에서 사용되는 객체는 반드시 초기 상태를 가져야 합니다. @Test 메서드마다 객체나 서비스를 새로 생성하여 상태를 분리하는 것이 중요합니다.

  • @DirtiesContext 사용: 특정 테스트 메서드가 컨텍스트를 더럽혔다고 판단되면, 해당 테스트를 마친 후 컨텍스트를 재생성하도록 @DirtiesContext를 사용할 수 있습니다.

  • 데이터 초기화: 각 테스트는 독립적으로 데이터베이스를 정리하거나 필요한 데이터를 삽입하여 시작해야 합니다. Spring의 @Transactional 어노테이션을 사용하여 테스트 후 데이터베이스를 롤백하도록 구현할 수 있습니다.

이와 관련하여 더 이해하고 싶으시다면, “프로젝트 규모가 큰 경우 @SpringBootTest 실행 속도 문제”에서 테스트의 격리와 성능에 대한 추가 토론을 참고하실 수 있습니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

라우팅 테이블 설정 중 궁금한게 있습니다.

0

26

1

10년간 CTO 활동을 하신 부분에 대한 질문

1

97

2

테스트 시나리오 유효하지 않은 경우는 언제 도출하나요?

1

107

2

테스트 클래스명 을 강의처럼 만드신 이유가 따로 있을까요?

1

121

2

현업에서도 현재와 같은 방식? 으로 TDD를 하는것이 일반적인가요??

1

116

1

아키텍처와 TDD의 오해에 대해 질문드립니다.

1

116

2

임의데이터 generator방식과 @Transactional에 대한 고찰

1

75

2

내부 설계에 의존하는 테스트 관련 질문 드립니다.

1

81

2

테스트 시나리오 관련 질문 드립니다.

1

76

2

@SpringBootTest 어노테이션의 classes 관련 질문 드립니다.

1

68

2

거짓 음성, 거짓 양성 관련 질문 드립니다.

1

86

1

30. 누락된 테스트 시나리오 발견

1

79

2

69.테스트격리 / 과도한 테스트 격리의 문제 중 '부적절한 설계 왜곡'

1

81

2

"오해: 단위 테스트와 통합 테스트를 잘 분리해야한다." 에 대한 질문

1

798

2

아키텍처 개선

1

119

1

병렬 처리 시 질문

0

110

2

assertThat 상태 코드 비교

1

84

1

테스트 코드 작성 범위 고민

1

241

3

질문드립니다.

2

106

1

거짓 양성, 거짓 음성 질문

2

159

2

cqrs 명령 아키텍처 개선 질문

1

147

2

거짓 양성 감지 노하우 질문입니다

4

790

2

질문드립니다.

1

152

2

프로젝트 규모가 큰 경우 @SpringBootTest 실행 속도 문제

2

1615

1