본문 바로가기

블로그 / 기술

QA 담당이 없을 때: 혼자 돌리는 시험, E2E, 그리고 믿으면 안 되는 초록불

QA 팀 없이 게임 네 개를 검증한 방법을 정리했다. 봇 시뮬레이션, 실제 서버에 붙는 E2E, 모바일 브라우저 자동 플레이, 그리고 필터를 건 '전부 통과'가 23건의 실패를 숨긴 사고까지 적었다.

Salmonholic ·· 5분 읽기

PallMark 탑 1층 주방 아레나에서 캐릭터가 전투하는 캡처 화면

혼자 게임을 만들면 QA 담당도 나다. 그런데 게임 네 개를 매일 손으로 끝까지 해 볼 수는 없다. 그래서 “사람 대신 뭔가가 끝까지 해 보게” 만드는 데 시간을 많이 썼다. 이 글은 게임별로 무엇을 자동으로 돌렸는지, 그리고 그 자동화가 어디서 나를 속였는지에 대한 기록이다.

네 게임의 검증 층

층 AvoidNow 랜선포차 PallMark Salmonholic
규칙 단위 시험 판정 시험 (Godot, TS 양쪽 같은 값) vitest, 미니게임마다 시험 시뮬 시험 5천여 건 골든 비교
자동 시뮬레이션 봇 20판 서버 시뮬레이션 200판 자동 플레이 녹화 100시드 스윕
실제 서버 E2E Node와 DO 서버 둘 다 재접속·드레인 점검 해당 없음 재접속 점검
브라우저 E2E 헤드리스 Chrome 클릭 Playwright 모바일 해당 없음 3개 브라우저 매트릭스
화면 확인 녹화 프레임 게임별 스크린샷 모음 32컷 캡처 첫 60초 캡처

Salmonholic의 골든, 스윕, 소크 테스트는 다른 글에 자세히 있어서 여기서는 나머지 셋을 중심으로 적는다.

단위 시험이 못 보는 곳: 전송 계층

AvoidNow에서 9월 26일 밤에 버그 두 개가 CI를 통과해 버렸다.

하나는 화면 코드의 문법 오류였다. 규칙 시험(sim_test)은 게임 규칙만 불러오고 화면·UI 코드는 불러오지 않는다. 그러니 UI 파일이 깨져도 시험은 초록이었다.

다른 하나는 더 아팠다. 해외용 DO 서버가 플레이어 입력을 전부 무시했다. DO 런타임은 바이너리 웹소켓 프레임을 Blob으로 넘겨주는데, 입력 해석 코드는 바이트 배열만 기대했다. 그래서 서버에서 캐릭터가 한 발짝도 안 움직였다(커밋 7860504). 단위 시험은 방 로직만 봤고, Node와 DO 어댑터는 시험 대상이 아니었다.

다음 날 0시 33분 커밋 73c05a1에서 두 가지를 CI에 넣었다.

  • 모든 .gd 파일을 실제로 컴파일해 보는 check_scripts.gd
  • 떠 있는 서버에 바이너리 입력을 보내 응답(ack)이 오르고 캐릭터가 움직이는지 보는 live.ts. CI가 Node 서버와 wrangler dev로 띄운 DO 서버 양쪽에 대해 돌린다.

커밋 메시지 마지막 줄은 “둘 다 예전의 고장 난 코드에서는 실패하는 것을 확인했다”다. 새 검사를 넣을 때 고장 난 코드에서 빨간불이 뜨는지 먼저 본다. 안 뜨면 그 검사는 아무것도 지키지 않는다.

개발 서버에서 수백 판 돌리기

랜선포차는 미니게임이 24종이다. 최대 여섯 명이 한 방에서 하는 게임이라 손으로 시험하기가 제일 어렵다. 그래서 개발용 서버에서 판을 처음부터 끝까지 자동으로 돌리는 시뮬레이션 명령(sim 200)을 만들었다. 한 판 길이, 라운드 수, 탈락자 분포가 나온다. 9월 27일 새벽 기록은 “24종 모두 100% 종료, 한 판 7.5분”이다. “끝나지 않는 판”이 하나도 없다는 게 제일 중요한 숫자다.

화면은 Playwright로 따로 본다. e2e.mjs는 휴대폰 화면 크기로 홈 → 빠른 매칭 → 한 판 → 결과까지 따라가며 스크린샷과 콘솔 오류를 모은다. e2e-games.mjs는 게임마다 그 게임만 나오는 방 서버를 띄워 두 라운드씩 찍는다. 부하가 높을 때 서버 기동이 느려서 기다리는 시간을 15초에서 60초로 늘린 커밋(f3555ea)도 있다. 시험 도구도 고쳐 가며 쓴다.

Salmonholic 첫 60초를 모바일과 웹킷에서 캡처한 세 장, 튜토리얼과 레벨업 카드 화면 Salmonholic 0.16.2의 첫 60초 점검 캡처. 왼쪽부터 수정 전 모바일, 수정 후 모바일, 수정 후 웹킷 화면이다

믿으면 안 되는 초록불

가장 크게 배운 건 PallMark에서다. PallMark의 게이트는 컴파일 → 시뮬 → 씬 생성 → 에디터 시험 → 플레이 시험 → 화면 캡처 순서로 돈다. 저장소 문서에는 “앞이 빨간불이면 뒤는 볼 값어치가 없다”고 적어 두었다.

9월 21일에 그 약속이 깨져 있었다는 걸 알았다. 여러 작업을 병합할 때마다 “시험 N/N 통과”라는 보고를 받았는데, 그건 --filter로 고른 일부만 돌린 결과였다. 필터를 떼니 5,262건 중 23건이 실패하고 있었다. 날짜를 거슬러 이분 탐색해 보니 실패는 9월 19일 밤 8건에서 21일 밤 22건까지 며칠에 걸쳐 쌓였다.

그 뒤로 규칙을 바꿨다.

  1. “게이트 초록”은 필터 없는 전체 시험으로만 주장한다.
  2. 이미 알고 있는 실패는 목록 파일로 관리한다. 목록 밖의 실패도 빨간불, 목록에 있는데 통과해도 빨간불이다. 톱니처럼 한 방향으로만 갈 수 있게 해서, 필터로 만든 초록이 통과하지 못하게 했다.
  3. 시험이 읽는 자료는 반드시 커밋한다. 보고서 폴더에 있던 기준값 파일이 커밋에서 빠져 다른 기계에서만 깨진 일이 있었다.

Salmonholic 온라인 경기에서 고양이 캐릭터가 원을 그리며 움직이는 캡처 Salmonholic 캐릭터 떨림을 고친 뒤 온라인 경기에서 원 운동을 녹화한 점검 화면. 숫자 대신 화면으로 확인했다

결국 눈으로 본다

자동 검사를 아무리 쌓아도 마지막은 화면이다. PallMark 문서의 검증 원칙은 이렇다. 새 검사는 되돌리면 빨간불이 떠야 하고, 화면은 캡처나 영상으로 눈으로 보고, “고쳤다”는 실제 실행 결과로만 말한다. PallMark에서 “계단이 연결됐다”는 보고를 받고도 실제 빌드에서는 2층에 못 올라간 적이 있다. 도달과 상승은 다른 일이었다.

커밋 전에 거는 검사는 PallMark 커밋 훅 글에, 검증에 쓰는 도구 목록은 공용 도구 글에 정리했다. 이렇게 검증한 게임은 AvoidNow, 랜선포차, PallMark 페이지에서 볼 수 있다.

#QA#E2E 테스트#자동화#CI#1인 개발

함께 읽으면 좋은 글

전체 글 →