sgkstudio.
엔지니어링

E2E 테스트 없이 배포한 영문 서비스, 실제 신청은 0건이었다

테스트가 전부 통과하고 배포도 문제없이 끝난 영문 서비스에서, 실제로 규칙 하나를 끝까지 제출해 보는 E2E 테스트를 하니 처리된 신청이 0건이었습니다. 자동화된 테스트는 진짜 서비스 대신 가짜 답변과 가짜 통신을 쓰고 있었고, 실제로 막혀 있던 층은 세 개였습니다.

2026-09-29실제 서비스 화면에서 영어 매매 규칙을 3건 왕복 제출한 검증 기록 — 코드 변환부터 결과 처리까지 단계별로 확인, AAPL 매매 기록 92건(수익률 14.87%·최대낙폭 -8.65%)과 TSLA 매매 기록 154건(수익률 13.84%·최대낙폭 -5.9%)까지 처리됨을 확인시세 조회 실측 기록 — 조회 구간의 끝을 오늘로 잡으면 오류, 하루 전으로 잡으면 AAPL 시세 2,669개가 정상 조회됨을 확인환경변수 파일 겹쳐쓰기 발견 기록 — 배포 도구가 필요한 값을 담은 파일을 덮어써 한국어 신청 1건이 27일째 처리되지 않은 채 남아 있던 것을 확인, 이후 필요한 값 5개만 별도 경로로 재조립재발 방지 확인 항목 신설 기록 — 언어별 지시문 변환 확인 8건·시세 조회 클램프 확인 5건·영어 매매 방향 판정 확인 7건·안전장치 문구 확인 2건 추가, 전체 자동화된 테스트 447건·별도 테스트 도구 확인 89건 통과

왜 통과한 테스트가 실제 신청을 하나도 처리하지 못했나?

SGK 스튜디오가 운영하는 백테스트 서비스 트레이드스튜디오는 매매 규칙을 문장으로 입력하면 그 규칙을 과거 시세에 대입해 수익률을 계산해 주는 서비스다. 원래 한국어 사용자만 대상으로 만들어졌는데, 해외 투자자에게도 열기 위해 영어 화면과 영어 매매 규칙 변환 기능을 새로 만들어 배포했다.

배포 자체는 5분 만에 끝났고, 자동화된 테스트도 전부 통과했다. 하지만 배포를 마친 것과 서비스가 실제로 쓸 수 있는 상태인 것은 다른 문제였다. 배포 직후 영어로 쓴 매매 규칙 하나를 화면부터 결과 처리까지 실제로 끝까지 제출해 보는 E2E 테스트를 진행했는데, 처리된 신청이 하나도 없었다.

원인은 자동화된 테스트가 실제 서비스 대신 가짜로 만든 답변과 가짜 통신을 쓰고 있었다는 데 있었다. 그 테스트가 증명한 건 '규칙대로 코드를 짰다'는 사실뿐이었고, '실제로 작동한다'는 사실은 증명하지 못하고 있었다.

가짜 답변을 쓰는 테스트가 나쁜 방식은 아니다. 실제 모델을 매번 호출하면 시간도 오래 걸리고 비용도 든다. 문제는 가짜 답변이 '모델이 이렇게 답할 것'이라는 가정을 담고 있고, 그 가정 자체가 틀리면 테스트는 통과하는데 실제 서비스는 멈춘다는 데 있다. 이 사례에서 그 가정은 '모델이 지시받은 대로 여섯 자리 종목 코드를 만든다'는 것이었는데, 영어로 쓴 규칙에서는 그 가정이 애초에 성립하지 않았다.

처음에는 무엇을 의심했나?

신청이 전부 실패하는 걸 확인하고 가장 먼저 떠올린 의심은 두 가지였다. 하나는 매매 규칙을 코드로 바꾸는 과정에서 정상적인 규칙까지 걸러내는 안전장치가 오작동하고 있다는 의심이었다. 이 안전장치는 모델이 만들어 낸 매매 규칙이 정해진 형식을 지키는지 검사해서, 형식이 틀리면 그 규칙을 통째로 거부하도록 만들어져 있었다.

다른 하나는 이미 해결된 문제일 거라는 가정이었다. 이 서비스는 얼마 전 미국 종목까지 다룰 수 있도록 검증 범위를 넓힌 적이 있었다. 그때 미국 종목 코드를 받아들이도록 검증 로직을 고쳤으니, 영어 규칙이 거부되는 문제도 그 작업에서 함께 해결됐을 거라고 짐작했다.

