캡차가 있는 앱에서 CI를 초록불로 유지하는 방법
회원가입 폼에 PopularCaptcha가 있고, E2E 테스트 스위트는 가입을 해야 합니다. 그러면 CI가 빨간불이 됩니다. 유혹적인 해결책은 테스트 빌드에서 캡차를 끄는 것이지만, 그러면 테스트하는 흐름이 사용자가 실제로 겪는 흐름과 달라집니다.
이 문제를 해결하는 방법은 여러 가지가 있습니다. 실제 흐름을 얼마나 많이 검증하는지가 방법마다 다르므로, 테스트가 답하려는 질문에 맞는 방법을 고르세요. 가장 저렴한 것부터 가장 현실적인 것 순서로 정리했습니다.
Scarnox는 현재 PopularCaptcha를 풉니다. 다른 캡차 유형은 준비 중이므로, 아래의 풀이 방법은 PopularCaptcha에만 해당합니다.
1. 단위 테스트와 로컬 테스트에는 테스트 키 사용
많은 캡차 공급자가 항상 통과하는 테스트 키를 공개합니다. 환경을 내가 통제하고 폼이 렌더링되고 제출되는지만 확인하면 될 때 사용하세요. 테스트 키는 실제 검증을 수행하지 않으며, 실제 키를 쓰는 배포 환경을 테스트하는 순간부터는 도움이 되지 않습니다.
2. 내 스테이징을 위한 우회 경로
일부 팀은 캡차 토큰 대신 백엔드가 받아들이는 비밀 헤더를 추가합니다. 빠르고 무료지만, 테스트 전용 코드 경로이며 설정 실수 한 번이면 프로덕션에 존재하게 됩니다. 이 방법을 쓴다면 환경 검사 뒤에 두고, 비밀 값은 길고 무작위로 만들고, 프로덕션에서 거부되는지 테스트하세요.
3. 검증 호출 모킹
통합 테스트에서 서버 측 검증 요청을 스텁으로 대체하세요. 검증이 실패할 때 무슨 일이 일어나는지처럼 백엔드 로직을 확인하기에는 좋습니다. 하지만 프론트엔드가 토큰을 올바르게 보내는지는 알려 주지 않으므로, 다른 방법 중 하나와 함께 사용하세요.
4. 스테이징과 스모크 테스트에서 실제로 풀기
실제 키, 실제 위젯, 실제 검증으로 실제 흐름이 끝까지 동작한다는 것을 증명해야 할 때는, 테스트 안에서 솔빙 API로 토큰을 받으세요. 깨진 위젯 연동을 잡아낼 수 있는 유일한 방법입니다.
Playwright 헬퍼는 다음과 같습니다.
// Playwright 테스트 헬퍼
export async function solveCaptcha(page) {
const sitekey = await page.getAttribute("[data-sitekey]", "data-sitekey");
const r = await fetch("https://api.scarnox.com/api/tasks/create", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.SCARNOX_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
captcha_type: "PopularCaptchaTaskProxyless",
site_key: sitekey,
site_url: page.url(),
}),
});
const { errorId, solution, errorCode, errorDescription } = await r.json();
if (errorId !== 0) throw new Error(`${errorCode}: ${errorDescription}`);
await page.evaluate((t) => {
document.querySelectorAll('[name="h-captcha-response"],[name="g-recaptcha-response"]')
.forEach((el) => { el.value = t; });
}, solution.token);
}
테스트에서 폼을 제출하기 직전에 이 함수를 호출하세요. 테스트 시작 시점에 호출하지 마세요. 토큰은 약 2분 안에 만료되며, 테스트 앞부분의 느린 단계가 그 시간을 다 써 버릴 수 있습니다.
솔빙 횟수를 최소로 유지하기
매 실행마다 가입하는 스위트는 일주일 동안 많은 솔빙을 발생시킬 수 있습니다. 횟수를 줄이려면 다음을 지키세요.
- 실제 솔빙은 스테이징과 스모크 테스트에서만 실행하세요. 다른 방법은 모든 커밋에서 사용하세요.
- 테스트 파일마다 말고 파이프라인당 한 번만 실제 솔빙을 실행하세요.
- 헬퍼에서 실행당 솔빙 횟수에 상한을 두세요. 상한에 걸려 실패하는 테스트는 스위트를 검토하라는 명확한 신호입니다.
- 실패한 솔빙은 무료이므로 불안정한 단계는 돈보다 시간을 낭비합니다. 하지만 무분별하게 재시도하는 스위트는 여전히 러너 시간을 낭비합니다.
헬퍼 내부의 재시도 규칙은 오류 처리와 백오프 가이드의 정책을 재사용하세요.
키를 저장소 밖에 두기
키는 SCARNOX_KEY 같은 이름으로 CI 비밀 값에 저장하고, 테스트 코드나 픽스처에는 절대 넣지 마세요. 유출되면 대시보드에서 다시 발급하세요. 이전 키는 즉시 작동을 멈추므로, 유출된 키로 오랫동안 솔빙을 실행할 수 없습니다.
CI에는 별도의 키를 사용하세요. 한 파이프라인이 잘못 동작하더라도 다른 것을 건드리지 않고 그 키만 교체할 수 있습니다.
내 스테이징에서 시험해 보기
계정을 만들고 무료 체험 크레딧으로 시작하세요. 카드 등록은 필요 없습니다. 먼저 헬퍼를 스모크 테스트 하나에 연결해 깔끔하게 가입되는지 확인한 뒤, 나머지 스위트에 추가하세요. 대량으로 풀 때의 비용은 현재 요금을 참고하세요.
제출 후 무엇을 검증할지
캡차가 풀렸다는 것은 위젯 단계가 동작했다는 것만 증명합니다. 제출 후에는 사용자에게 중요한 것을 검증하세요. 다음 페이지가 로드되는지, 성공 메시지가 나타나는지, 계정이나 주문이 데이터베이스에 있는지 확인합니다. "폼에 오류가 없음"에서 멈추는 테스트는, 백엔드에서 가입이 조용히 실패하는 동안에도 통과할 수 있습니다.
검증은 비즈니스 결과에 가깝게 유지하세요. URL, 화면에 보이는 메시지, 테스트가 만든 레코드 하나를 확인합니다. 실행이 끝나면 그 레코드를 정리해서, 다음 실행이 알려진 상태에서 시작되게 하세요.
예약 실행으로 스모크 테스트 돌리기
실제 솔빙을 쓰는 스모크 테스트는 모든 풀 리퀘스트마다가 아니라, 예를 들어 하루에 한 번 스테이징에 대해 예약 실행하세요. 예약 실행은 사이트가 밤사이 바꾼 것, 예를 들어 새 위젯 버전이나 옮겨진 sitekey를 잡아냅니다. 커밋마다 솔빙을 쓰지 않으면서도 이를 확인할 수 있습니다. 예약 실행이 실패하면 팀에 알리고, 커밋별 스위트는 더 빠른 방법으로 유지하세요.