본문으로 건너뛰기

© 2026 Molayo

Qiita헤드라인2026. 06. 26. 11:09

Junie CLI의 Debug mode로 테스트 조사 방식이 개선된 이야기

요약

JetBrains의 AI 코딩 에이전트인 Junie의 정식 출시와 함께, CLI의 Debug mode를 활용하여 간헐적으로 실패하는 Flaky 테스트를 조사하는 방법을 소개합니다. 디버거를 통해 실행 상태를 직접 확인하며 테스트 실패의 근본 원인을 파악하는 과정을 다룹니다.

핵심 포인트

  • Junie CLI의 Debug mode를 통해 Flaky 테스트의 원인 분석 가능
  • System.currentTimeMillis() 사용으로 인한 ID 충돌 사례 분석
  • AI 에이전트에게 디버깅 목표와 확인 사항을 전달하여 자동화된 조사 수행
  • 브레이크포인트 설정 및 스텝 실행 과정을 AI가 주도적으로 수행

Junie가 베타 버전을 종료하고 정식 버전이 되었습니다.

Junie는 JetBrains가 제공하는 AI 코딩 에이전트(AI Coding Agent)입니다. JetBrains IDE나 CLI에서 사용할 수 있습니다.

공식 발표 중에서 Junie의 일반 제공(GA) 시작과 함께 이루어진 변경 사항 중, Junie CLI의 Debug mode에 초점을 맞춥니다.

이 기사에서는 Junie CLI의 Debug mode를 사용해 보면서 「가끔 실패하는 테스트」의 조사가 어떻게 개선되었는지를 작성합니다.

이 리포지토리(Repository)에 있는 spring-demo-project입니다.

Spring Boot의 주문 처리 앱으로, OrderService, OrderRepository, OrderServiceTest 등이 있습니다. 주문을 생성하는 처리입니다.