확인에 쓴 수단 — 실제 화면에서 끝까지 제출해 보기

짐작만으로는 판정할 수 없어서, 실제 서비스 화면에 접속해 영어 매매 규칙을 하나씩 제출하며 처리 기록을 그대로 들여다봤다. 규칙을 코드로 바꾸는 단계, 그 규칙을 과거 시세에 대입해 계산하는 단계, 계산 결과를 사용자에게 보내는 단계까지 세 단계를 전부 눈으로 확인하는 방식이었다.

이 방식으로 확인하니 문제가 한 곳이 아니라 여러 단계에 걸쳐 있다는 게 드러났다. 첫 번째 단계인 코드 변환 과정부터 이미 막혀 있었고, 그 단계를 넘기더라도 다음 단계에서 또 막히는 경우가 있었다. 처리 기록을 단계별로 나눠 보지 않았다면 '어딘가 안 된다'는 것만 알았을 뿐, 어느 단계가 문제인지는 알아내지 못했을 것이다.

이 방식을 쓴 이유는 하나다. 화면에 뜨는 오류 문구만 보면 '거부됐다'는 결과만 보이고, 어느 층에서 왜 거부했는지는 안 보인다. 코드 변환·시세 조회·결과 계산, 세 단계마다 남는 처리 기록을 각각 따로 열어야 어느 층이 무죄이고 어느 층이 범인인지 갈릴 수 있었다.

알리바이 — 의심했던 두 곳은 둘 다 무죄였다

안전장치의 처리 기록을 열어 보니, 안전장치는 만들어 둔 그대로 움직이고 있었다. 종목 코드가 정해진 형식(여섯 자리 숫자)을 지키지 않으면 규칙을 거부하도록 짜여 있었는데, 실제로 정확히 그 규칙대로 거부하고 있었다. 안전장치는 무죄였다.

검증 범위를 넓힌 작업도 다시 확인해 보니 무죄였다. 그 작업이 고친 건 '규칙이 형식에 맞는지' 확인하는 검사 로직이었지, 규칙을 만들어 내는 지시문 자체는 아니었다. 지시문은 여전히 한국어로만 쓰여 있었고, 검증 범위를 넓힌 작업과는 서로 다른 자리였다. 두 용의자 모두 알리바이가 있었다.

진짜 원인 — 세 개 층이 동시에 막혀 있었다

실제로 막힌 곳은 안전장치도, 검증 로직도 아니었다. 매매 규칙을 코드로 바꾸는 과정 전체와 그 이후 계산 과정에 걸쳐 세 개 층이 동시에 막혀 있었다.

첫 번째 층 — 한국어 지시문이 미국 종목에도 6자리 코드를 요구했다

매매 규칙을 코드로 바꾸는 모델에게 내리는 지시문은 원래 한국어 하나뿐이었다. 이 지시문은 '종목은 반드시 6자리 코드로 쓴다'는 규칙을 강제하고 있었는데, 이는 국내 종목 표기 방식에 맞춘 규칙이었다.

영어로 쓴 매매 규칙에도 이 지시문이 그대로 쓰이자, 모델은 미국 종목 이름(예: AAPL)에도 6자리 숫자 코드를 억지로 만들어 붙였다. 안전장치는 이렇게 만들어진 가짜 코드를 형식 위반으로 정확히 걸러냈고, 그 결과 멀쩡한 영어 규칙이 전부 거부됐다.

이 층이 특히 찾기 어려웠던 이유는, 겉으로 보이는 오류 문구가 '규칙이 틀렸다'는 말뿐이었기 때문이다. 규칙을 쓴 사람 입장에서는 종목 이름을 정확히 적었는데도 거부당한 셈이라, 문제가 자기 쪽 문장에 있다고 오해하기 쉬운 구조였다. 지시문이 언어와 무관하게 하나로 공유되고 있다는 사실을 몰랐다면, 이 오해는 계속 반복됐을 것이다.

두 번째 층 — 오늘 날짜가 들어가면 시세 조회가 통째로 거부됐다

규칙을 코드로 바꾸는 단계를 통과해도 다음 단계인 시세 조회에서 다시 막혔다. 백테스트에 쓰는 시세 제공사 구독 플랜은 조회 구간에 오늘 날짜가 들어가면 일부만 잘라 주는 게 아니라 요청 전체를 거부하도록 돼 있었다.

