LLM 기반 Spring Boot + Kotest API 테스트 자동화와 리팩토링 실전 가이드

JH.KIM·2025년 7월 4일

📌 들어가며

소프트웨어 개발 과정에서 흔히 발생하는 문제는 '코드 작성 → 테스트 → 버그 수정 → 재테스트'의 무한 반복입니다. 이런 반복 작업을 사람이 직접 수행하기에는 비효율적이며 오류 발생 가능성도 높습니다. 하지만 최근 주목받고 있는 LLM(Large Language Model)을 활용하면 반복되는 테스트 작업을 더 효율적으로 수행할 수 있습니다.

이 글에서는 Kotlin/Spring Boot 환경에서 Kotest를 이용한 API E2E 테스트 자동화 과정에 LLM을 어떻게 효과적으로 적용할 수 있는지 실전 예시를 통해 안내합니다.


1️⃣ 문제 정의 및 샌드박스 구성

🎯 목표 API

  • 엔드포인트: POST /members
  • 역할: 회원가입 기능
  • 검증 대상 필드: email, password, age
POST /members
Content-Type: application/json

{
  "email": "user@example.com",
  "password": "Secure123!",
  "age": 30
}

✅ 기대 응답

HTTP 201 Created
{
  "id": 1,
  "email": "user@example.com"
}

2️⃣ 테스트 케이스 생성 자동화

GPT와 같은 LLM 도구를 활용하면 테스트 케이스를 신속하고 정확하게 생성할 수 있습니다.

예시 프롬프트:

회원가입 API를 위한 email, password, age에 대해 성공 및 실패 케이스를 포함하여 테스트 케이스 10개를 생성해줘. 각 케이스별 기대 응답도 함께 제시해줘.

📝 예시 결과

구분입력값기대 응답
정상email=valid@domain.com, pw=Password123, age=25201 Created
실패email=null400 Bad Request: "email 필수 입력"
실패age=-5400 Bad Request: "age는 0 이상"
실패pw=short400 Bad Request: "password는 최소 8자 이상"

3️⃣ Kotest 기반의 E2E 테스트 코드 작성

생성된 테스트 케이스를 Kotest를 사용하여 다음과 같이 코드화합니다.

class MemberApiE2ETest : DescribeSpec({

    describe("POST /members") {

        it("정상적인 회원가입") {
            val response = client.post("/members") {
                contentType(ContentType.Application.Json)
                setBody("""
                    {
                        "email": "user@example.com",
                        "password": "Secure123!",
                        "age": 30
                    }
                """.trimIndent())
            }
            response.status shouldBe HttpStatusCode.Created
        }

        it("비밀번호가 짧으면 실패") {
            val response = client.post("/members") {
                contentType(ContentType.Application.Json)
                setBody("""
                    {
                        "email": "user@example.com",
                        "password": "short",
                        "age": 30
                    }
                """.trimIndent())
            }
            response.status shouldBe HttpStatusCode.BadRequest
        }

        // 추가 케이스는 반복 작성
    }
})

4️⃣ 실패 케이스를 통한 버그 수정 및 리팩토링

🔥 최초 테스트 결과 예시

  • 비밀번호 길이 검사 미적용
  • 나이 음수 입력에도 성공 처리되는 오류

🛠️ 서비스 코드 리팩토링 예시

fun registerMember(request: MemberRequest): Member {
    require(request.age >= 0) { "age는 음수일 수 없습니다." }
    require(request.password.length >= 8) { "password는 최소 8자 이상입니다." }

    return repository.save(request.toEntity())
}

✅ 재실행 테스트 결과

  • 모든 테스트 케이스 통과 🎉

5️⃣ LLM을 이용한 브루트포스 테스트 자동화 확장

테스트 케이스를 수십, 수백 개로 늘려 GPT가 자동 생성한 테스트 케이스를 바탕으로 반복적인 테스트를 수행할 수 있습니다. 이는 사실상 브루트포스 방식으로 자동화된 문제 해결 접근법입니다.


🔄 LLM 사고방식 적용 과정 정리

단계설명
문제 식별API 유효성 검사 범위 설정
샌드박스 구축독립적인 테스트 환경 구축
도구 활용Kotlin, Spring Boot, Kotest, GPT
성공 기준 설정모든 테스트 케이스가 통과할 때까지 반복
자동화 반복 실행브루트포스 방식의 테스트 반복

✍️ 마무리하며

이러한 방식은 인간이 직접 시행착오를 반복하는 대신, LLM을 통해 자동화된 브루트포스 접근을 활용하여 훨씬 효율적이고 신속한 문제 해결을 가능하게 합니다. 특히 반복적인 테스트 환경에서는 매우 유용하게 적용될 수 있습니다.

앞으로는 LLM을 활용하여 테스트 코드 및 문서화를 자동화하고 디버깅까지 지원하는 단계로 더욱 발전할 수 있을 것입니다.


🚀 발전을 위한 다음 단계

  • 코딩 에이전트 Cursor를 활용한 테스트 케이스 및 Kotest 코드 자동 생성 고도화
  • 성공 케이스를 바탕으로 문서 자동화 도입 (예: Spring RestDocs)
profile
일하며 겪은 문제를 나눠요

0개의 댓글