11년차의 자만심, 그리고 첫 번째
"테스트 환경이 또 안 되네요."
개발자가 슬랙에 남긴 메시지를 보며 저는 속으로 한숨을 쉬었습니다. 11년차 QA 엔지니어이자 SDET인 저에게 이런 상황은 너무나 익숙했습니다. 환경 설정, 의존성 문제, 데이터베이스 연결 오류... 개발자들이 겪는 이런 '사소한' 문제들은 제게 그저 일상적인 이슈 리포트의 한 줄에 불과했죠.
11년간 수많은 제품을 테스트하고, 자동화 프레임워크를 구축하고, CI/CD 파이프라인을 설계해왔습니다. 개발자들이 하는 일? 그 정도는 충분히 이해하고 있다고 생각했습니다.
그런데 2024년 어느 날, 저는 제 노트북에서 처음으로 "yarn install"을 실행하게 되었습니다. 그리고 화면에 뜬 에러 메시지를 보며 깨달았죠. 저는 아무것도 모르고 있었다는 것을요.
JamesCompany는 제가 2년 전부터 운영하고 있는 1인 사업입니다. QA 엔지니어들을 위한 플랫폼을 만들고 싶었죠. 커피챗으로 후배들을 멘토링하고, 교육 허브를 통해 지식을 공유하고, 버그 바운티 아레나에서 실전 경험을 쌓을 수 있는 공간. 처음에는 imweb이라는 노코드 툴로 충분하다고 생각했습니다.
"개발자가 아니어도 웹사이트를 만들 수 있다"는 imweb의 슬로건은 정말 매력적이었습니다. 드래그 앤 드롭으로 페이지를 구성하고, 템플릿을 선택하고, 결제 모듈을 붙이면 끝. 실제로 2년간 이렇게 운영하며 큰 문제는 없었습니다.
하지만 점점 한계가 보이기 시작했습니다. QA 플랫폼답게 더 전문적인 기능을 넣고 싶었는데, imweb의 틀 안에서는 불가능했죠. 테스트 케이스를 자동으로 생성하는 CaseMaker, QA 자동화를 돕는 QAuto 같은 기능들은 커스텀 개발 없이는 구현할 수 없었습니다.
더 중요한 이유가 하나 더 있었습니다. 바로 제 자신의 성장이었죠.
11년간 QA를 하면서 수없이 많은 버그 리포트를 작성했습니다. "이 버튼을 클릭하면 500 에러가 발생합니다", "환경 변수가 제대로 설정되지 않아 API 호출이 실패합니다", "CORS 정책 때문에 프론트엔드에서 백엔드 API를 호출할 수 없습니다"...
그런데 어느 순간 의문이 들었습니다.
과연 제가 이런 이슈들을 정말로 이해하고 있을까요? 아니면 그저 표면적인 현상만 관찰하고 있는 건 아닐까요?
"개발자 입장이 되어 이슈를 만들어보고, QA 관점에서 분석하는 힘을 기르자."
이것이 제가 직접 개발에 뛰어든 이유였습니다. 단순히 더 나은 서비스를 만들기 위해서가 아니라, 더 나은 QA 엔지니어가 되기 위해서였죠.
기술 스택을 선택하는 것부터가 모험이었습니다.
프론트엔드는 React + Vite + TypeScript, 백엔드는 FastAPI + Python, 데이터베이스는 PostgreSQL. 11년간 이 기술들로 만들어진 제품을 테스트해왔으니, 얼마나 어렵겠어요?
첫 번째 난관은 패키지 매니저(Package Manager)였습니다. 프론트엔드는 yarn, 백엔드는 uv pip.
처음엔 "그냥 패키지 설치하는 거 아니야?"라고 생각했는데, yarn.lock과 package-lock.json이 충돌하고, uv와 pip의 미묘한 차이를 경험하면서 제 자만심에 첫 번째 균열이 생겼습니다.
특히 "yarn install"과 "npm install"을 혼용했다가 생긴 의존성 지옥은 잊을 수 없습니다.
"왜 Local에서는 되는데 Vercel에서는 안 되지?"라는 의문이 들 때마다, 제가 그동안 개발자들에게 "환경 확인 부탁드립니다."라고 쉽게 말했던 것이 얼마나 무책임했는지 깨달았죠.
환경 변수 설정은 더 복잡했습니다. 로컬 개발 환경(.env.development.local), Vercel 개발 환경(.env.development), 운영 환경(.env.production)... 각각 다른 설정값들을 관리하면서 왜 개발자들이 "환경에서만 재현되는 버그"를 그렇게 싫어하는지 비로소 이해하게 되었습니다.
"Git push만 하면 자동으로 배포된다"고 들었을 때는 정말 간단해 보였습니다. 하지만 실제로는 어땠을까요? 간단해 보이는 이 구조를 실제로 구현하면서 저는 수많은 실수를 했습니다.
- develop 브랜치에 푸시하면 개발 환경으로 배포
- main 브랜치에 푸시하면 운영 환경으로 배포
- 환경별로 다른 환경 변수는 Vercel Dashboard에서 관리
- 데이터베이스는 로컬(Docker), 개발(AWS PostgreSQL), 운영(AWS PostgreSQL)으로 각각 분리
간단해 보이는 이 구조를 실제로 구현하면서 저는 수많은 실수를 했습니다. 개발 환경의 토스페이먼츠 테스트 키를 운영에 배포하는 바람에 실제 결제가 안 되는 사고도 있었고, CORS 설정을 잘못해서 운영 환경에서만 API 호출이 안 되는 문제도 겪었습니다.
가장 황당했던 것은 백엔드에서 uv pip로 설치한 패키지가 Vercel 빌드 환경에서는 인식되지 않아서, requirements.txt를 따로 관리해야 했던 일입니다. "로컬에서는 되는데..."라는 말이 왜 개발자들의 영원한 숙제인지 뼈저리게 느꼈죠.
결제 시스템을 구현하면서 겪은 일들은 정말 잊을 수 없습니다. 토스페이먼츠의 클라이언트 키와 시크릿 키를 환경별로 분리하는 것은 기본이었지만, 웹훅 검증을 위한 TOSS_WEBHOOK_SECRET까지 관리해야 한다는 것은 문서를 꼼꼼히 읽고서야 알게 되었죠.
가장 큰 실수는 JWT_SECRET_KEY를 Git에 올린 것이었습니다. "어차피 프라이빗 레포지토리인데 뭐 어때"라고 생각했던 제 자신이 부끄러웠습니다. 11년간 보안의 중요성을 강조해온 QA 엔지니어가 이런 초보적인 실수를 하다니요.
"테이블 구조를 바꿔야겠네요. DROP TABLE하고 다시 만들면 되겠죠?"
개발 초기에 저는 정말 이렇게 생각했습니다.
다행히 SQLAlchemy와 Alembic을 도입하면서 체계적인 마이그레이션 관리의 중요성을 깨달았죠. 개발 환경과 운영 환경의 데이터베이스 스키마를 동기화하고, 변경 이력을 관리하는 것이 얼마나 중요한지 몸소 체험했습니다.
이 글을 쓰고 있는 지금도 JamesCompany의 리뉴얼 작업은 계속되고 있습니다. 2025년 7월 중 오픈을 목표로 밤낮없이 코딩하고 있죠. 처음에는 손쉽게 Canva로 시작하고, imweb로 변경했다가, React + FastAPI로 완전히 새롭게 태어날 JamesCompany. 이 여정에서 배운 것들을 하나씩 풀어놓으려 합니다.
이 프롤로그는 시작에 불과합니다. 앞으로 제가 겪은 경험들을 하나씩 풀어놓을 예정입니다.
환경 분리와 환경 변수 - Local, Development, Production의 미묘한 차이들
패키지 관리자의 혼돈 - npm, yarn, brew... 아무거나 쓰면 되는 줄 알았다
Alembic과 데이터베이스 마이그레이션 - 테이블 DROP은 이제 그만
Monorepo에서 Multi-repo로 - 모든 걸 한 곳에 넣으면 편할 줄 알았던 착각
CORS와 도메인 정책 - Vercel에서는 되는데 운영에서 안 되는 이유
보안 키 관리의 악몽 - Git에 올라간 JWT Secret Key
Vercel 배포와 CI/CD - Git Push만 하면 끝인 줄 알았던 날들
의존성 관리의 이중고 - yarn과 uv pip의 조화
결제 시스템 구현 - 토스페이먼츠 연동의 숨겨진 복잡성
인증/인가 시스템 - JWT + OAuth가 만나면
파일 업로드와 CDN - 로컬 파일 시스템에서 S3로
모니터링과 에러 추적 - Sentry가 보여준 불편한 진실
QA 플랫폼의 핵심 기능들 - 직접 만들어본 QA 도구들
2년간의 개발 경험은 저를 완전히 다른 QA 엔지니어로 만들었습니다. 이제 개발자가 "환경에서만 재현돼요"라고 하면, 어떤 환경 변수가 문제일지, 어떤 의존성이 꼬였을지, yarn.lock과 requirements.txt 중 무엇을 확인해야 할지 구체적으로 추측할 수 있게 되었습니다.
특히 프론트엔드의 yarn과 백엔드의 uv pip를 동시에 다루면서, 각 생태계의 특성과 함정들을 직접 경험한 것은 큰 자산이 되었습니다. "프론트는 yarn dev로 실행하고, 백엔드는 uvicorn main:app --reload로 실행하세요"라는 README의 한 줄이 얼마나 많은 시행착오 끝에 나온 것인지 이제는 압니다.
무엇보다 중요한 것은 겸손함을 배웠다는 것입니다. 11년의 경험이 때로는 편견이 될 수 있고, 아는 것이 많다고 생각할수록 실제로는 모르는 것이 더 많다는 진리를 깨달았죠.
이 시리즈가 저처럼 "다 안다"고 생각하는 QA 엔지니어들에게, 그리고 "QA 엔지니어는 개발을 모른다"고 생각하는 개발자들에게 작은 울림이 되기를 바랍니다.
개발자 입장이 되어 이슈를 만들어보고, QA 관점에서 분석하는 것. 이것이 진정한 품질을 만드는 길이 아닐까요?
JamesCompany는 2025년 7월, 완전히 새로운 모습으로 여러분을 만날 예정입니다. QA를 위한, QA에 의한, QA의 플랫폼을 만들어가는 여정은 계속됩니다.