실제로 조회 구간의 끝을 오늘로 잡으면 오류가 났고, 하루 전으로 잡으면 AAPL 시세 2,669개가 정상적으로 돌아왔다. 그런데 백테스트를 처리하는 쪽은 조회 구간의 끝을 항상 오늘 날짜로 넘기고 있었고, 그래서 매번 실패하고 있었다.

이 층이 한국어 서비스에서는 드러나지 않은 이유도 확인했다. 한국어 서비스는 오래전부터 같은 시세 제공사를 썼는데, 그동안 조회 구간의 끝을 지금 시점보다 앞선 날짜로 지정하는 습관이 이미 자리 잡혀 있었다. 영어 서비스를 새로 만들면서 그 습관이 그대로 옮겨지지 않았고, 옮겨지지 않았다는 사실도 실제로 오늘 날짜를 넣어 조회해 보기 전까지는 눈에 보이지 않았다.

세 번째 층 — 원화 기준 자본금이 달러 계좌에도 남아 있었다

앞의 두 층을 고친 뒤에도 숫자 하나가 남아 있었다. 영어 규칙은 원화를 기준으로 잡아 둔 자본금 설정값을 그대로 물려받고 있었는데, 이 값을 달러 계좌 기준 포지션에 대입하면 수익률이 0.01%로 찍혔다. 계산 자체는 틀리지 않았지만, 기준이 되는 화폐 단위가 서로 달라서 나온 숫자가 사실상 의미 없는 값이었다.

이 문제는 앞의 두 층을 고치고 나서야 눈에 띄었다. 코드 변환과 시세 조회를 다 고친 뒤 첫 영어 결과 메일에 '이 서비스는 안 된다'는 인상을 주는 숫자가 그대로 나갈 뻔한 셈이다. 영어 규칙 기준 자본금을 10,000달러로 따로 잡아 이 문제를 없앴다.

세 개 층의 증상·원인·조치를 정리한 표 — 규칙 번역 층은 정상 영어 규칙이 전부 거부됨(원인: 한국어 지시문이 미국 종목에도 6자리 코드를 요구, 조치: 지시문을 언어별로 분리), 시세 조회 층은 오늘 날짜가 들어가면 요청 전체 거부(원인: 조회 구간의 끝을 매번 오늘로 넘김, 조치: 끝을 하루 전으로 클램프), 기준 통화 층은 수익률이 0.01%로 찍힘(원인: 원화 기준 자본금이 달러 계좌에도 적용, 조치: 영어 기준 자본금을 10,000달러로 분리)
세 층 모두 같은 검증 한 번에서 함께 드러났다

덤으로 드러난 무음 결함 — 같은 검증에서 두 가지가 더 나왔다

같은 검증을 진행하는 동안 세 개 층과 별개인 문제 두 가지가 추가로 드러났다. 배포 도구와 안전장치는 애초에 이 검증의 대상이 아니었는데도, 실제 화면에서 끝까지 밀어 보는 과정 중에 우연히 함께 걸려 나왔다.

  • 환경변수 겹쳐쓰기 — 배포 도구가 실행할 때마다 필요한 값을 담은 파일 하나를 통째로 덮어써, 알림 발송에 쓰는 값 하나만 남기고 나머지가 사라져 있었다. 이 상태에서는 영어 서비스뿐 아니라 원래 있던 한국어 서비스까지 함께 멈춘다는 뜻이었고, 실제로 한국어 신청 1건이 27일째 처리되지 않은 채 남아 있었다.
  • 안전장치의 언어 편중 — 매매 방향(상승·하락)이 뒤집히지 않았는지 확인하는 안전장치가 한국어 방향 단어만 보고 있어서, 영어 규칙에서는 이 확인이 통째로 빠져 있었다.

겹쳐쓰기 문제는 필요한 값 5개만 별도 경로로 다시 모으도록 고쳐 해결했고, 언어 편중 문제는 방향 단어를 영어 패턴으로 추가해 해결했다.

덤으로 드러난 무음 결함 세 값 스탯 카드 — 처리되지 않은 채 남아있던 한국어 신청 27일(환경변수 파일이 겹쳐 쓰인 채로), 방치된 신청 건수 1건(발견 전까지), 다시 모은 값 5개(필요한 값만 별도 경로로 분리)
영어 서비스를 배포하는 도구가 한국어 서비스까지 함께 멈춰 있었다

