자동화 검사
32 · 30 통과
GraphQL 23건(pytest) + 대시보드 9건(Playwright), 문서화된 결함 xfail 2건 포함 — 순서 독립적, 하나의 병합된 Allure 리포트, CI 검증 완료
고정된 로컬 Saleor 환경을 대상으로 독립적인 리스크 기반 QA 프레임워크를 만들었습니다. 결함 또는 후보 이슈 4건을 문서화하고, VFX 작업에서 익힌 미세한 이미지 차이 판별 경험을 크로스 브라우저 시각 회귀 테스트에 적용했습니다.
독립 QA 사례 연구 · Saleor 3.23(고정 로컬 버전) · 특정 시점 결과 · 발견 내용 문서화, 업스트림 미제출
자동화 검사
32 · 30 통과
GraphQL 23건(pytest) + 대시보드 9건(Playwright), 문서화된 결함 xfail 2건 포함 — 순서 독립적, 하나의 병합된 Allure 리포트, CI 검증 완료
문서화한 발견
발견 4건
고정된 로컬 환경에서 결함 또는 후보 이슈 4건을 문서화했고 2건은 strict-xfail 회귀 검사가 뒷받침; 모두 업스트림 미제출
예외 입력에 대한 API 동작
서버 오류 0
8가지 예외 입력에서 서버 오류가 발생하지 않았고, 쿼리 비용과 배치 크기 제한도 유지됐습니다.
시각 베이스라인
40
36개는 chromium/firefox/webkit + chromium 전용 i18n 4개; 재실행 시 차이 0픽셀
시드된 회귀
0.01에서 포착
0.2px 폰트 메트릭 드리프트가 게이트를 실패시킴 — 차이 5,366px, 비율 0.01로 0.005 한계 초과
발견한 i18n 격차
실제 격차 1건
“Catalog” / “Fulfillment”가 zh-Hans / zh-Hant / ko 전부에서 영어로 표시됨
제가 만들지 않은 대형 오픈소스 커머스 플랫폼 Saleor(Python/Django/GraphQL)를 밖에서 검증하는 독립 QA 프레임워크를 구축했습니다. 테스트는 GraphQL API와 관리자 대시보드를 통해 실행 중인 앱을 구동하며 Saleor 자체 코드를 복사하거나 수정하지 않습니다.
첫 부분은 API 견고성·접근 제어·체크아웃을 아우르는 32개 자동화 검사의 리스크 기반 기능 테스트 프레임워크로, 고정된 로컬 환경에서 결함 또는 후보 이슈 4건을 문서화했습니다. 둘째는 크로스 브라우저 시각 회귀 도구로, 시드된 회귀와 로컬라이제이션 격차를 포착했습니다.
로컬 Saleor 3.23(고정된 사전 빌드 이미지)을 대상으로 외부에서 구동합니다. 두 레인 — pytest(GraphQL)와 Playwright(대시보드 + axe) — 이 CI에서 하나의 병합된 Allure 리포트를 내며, 시각 스위트는 자체 설정으로 실행됩니다. 아래의 모든 항목은 저장소의 산출물에 대응합니다: 리스크 기반 테스트 계획, 추적성·커버리지 맵, 초안 버그 리포트 4건, 지각 기반 이미지 비교 문서.
먼저 14개 영역을 발생 가능성과 영향도로 평가했습니다. 자금 이동과 접근 제어를 최우선으로 두고, 국제화, 시각 회귀, 접근성도 별도 위험 영역으로 다뤘습니다. 기능 테스트와 함께 네 가지 전문 검증을 운영했습니다.
잘못된 id와 enum, 지나치게 큰 first 값, 깊게 중첩하거나 별칭을 많이 쓴 쿼리 등 8가지 입력을 시험했습니다. 서버는 500을 반환하지 않았고 모든 실패를 형식이 정해진 GraphQL 오류로 처리했으며, 쿼리 비용과 배치 크기 제한도 유지했습니다. 문제가 확인되지 않은 부분은 통과 결과로 남겨 회귀 검사를 구성했습니다.
MANAGE_ORDERS 전용 App 토큰이 권한 경계를 증명합니다 — 취약한 스태프 초대 흐름 없이도 주문은 읽지만 제품은 생성하지 못합니다. 익명 대 스태프 게이팅과 tokenCreate(정상·잘못된 자격증명)도 함께 다룹니다.
saleor-platform에는 스토어프론트가 없어 고객 여정을 API로 실행합니다: checkoutCreate → 라인 추가 → 주소 → 배송 방법 → 합계. 각 체크아웃·제품·범위 App은 자기 테스트 안에서 생성되고 정리됩니다.
기대 결과는 실행 중인 앱에서 옵니다. 한 부정 입력 테스트는 실제 HTTP 400 검증 계약을 단언합니다 — 업스트림 조사는 200을 예측했지만 실제 앱은 달랐고, 테스트를 시스템에 근거시켜 그 불일치를 잡았습니다.
구조적 탐색 세션을 통해 고정된 로컬 Saleor 3.23 환경에서 증거가 뒷받침된 발견 리포트 4건을 작성했습니다. 이들은 포트폴리오의 결함 또는 후보 이슈이며 업스트림에서 확인된 결함이 아닙니다. 모두 미제출 상태이며, 제출 전 중복 확인과 Saleor의 CLA 또는 보안 공개 절차가 필요합니다.
Checkout의 공개 updateMetadata는 no_permissions에 매핑되어, 인증되지 않은 클라이언트가 1 MB 값, 2,000개 키, 100,000자 키를 오류 없이 받아들였습니다 — 저비용 스토리지/DoS 벡터입니다. strict-xfail 회귀가 원하는 100개 상한을 단언하고, 제한이 도입되면 경보를 울립니다.
Saleor #19210 관련 · 재현(완전) · strict-xfail
checkoutLinesAdd가 한 번의 호출에서 73개의 서로 다른 variant 라인을 받아들였고(시드 카탈로그 수에만 제한됨), 한 CheckoutLine은 1 MB 메타데이터 값을 받았습니다 — 반면 라인당 수량은 50으로 올바르게 제한됩니다. 두 번째 strict-xfail이 원하는 목록 크기 상한을 고정합니다.
Saleor #19209 관련 · 재현(완전) · strict-xfail
axe-core 게이트가 제품 생성 폼에서 접근 가능한 이름이 없는 아이콘 버튼 12개, 누락된 문서 lang, 비활성화된 핀치 줌, AA 미만 대비 노드 5개를 찾았습니다. 고신뢰 항목을 앞세우고, 프레임워크가 생성한 ARIA role 노드는 제출 전 수동 확인 대상으로 표시했습니다.
새 발견 · axe 증거 · 제출 전 중복 제거
get_client_ip가 클라이언트가 제공한 가장 왼쪽 X-Forwarded-For 값을 신뢰하므로, IP별 로그인 스로틀 키를 공격자가 제어·회전할 수 있습니다. 3.23.5 소스로 검증하고 라이브에서 스로틀을 확인했습니다; 깨끗한 종단 간 스푸핑에는 프록시 배포가 필요하므로 이는 완전한 로컬 익스플로잇이 아닌 부분(소스 검증) 재현입니다.
Saleor #19203 관련 · 소스 검증 · 보안 공개
흥미로운 부작용으로, 반복적인 tokenCreate 프로빙이 Saleor의 IP별 로그인 스로틀(LOGIN_ATTEMPT_DELAYED)을 발동시켰습니다. 이를 억지로 우회하는 대신, E2E 스위트는 한 번만 로그인해 공유 storageState로 들어가고 API 픽스처는 스로틀을 재시도하도록 했습니다 — 프레임워크의 인증 재사용 아키텍처를 형성한 실제 테스트 용이성 제약입니다.
스크린샷을 찍는 것 자체는 어렵지 않습니다. 시각 회귀 테스트의 핵심은 실제 UI 변화만 실패로 잡고, 렌더링 노이즈나 글꼴 차이, 계속 바뀌는 타임스탬프는 걸러내는 것입니다. 그래서 기준 이미지와 회귀 사례를 만들기 전에 안정적인 판정 조건부터 정했습니다.
커밋된 베이스라인 40개: 밀도 높은 관리자 화면 3개(제품 편집기, 구성, 주문 상세) × 데스크톱 1280×800 + 모바일 375×812 × 라이트 + 다크 × chromium/firefox/webkit, 여기에 4개 로케일 i18n 패스. saleor-dashboard 자체 설정이 남긴 공백을 메웁니다 — Chrome 전용, 베이스라인 없음, Firefox/WebKit 없음, 모바일 없음.
deviceScaleFactor와 뷰포트를 고정하고, 애니메이션과 캐럿을 끄고, document.fonts.ready를 기다립니다. 시간대와 로케일은 UTC/en-US로 고정하고, 첫 화면을 열기 전에 localStorage로 테마와 UI 로케일을 설정하며, 동적 영역(id·날짜·금액·주소)은 마스킹합니다. 그 결과 여러 차례 깨끗하게 실행했을 때 픽셀 차이가 0으로 유지돼 게이트를 엄격하게 운영할 수 있습니다.
pixelmatch는 의존성 없는 기본값입니다. 위 설정으로도 제거되지 않는 감마나 안티앨리어싱 차이가 나타나면 SSIM으로 전환할 수 있고, 실행 시간이 더 중요하면 odiff를 선택할 수 있습니다. PR에서 나란히 비교해야 할 때는 프레임워크를 다시 쓰지 않고 Argos, Percy, Lost Pixel 같은 서비스로 리포터만 바꾸면 됩니다.
영화 VFX 작업에서 픽셀 단위 QC를 하며 실제 결함과 렌더링 노이즈를 구분했습니다. 이 경험을 웹 UI에 맞게 옮겨, 의미 있는 화면 변화만 자동으로 잡도록 구성했습니다.
Playwright의 toHaveScreenshot은 서로 독립적인 두 허용치를 노출하며, 둘의 사각지대는 정반대입니다. 페이지 전체에 3° 색상 회전을 준 경우 임계값 0.15에서 통과했습니다 — 모든 픽셀의 YIQ 차이가 픽셀당 임계값 아래여서 pixelmatch가 다른 픽셀을 0개로 셌기 때문입니다. 제목만 1px 이동한 것도 통과했습니다 — 비율을 넘기에 픽셀이 너무 적었죠. 안정적으로 실패시킨 것은 0.2px 자간 드리프트였습니다: 모든 글리프 가장자리를 움직여 텍스트 밀도 높은 화면의 약 1% 픽셀을 밝힙니다(비율 0.01로 0.005 게이트 초과). 색상 드리프트를 잡으려면 임계값을 낮춰야 하고, 레이아웃 이동을 잡으려면 비율을 낮추고 텍스트 밀도 높은 대상을 택해야 합니다. 이 상호작용이 핵심 방법론 교훈입니다.
게이트가 실제 회귀를 잡아내는지 확인하기 위해 가장 복잡한 화면인 제품 편집기에 미세한 글꼴 메트릭, 색상, 1px 위치 차이를 의도적으로 넣고 스위트를 다시 실행했습니다. 예상대로 5,366픽셀(비율 0.01, 임계값 0.005 초과) 차이에서 실패했고, 위치가 달라진 폼 레이블을 모두 표시했습니다.
여기서는 원시 pixelmatch 차이 이미지 대신 깨끗한 베이스라인을 보여 줍니다. 차이 이미지는 변경된 픽셀만 어두운 의사색(false-colour) 오버레이로 표시하므로, 전후 화면을 나란히 보지 않으면 시각적 잡음처럼 보일 수 있습니다. 따라서 핵심 증거는 게이트가 판정에 사용한 수치, 즉 5,366픽셀(비율 0.01) 차이이며 이 값이 빌드 실패를 일으켰습니다.
같은 로케일 패스가 진짜 발견을 끌어냈습니다: “Catalog”와 “Fulfillment”가 zh-Hans, zh-Hant, ko 전부에서 영어로 표시되고, “Translations”는 zh-Hans와 ko에서 영어로 남습니다 — 로케일별 베이스라인과 기록된 레이블 리포트로 포착했습니다. 이 너비에서는 잘림이나 넘침이 없습니다. 이는 레이아웃 버그가 아니라 대시보드 번역 완성도 격차이며(제출 전 업스트림에서 중복 제거), 지어낸 것이 아닌 QA 일관성 발견입니다.
프레임워크는 고정된 로컬 Saleor 3.23 환경을 구동하므로 모든 결과는 해당 빌드에 대한 특정 시점 결론입니다. 결함 또는 후보 이슈 4건은 초안 리포트로 문서화했지만 업스트림에 제출하거나 확인받지 않았습니다. 제출 전에는 중복 확인과 Saleor의 CLA 또는 보안 공개 절차가 필요합니다. BR-004는 완전한 로컬 익스플로잇이 아니라 소스 검토와 스로틀 현상 확인 수준입니다. 적대적 입력 테스트에서 API는 500을 내지 않았고 비용·배치 제한이 유지됐으며, 이를 긍정 결과로 기록했습니다.
이 사례가 보여 주는 것은 낯선 프로덕션 코드베이스를 대상으로 독립적인 리스크 기반 QA를 구축한 경험입니다. 실제로 동작하는 테스트 프레임워크, 문서화한 결함 또는 후보 이슈 4건, 의도적으로 넣은 회귀를 잡아낸 지각 기반 이미지 비교 도구를 포함하지만, 보안 감사나 업스트림 기여 실적으로 제시하지는 않습니다.
초안 리포트를 중복 제거해 Saleor 절차로 제출하고(X-Forwarded-For 발견은 보안 공개 경로로); API 레인을 바우처·결제 동시성과 주문 이행 상태 머신으로 확장하고; 고정된 Playwright 이미지 안에서 Linux CI 베이스라인을 부트스트랩하며 결정론이 입증되는 대로 화면별 0.1 / 0.001로 게이트를 조이고; 실제 번역을 시드해 i18n 프로브를 완전한 로케일 매트릭스로 끌어올립니다.
낯선 시스템을 대상으로 한 독립·리스크 기반 QA 사례로, ISTQB 스타일 테스트 설계와 ITIL에 가까운 결함 기록 방식, VFX 컴포지팅 경험을 활용한 지각 기반 이미지 비교를 함께 보여 줍니다.
리스크 기반 계획, 추적성·커버리지 맵, 초안 버그 리포트 4건, 병합된 Allure 리포트, 그리고 시드 회귀 증거가 담긴 시각 회귀 툴킷이 모두 저장소에 있습니다. 워크스루나 리포트의 읽기 전용 열람을 요청하세요.
워크스루 요청