public Order createOrder(Long userId, BigDecimal amount) {
long id = System.currentTimeMillis();
Order order = new Order(id, userId, amount);
...

주문 ID에 System.currentTimeMillis()를 사용하고 있습니다. 이는 현재 시각을 밀리초(ms) 단위로 반환하는 Java 메서드입니다.

저장처는 OrderRepository입니다.

@Repository
public class OrderRepository {
private final Map<Long, Order> store = new HashMap<>();
...

이 조합이라면, 짧은 시간 내에 두 개의 주문을 생성했을 때 동일한 밀리초가 되어 같은 ID가 생성될 가능성이 있습니다. Map은 동일한 키가 들어오면 나중에 들어온 값으로 덮어쓰기 때문에, 테스트가 가끔 실패하는 원인이 될 수 있습니다.

하지만 코드만 읽어서는 「정말로 동일한 밀리초가 되는지」 단정 지을 수 없습니다. 실행 중인 id 값이나 저장처의 상태를 보지 않으면 판단할 수 없습니다.

flaky한 테스트에서는,

  • 로그를 추가해도 동일한 상태가 재현된다는 보장이 없다
  • 재실행하면 통과해 버리는 경우가 있다
  • 조사용 로그를 나중에 삭제해야 한다
  • 어디에 로그를 추가해야 할지를 미리 스스로 결정해야 한다

flaky 테스트란,

동일한 코드에 대해 실행할 때마다 성공하거나 실패하는 등 결과가 안정적이지 않은 테스트를 말합니다. 코드의 버그뿐만 아니라 시각, 실행 순서, 병행 처리(Concurrency), 외부 서비스 등 「실행 시의 상황」에 좌우되어 발생하는 경우가 많습니다. 실패가 매번 재현되지 않기 때문에 원인 특정(Identification)이 어렵다는 것이 특징입니다. 이번 사례처럼 System.currentTimeMillis()로 ID를 채번하고 있으면, 우연히 같은 밀리초가 되었을 때만 충돌하여 실패하는 flaky한 동작이 됩니다.

저는 다음과 같이 대상과 「무엇을 확인해 주길 바라는지」를 전달했습니다.

OrderService#createOrder의 주문 ID가 System.currentTimeMillis() 때문에 충돌할 가능성이 있는지,
디버거(Debugger)로 밝혀내 주세요.
OrderServiceTest를 실행하여 createOrder의 id와 OrderRepository의 store 상태를 확인하고,
...

어디에 브레이크포인트(Breakpoint)를 설정할지, 어떻게 스텝 실행(Step execution)할지, 어떤 식을 어떻게 평가할지는 Junie에게 맡겼습니다.

  1. IntelliJ IDEA에서 spring-demo-project를 연다
  2. src/test/java/com/example/order/OrderServiceTest.java를 연다
  3. Junie CLI를 기동한다
  4. Junie CLI에서 Debug mode로 전환한다
/debug
  1. Junie에게 조사하고 싶은 내용을 전달한다
OrderService#createOrder의 주문 ID가 System.currentTimeMillis() 때문에 충돌할 가능성이 있는지,
디버거로 밝혀내 주세요.
OrderServiceTest를 실행하여 createOrder의 id와 OrderRepository의 store 상태를 확인하고,
...

이번에는 이 한 번의 의뢰만으로, Junie가 브레이크포인트 설정부터 디버그 실행, 값 확인까지 일련의 과정을 모두 수행해 주었습니다.

ezgif-855c798963288dbf.gif

Junie는 스스로 브레이크포인트 (breakpoint)를 설정하고, OrderServiceTest를 디버그 실행하여 다음 사항들을 실행 중인 값으로 보여주었습니다.

image.png

  • 1782278540214라는 주문 ID로 생성된 주문(Order@2287)을 저장하기 직전에, 동일한 ID를 가진 더미 주문(Order@2496)을 미리 저장하도록 함
  • 스텝 실행 (step execution)을 통해 store 내부를 확인했을 때, 사이즈는 1로 유지된 채 값이 Order@2496에서 Order@2287로 덮어씌워짐
  • 또한 중단된 프레임 (frame)에서 System.currentTimeMillis()를 100회 연속으로 평가했을 때, 반환값이 모두 동일한 값 (distinct count = 1)이었음

"동일한 밀리초(millisecond)에 동일한 ID가 생성되어, Map의 동일한 키가 덮어씌워진다"는, 코드만 읽어서는 단정할 수 없었던 사실을 실행 중인 값으로서 확인할 수 있었습니다.

특히 println으로는 수행하기 어려운 다음과 같은 조작들을, 실행이 멈춰 있는 상태 그대로 진행할 수 있었다는 점이 좋았습니다.

  • 현재 시각을 100회 연속으로 평가하여 충돌 가능성을 수치로 확인
  • 저장되기 직전에 동일한 ID의 주문을 삽입하여, 덮어쓰기가 발생하는 순간을 재현

Flaky 테스트에서는 동일한 실패 상태가 반드시 반복해서 재현된다는 보장이 없습니다.

그렇기에 실행이 멈춘 타이밍에 추가로 확인할 수 있다는 점이 유용했습니다.

예를 들어, Junie에게 다음과 같이 물어볼 수 있습니다.

현재 주문 ID와, 저장소에 동일한 ID의 주문이 있는지 확인해 주세요.
이 처리가 어떤 테스트에서 호출되었는지도 확인해 주세요.

로그를 추가하는 방식이라면 이러한 확인을 할 때마다 코드를 수정하고 다시 실행해야 합니다. Debug mode에서는 멈춰 있는 상태를 활용하여 그대로 다음 확인 단계로 넘어갈 수 있습니다.

Debug mode에서는 먼저 실행 중인 상태를 보고 원인을 확인합니다. 이번 사례라면 살펴봐야 할 포인트는 다음과 같습니다.

  • id에 어떤 값이 들어있는가 - 동일한 ID가 저장소에 존재하는가
  • 어떤 테스트에서 createOrder가 호출되었는가 - 저장 시 덮어쓰기가 발생할 가능성이 있는가

원인이 파악된 후에는 일반 모드로 돌아가 수정을 요청합니다.

Junie CLI Debug mode를 통해 특히 개선된 점은 다음과 같습니다.

  • 로그를 늘리기 전에 실행 중인 값을 확인할 수 있음
    println을 추가하고 재현되기를 기다리기 전에, 멈춰 있는 상태의 변수나 저장소를 확인할 수 있습니다.
  • 세세한 디버그 조작을 직접 결정할 필요가 없음
    평가할 식이나 확인할 값을 처음부터 모두 결정하지 않아도, Junie가 목적에 따라 조사 과정을 구성해 줍니다.
  • 조사와 수정을 분리하기 쉬움
    먼저 Debug mode로 원인을 확인하고, 원인이 파악되면 일반 모드에서 수정으로 넘어갈 수 있습니다.

spring-demo-projectOrderService를 소재로, Junie CLI Debug mode를 통해 Flaky 테스트 조사 흐름이 어떻게 변했는지 작성해 보았습니다.

대상과 확인하고 싶은 값을 전달하는 것만으로, Junie가 중단 지점과 식을 스스로 구성하여 실행 중인 상태를 보며 조사를 진행해 줍니다.

Debug mode에서 "먼저 실행 중인 값을 확인하게 한다"는 방식은 상당히 실용적이라고 느꼈습니다.

저희는 JetBrains 제품에 관한 질문이나 상담 등을 받고 있습니다. 저희 X(구 Twitter) 또는 이메일로 연락해 주세요.

AI 자동 생성 콘텐츠

본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0