고친 방법 — 네 가지를 고치고 다시 왕복으로 확인했다

세 개 층과 덤으로 나온 두 문제를 합쳐 네 가지를 순서대로 고쳤다.

  • 지시문을 언어별로 분리했다 — 한국어 규칙에는 6자리 코드 규칙을, 영어 규칙에는 미국 종목 표기 규칙을 따로 적용하도록 나눴다.
  • 시세 조회 구간의 끝을 하루 전으로 당겨 잡도록 고쳤다.
  • 영어 규칙 기준 자본금을 10,000달러로 따로 설정했다.
  • 필요한 값 5개만 별도 경로로 다시 모으도록 배포 절차를 바꿨다.

네 가지를 고친 뒤 다시 실제 서비스 화면에서 왕복으로 확인했다. 미국 종목 두 개를 대상으로 영어 규칙을 3건 제출해 코드 변환부터 계산, 결과 처리까지 전부 지켜봤다. AAPL 규칙은 매매 기록 92건에 수익률 14.87%, 최대낙폭 -8.65%로 계산됐고, TSLA 규칙은 매매 기록 154건에 수익률 13.84%, 최대낙폭 -5.9%로 계산됐다. 실제 신청 화면에 제출한 값이 결과 저장소에 그대로 기록된 것까지 확인한 뒤 확인용으로 넣었던 값을 지웠다.

수정 후 다시 왕복으로 확인한 결과 스탯 카드 — 영어 규칙 왕복 제출 3건(코드 변환부터 결과 처리까지), AAPL 매매 기록 92건·수익률 14.87%(최대낙폭 -8.65%), TSLA 매매 기록 154건·수익률 13.84%(최대낙폭 -5.9%)
네 가지를 고친 뒤 실제 서비스 화면에서 다시 확인한 값

같은 실수를 어떻게 막았나?

이번에 드러난 문제는 전부 '코드가 문서를 읽은 대로 짜여 있는가'를 재는 자동화된 테스트로는 잡을 수 없는 종류였다. 그래서 같은 실수를 막는 장치도 실제 처리 경로를 재현하는 방식으로 새로 추가했다.

새로 추가한 확인 항목과 확인 건수를 정리한 표 — 언어별 지시문 변환 확인 8건, 시세 조회 구간 클램프 확인 5건, 영어 매매 방향 판정 확인 7건, 안전장치 문구 확인 2건, 전체 자동화된 테스트 447건, 별도 테스트 도구 확인 89건
네 가지 수정 각각에 실제 처리 경로를 재현하는 확인을 추가했다

이 확인들을 더해 전체 자동화된 테스트는 447건, 별도 테스트 도구로 돌리는 확인은 89건이 전부 통과하는 상태로 만들었다. 이번 사례가 남긴 교훈은 하나다 — 자동화된 테스트가 전부 통과하고 배포도 문제없이 끝났다는 사실은, 실제로 끝까지 제출해 보는 E2E 테스트를 대신하지 못한다. 이 검증을 실제 이용자에게 서비스를 알리기 전에 마쳤기 때문에, 영어권 이용자 문의를 한 건도 놓치지 않을 수 있었다.

규칙을 하나씩 늘려 가며 지금도 확인하는 이유는 같다. 코드 변환·시세 조회·계산이 각각 따로는 옳아도, 세 개를 이어 붙이는 자리에서 서로 다른 가정을 하고 있으면 결과는 틀어진다. 이 서비스는 규모가 크지 않은 팀이 만들어서, 배포 뒤 실제 화면에서 끝까지 밀어 보는 확인을 건너뛸 여유가 없다는 사실을 이번 사례로 다시 확인했다.

비슷하게 백테스트 결과 자체가 왜곡되는 문제를 다룬 사례는 5분봉 백테스트가 −69%로 무너진 이유에 따로 정리했다. 배포 전 검증 절차를 점검하고 싶다면 상담에서 현재 구조를 확인할 수 있다.

같은 방식으로 우리 업무를 재보고 싶다면

이 글에 쓴 계측·판정·자동화는 저희가 실제로 매일 돌리는 방식 그대로입니다. 어떤 작업을 자동화할 수 있고 어디를 사람이 잡아야 하는지, 현재 업무 흐름을 놓고 같이 짚어 드립니다.

새 글이 올라오면 알려 드립니다

이런 계측 기록을 새로 쓰면 메일로 한 통 보냅니다. 광고나 판촉은 보내지 않습니다.