오늘은 원래는 프로젝트 관련된 공부를 하지 않고, 평소 못했던 다른 부분을 공부하려고했다. 독서까지는 이게 가능했는데... 잠깐만 볼까? 하던 계획이, 계속해서 이것저것찾아보고 시도하고 해보다보니 그대로 9시간은 한것같다. 그리고 이 글을 작성하고 나면 어서 빨리 못해본 것들을 시도해봐야겠다.
카프카 메시징 테스트
나는 신발 주문 시스템을 카프카와 연계하여, 이벤트 기반의 아키텍처로 개발하고 있다. 그리고 개발을 할 때 꼭 단위테스트를 작성하여 해당 클래스의 정상작동을 검증하고 있었는데, 유일하게 테스트를 하지 못한(않았던) 부분이 있었다. 바로, 로컬 카프카 클러스터와 상호작용하는것을 검증하는 테스트 이다.
내가 해당 부분을 테스트 하지 않았던 이유는, 내부(애플리케이션)이 아닌 외부요소(카프카클러스터)를 검증할 필요가 있는가? 외부에 의존하는 테스트는 깨지기 쉬운 테스트 이지 않은가? 하는 생각을 했었기 때문이다. 그래서 나는 상호작용을 테스트하는 verify() 메서드를 통해 이벤트를 발행하는 메서드가 호출되면 전달되는 데이터를 확인하고 이를 검증했다.(원하는 데이터가 정상적으로 전달이 되었는지 검증)
하지만 이 생각은 맞으면서도 틀린 생각이라는 것으로 변화하였다. 지난 승원이와의 온라인 만남 간 이야기를 하면서, 테스트의 목적과 테스트를 통해 진정으로 이루고자하는 것에 대한 생각을 다시해보면서, 외부계층(카프카클러스터 등) 또한 내 서비스에 일부분이며, 정상작동함을 검증해야했다.
그렇게 나는 카프카 클러스터 가 정상 작동함을 테스트 할 방법을 찾아보기 시작했다.
[오늘의 헤드라인] 테스트 코드 작성기(2) — Mock
안녕하세요. 오늘의 헤드라인 서버팀의 소프트웨어 엔지니어 Jun입니다. 오늘의 헤드라인에서 ‘python 기반 테스트 코드를 작성한 과정과 고민’을 2편을 공유하고자 합니다.
medium.com
나는 이 글을 보고, 나와 비슷한 생각을 가진 개발자라 생각하여 조금 오래된 글이지만, 질문을 남겼었다. 하지만 아쉽게도 아직 답변을 받지는 못했다.. 그러나 이 글을 계기로, spring-kafka-test 라는 것을 알게되었다.
spring-kafka-test: 외부 Kafka 서버에 의존하지 않는 안정적이고 독립적인 테스트 작성하기
해당 포스팅 이후, 나는 Embedded Kafka 를 사용하여 외부 카프카 서버에 의존하지 않고서 테스트 하는 방법이 존재한다는 것을 알 수 있었다. 그리고 이것이 내 고민을 아주 깔끔하게 해결해 줄 수 있을 것이라 직감했다.
그러나 문제가 (많은) 있었다. 그리고 아직 해당 문제를 해결한 것은 아니지만, 조금씩 앞으로 나아간 과정을 기록해본다.
나는 로컬 kafka 클러스터 설정에 따른 application.yml 에 작성된 설정 값들이 존재했다. 이 때문에 단순하게 Embedded Kafka 를 바로 사용할 수 없었다.
크게 중요한 값들을 이야기해본다면, bootstrap-servers 와 schema-registry-url 을 이야기 할 수 있을 것 같다.
- bootstrap-servers: @EmbeddedKafka 어노테이션에 설정한 값과 일치해야한다.
- schema-registry-url: schemaResgistry 를 Mocking 하는 것임으로, 반드시 주소를 mock:// 으로 해야한다.
schema-registry-url 의 경우 외국 블로그에서 값을 사용하지 않지만, 설정해야한다. 라는 말이 많았는데 아니다. 이것 때문에 진짜 애를 먹었다. 반드시 mock:// 으로 주소형식으로 작성해야한다. 그렇지 않으면 오류가 발생했다. 그리고 schema-registry 를 따로 만들어주어야한다. 카프카 클러스터의 작동을 잘 알고 있다면, 이는 당연한 부분이다. 하지만 나는 몰랐다..
나는 다소 추상적인 카프카의 모습과, 정말 간단한 원리정도만 알고있었다. 그런데 내가 한가지를 빠트려 알고 있었던 것이다.
나는 스키마레지스트리를 깜빡하고 있었고, 이것이 문제가 됬던 것이다.
그렇게 스키마레지스트리를 만들고 (만족스럽지 못한) 테스트를 진행할 수 있었다.
publish(발행) 테스트 를 위한 consumer 클래스?
카프카 이벤트 발행을 검증하기 위해서는 발행한 토픽을 구독하는 컨슈머가 필요하다. 이는 당연하다. 그렇다면 모든 이벤트 발행 클래스에는 해당 기능 검증을 위해 해당 토픽을 구독하는 클래스가 필요할까? 나는 이는 아니라고 생각한다. 그래서 나는 테스트코드에서 컨슈머를 만들고 이를 검증하도록 만들어보았다.
하지만 이 테스트에서는 에러가 발생했다.
나는 토픽을 발행하는 클래스를 검증하기 위해 해당 토픽을 구독하는 클래스를 만들고 싶지 않았다. 그래서 계속해서 다양하게 시도를 해보았는데, 자꾸만 에러가 발생했다. 거의 다 된 것 같은데... 이곳에도 시간을 너무 많이 사용하여, 일단 검증을 위한 컨슈머를 만들어 검증을 진행하였다.
하지만 아무리 생각해도 너무 비효율적이다.. 앞으로 컨슈머 혹은 프로듀서를 만들면 무의미한 클래스를 계속 만들어야하는 것은 있을 수 없다... 저 에러만 해결하면 좋을텐데... 참 어렵다.
많이 의문인 것이, 나는 같은 설정값을 사용하도록 설정해놨는데, GPT가 말하는 부분이 문제의 원인이 맞는지가 의문이다. 내가 설정을 잘못한 것일까?
지금 현 상황은 이 상황에서 멈춰있다. 나는 오늘까지 해보고 안되면 검증을 위한 클래스를 작성하는 것으로 해결하려고하는데, 진짜 어덯게해서든 꼭 해결하고 싶다..
문제 해결: 설정 값을 선언함으로써 해결
새벽 2시반이 지난 지금.. 문제의 원인을 알 수 있었다. 글로 생각과 흐름을 정리하면서 설정을 잘못한 것인가? 했던 부분이 맞았다.
가장 마지막 사진을 확인해보면 DefaultKafkaConsumerFactory 를 만드는데 KafkaTestTuils 를 사용하고, 설정값을 지정 하고서, Consumer 를 만든다.
여기서 문제를 알 수 있었다. 첫번째로, 내가 설정한 설정값이 들어가지 않았다는 것(설정한다고 했던 코드는 필요가 없었다.) 두번째로, 시리얼라이저 문제가 맞았다는 것이다.
내가 사용하는 key-deserializer 와 value-deserializer 의 설정이 달라서 문제가 발생했던 것이다. 설정 값이 어디선가 안읽히는것인줄 알았는데 아니었다.. 내가 TestConfiguration 에 작성한 빈은 사용되지 않았던 것 같다.
눈도 안감고 놓친부분은 무엇일까 다시 확인하고, 생각하기를 반복하다, 설정값 어떻게 확인하지? 에서 힌트를 얻어 문제를 해결할 수 있었다. 계속해서 괴롭히던 고민과 문제가 해결된 것같아 너무 행복하다.. 이제 정말 빨리 자야겠다.. 내일은 개발은 잠시 미루고, 정말 못했던 공부를 하고서 정리를 해야겠다.
'회고 > TIL' 카테고리의 다른 글
예비군 훈련, TestContainer, 예측가능한 코드, 참조오류 (0) | 2023.08.21 |
---|---|
테스트 개선과 깨지기 쉬운 테스트?, 신규 이슈 등록 (0) | 2023.08.20 |
Application 계층 완료, Adapter 개발시작, 디자인패턴공부 (0) | 2023.08.17 |
출처 불분명스트레스, 테스트에 관하여, @Mock, @MockBean (0) | 2023.08.16 |
독서: 개발 프로세스에 관하여, 애플리케이션 계층 개발, 에러 (0) | 2023.08.14 |