'재현이 안 됩니다'로 닫히는 Unity 버그 티켓, 무엇이 빠졌을까

재현이 실패하는 세 가지 원인과, 버그 티켓에 무엇이 남아야 하는지. 수동 기록이 구조적으로 늦을 수밖에 없는 이유까지 다룹니다.

  • qa
  • unity
  • bug-report

Unity 버그 리포트 3부작 — ① 재현이 실패하는 이유 · ② 항상 기록하는 접근 · ③ Unity 최소 구현 (②·③ 순차 공개 예정)

QA가 버그를 발견합니다. 티켓을 씁니다. 개발자가 받습니다. 같은 절차를 밟아 봅니다. 아무 일도 일어나지 않습니다. 며칠 뒤 티켓은 "재현 불가"로 닫힙니다.

그리고 몇 주 후, 같은 버그가 라이브에서 터집니다.

저희가 Unity 버그 리포팅 도구를 만들게 된 출발점이 이 장면이었습니다. 문제는 QA가 거짓말을 한 것도, 개발자가 게으른 것도 아니었습니다. 버그가 발생한 순간의 상태가 어디에도 남지 않았을 뿐입니다.

재현이 실패하는 세 가지 지점

"재현 불가"는 하나의 현상이지만 원인은 대체로 셋 중 하나입니다.

1. 조건이 유실된다

티켓에는 이렇게 적힙니다.

인벤토리에서 아이템을 옮기다가 UI가 깨졌습니다.

개발자가 인벤토리를 열고 아이템을 옮깁니다. 멀쩡합니다. 실제로 필요했던 조건은 이런 것들이었습니다.

  • 인벤토리가 가득 찬 상태였다
  • 그 직전에 퀘스트 보상을 받아 아이템이 자동 추가됐다
  • 옮기려던 슬롯이 장착 중인 아이템이었다

QA는 이 셋을 조건이라고 인식하지 못했습니다. 그냥 게임을 하던 흐름이었으니까요. 재현 절차를 글로 옮기는 순간, 당사자에게 자명했던 맥락이 빠집니다.

2. 타이밍이 재현되지 않는다

프레임 단위 경합, 네트워크 응답 순서, 코루틴 완료 시점처럼 시간에 의존하는 버그는 절차를 그대로 따라 해도 재현되지 않습니다. 개발자 PC가 더 빠르면 문제의 창이 열리지 않습니다.

이런 버그는 절차가 아니라 그 순간의 타임라인이 있어야 진단됩니다. 어떤 로그가 어떤 순서로 찍혔는지, 프레임이 어디서 튀었는지.

3. 환경이 다르다

같은 빌드라도 그래픽 API, 해상도, 품질 설정, OS 버전, 심지어 창 모드 여부에 따라 갈립니다. 티켓에 환경 정보를 적는 칸이 있어도 대개 비어 있거나 "Windows"라고만 적혀 있습니다.

여기에 두 가지가 더 붙습니다. QA가 본 빌드와 개발자가 재현하는 빌드가 다른 경우, 그리고 서버 상태나 라이브옵스 이벤트에 의존하는 경우입니다. 둘 다 클라이언트 설정만 적어서는 드러나지 않습니다. 빌드 번호와 접속 서버·이벤트 활성 여부까지 함께 남겨야 잡힙니다.

그래서 무엇을 남겨야 하는가

재현 가능한 티켓과 그렇지 않은 티켓의 차이는 성실함이 아니라 남은 정보의 종류입니다.

정보없을 때있을 때
발생 직전 영상절차를 말로 복원무엇을 했는지 그대로 확인
발생 시점 로그사후에 재현해서 다시 수집예외·경고가 시간순으로 정렬
게임 상태"인벤토리에서요"씬·소지품·퀘스트 진행도
성능 지표체감으로 "끊겼어요"FPS·메모리 그래프의 실제 스파이크
환경"Windows"해상도·그래픽 API·품질 설정·빌드 번호

이 표에서 중요한 건 항목 목록이 아니라 가운데 열이 전부 "나중에 복원"이라는 점입니다. 복원은 실패하기 쉽고, 실패하면 티켓이 닫힙니다.

앞의 세 원인과 겹쳐 보면 대응 관계가 분명해집니다. 유실된 조건은 게임 상태가, 재현되지 않는 타이밍은 로그와 성능 지표가, 환경 차이는 빌드·설정 정보가 메웁니다. 어느 것도 사후에 기억으로 복원되지 않는 종류입니다.

수동 기록이 실패하는 구조적 이유

"그럼 QA가 이걸 다 적으면 되지 않나"로 결론이 나면 대개 정착하지 않습니다. 이유가 있습니다.

버그를 인지한 시점은 이미 버그가 발생한 다음입니다. 녹화 버튼은 항상 늦게 눌립니다.

[t-30s] 퀘스트 보상 수령        ← 진짜 원인
[t-12s] 인벤토리 진입
[t-3s]  아이템 드래그
[t=0]   UI 깨짐                 ← 여기서 "어? 버그다" 인지
[t+8s]  녹화 시작                ← 원인 구간은 이미 지나감

30초 전 상태가 필요한데, 사람은 그때 녹화 중이 아닙니다. 게다가 인지 이후에 남기는 정보는 이미 기억을 거칩니다. 앞에서 본 "인벤토리가 가득 차 있었다"는 조건은 기록되지 않은 게 아니라 기억에서 조건으로 분류되지 않은 것에 가깝습니다.

이걸 규율로 해결하려면 모든 플레이 세션을 항상 녹화해야 합니다. 그건 규율이 아니라 도구가 할 일입니다.


재현 불가로 닫힌 티켓이 쌓이고 있다면, 그건 QA 프로세스가 허술해서가 아닐 수도 있습니다. 그 순간의 증거를 남길 수단이 애초에 없었던 것에 가깝습니다.

그렇다면 "항상 녹화"를 성능과 용량을 감당하면서 어떻게 실제로 돌릴 수 있을까요. 다음 글에서 롤링 버퍼 접근을 다룹니다.