혼란스러운 중간 단계야말로 테스트가 진가를 발휘하는 곳입니다
요약
제품의 해피 패스(happy path)가 아닌, 세션 만료, 권한 변경, 복잡한 상태 변화가 발생하는 '혼란스러운 중간 단계(messy middle)'에서의 테스트 중요성을 강조합니다. 브라우저 자동화를 통해 복잡한 관리자 콘솔의 상태 머신과 권한 로직을 검증하는 전략을 제시합니다.
핵심 포인트
- 단순 성공 경로가 아닌 복잡한 상태 전환 단계의 테스트가 필수적임
- 관리자 콘솔의 밀도 높은 권한 로직과 상태 변화를 검증해야 함
- 브라우저 자동화를 활용해 세션 및 권한 변경 상황을 재현할 것
- 제3자 쿠키 제한 등 브라우저별 동작 차이가 비즈니스 로직에 미치는 영향 주의
대부분의 제품 데모는 동일한 형태를 따릅니다.
사용자는 깨끗한 상태에서 시작하여, 유효한 정보를 입력하고, 명확한 버튼을 클릭하여, 예상된 결과에 도달합니다.
대부분의 실제 실패는 다른 곳에서 발생합니다.
세션이 만료된 후에 발생합니다.
역할(role)이 변경되었지만 페이지가 여전히 캐시된 권한(cached permissions)을 유지하고 있을 때 발생합니다.
필터(filter), 정렬 순서(sort order), 그리고 페이지네이션(pagination) 상태가 상호작용할 때 발생합니다.
LLM이 잘못된 비즈니스 의미를 가진 유효한 JSON을 반환할 때 발생합니다.
할인 적용은 성공했지만 배송비 재계산이 실패할 때 발생합니다.
이것이 바로 혼란스러운 중간 단계(messy middle)입니다. 즉, 깨끗한 해피 패스(happy path)와 깔끔하게 처리된 에러 사이의 상태들입니다.
또한 이곳은 브라우저 자동화(browser automation)가 제 역할을 다하는 곳이기도 합니다.
관리자 콘솔은 테이블을 입은 상태 머신(state machines)입니다
AI 제품은 종종 채팅 인터페이스로 시작하여 빠르게 관리자 콘솔(admin console)을 축적합니다.
누군가는 다음을 관리해야 합니다:
- 사용자(users);
- 역할(roles);
- 프롬프트(prompts);
- 모델(models);
- 사용 제한(usage limits);
- 감사 이력(audit history);
- 데이터 보존(data retention);
- 기능 액세스(feature access);
- 승인 정책(approval policies).
이러한 화면들은 평범한 양식(forms)과 테이블(tables)처럼 보이지만, 밀도 높은 권한 로직을 포함하고 있습니다. 뷰어(Viewer)는 설정을 볼 수는 있지만 수정할 수는 없습니다. 에디터(Editor)는 프롬프트를 변경할 수는 있지만 결제(billing)는 변경할 수 없습니다. 관리자(Admin)는 액세스 권한을 취소할 수는 있지만 감사 이력을 삭제할 수는 없습니다.
AI 관리자 콘솔, 감사 추적 및 역할 기반 설정을 위한 Endtest에 대한 실질적인 고찰을 살펴보면, 페이지가 아닌 전환(transitions)에 기반한 테스트 전략을 제시합니다.
단순히 설정 페이지가 로드되는지만 확인하지 마십시오.
다음과 같은 상황에서 무엇이 변하는지 확인하십시오:
- 세션 중간에 사용자의 역할이 강등될 때;
- 두 개의 탭에서 동작을 시도할 때;
- 두 명의 관리자가 설정을 편집할 때;
- 감사 이벤트(audit event)가 기록될 때;
- 제한된 컨트롤이 비활성화(disabled)되는 대신 숨겨지는지(hidden) 여부;
- 재인증(reauthentication) 후 권한이 새로고침될 때.
비용이 많이 드는 결함은
개인정보 보호 정책의 변화가 브라우저 간 비즈니스 로직의 차이를 만듭니다
제3자 쿠키(Third-party cookie) 제한은 종종 브라우저 호환성 문제로 논의되곤 합니다.
하지만 많은 제품에 있어, 이는 인증(authentication) 및 기여(attribution)의 문제입니다.
임베디드 로그인(Embedded login), 결제 제공업체(payment providers), 지원 위젯(support widgets), 분석(analytics), 그리고 교차 도메인 핸드오프(cross-domain handoffs)는 Chrome, Edge, Safari에 따라 다르게 동작할 수 있습니다. 메인 페이지는 정상적으로 보일 수 있지만, 중요한 통합 기능이 조용히 상태(state)를 잃어버릴 수 있습니다.
Chrome, Edge, Safari에서 제3자 쿠키 오류를 재현하는 것의 유용한 작업은 단순히 브라우저 설정을 전환하는 것이 아닙니다.
그것은 쿠키에 의존하는 사용자 여정(user journey)을 재현하는 것입니다:
- 하나의 도메인에서 시작하여;
- 임베디드되거나 리디렉션된 서비스를 거쳐;
- 예상된 상태(state)와 함께 돌아오고;
- 상태를 사용할 수 없을 때 복구되는 과정.
테스트는 성공과 우아한 성능 저하(graceful degradation)를 모두 검증해야 합니다.
사용자는 쿠키가 차단되었다는 사실에는 관심이 없습니다.
그들은 로그인이 다시 시작되었거나, 결제 과정에서 장바구니를 잃었거나, 지원 채팅이 대화 내용을 잊어버린 것에 관심을 가집니다.
검색 인터페이스는 조합을 통해 실패합니다
검색, 필터, 정렬 페이지는 잘못 테스트하기 매우 쉽습니다.
자동 생성된 테스트 스위트(suite)는 각 컨트롤을 독립적으로 확인할 수 있습니다:
- 검색이 결과를 반환하는지;
- 카테고리 필터가 작동하는지;
- 정렬 순서가 변경되는지;
- 페이지네이션(pagination)이 진행되는지.
실제 결함은 상태(state)가 결합될 때 나타납니다:
- 정렬 시 선택된 필터가 초기화됨;
- 쿼리(query)를 변경해도 유효하지 않은 페이지 번호가 유지됨;
- 하나의 필터를 해제하면 모든 필터가 해제됨;
- URL과 화면에 보이는 컨트롤이 일치하지 않음;
- 뒤로 가기 탐색 시 상태의 일부만 복구됨;
- 결과는 업데이트되지만 개수(count)는 업데이트되지 않음.
이것이 바로 셀렉터 노이즈(selector noise) 없이 검색, 필터 및 정렬 워크플로를 위한 테스트 자동화 플랫폼을 평가할 때 상태 모델링 (state modelling)에 집중해야 하는 이유입니다.
셀렉터 (Selectors)도 중요하지만, 그것이 주요 난관은 아닙니다.
진짜 어려운 부분은 수백 개의 거의 동일한 테스트를 만들지 않으면서, 다양한 조합을 표현하고 재사용하는 것입니다.
좋은 접근 방식은 다음과 같이 소수의 대표적인 상태를 정의하는 것입니다:
- 필터 없음;
- 필터 하나;
- 충돌하는 필터;
- 결과 없음;
- 딥링크된 상태 (deep-linked state);
- 복구된 브라우저 히스토리;
- 요청 간의 변경된 데이터.
그런 다음 컨트롤, URL 상태, 결과 및 개수(count) 사이의 관계를 단언(assert)합니다.
유효한 JSON이라도 여전히 틀릴 수 있습니다
LLM 기능은 새로운 범주의 잘못된 확신 (false confidence)을 추가합니다.
모델이 JSON을 반환합니다. 파서 (parser)가 이를 수락합니다. 스키마 검증기 (schema validator)를 통과합니다. 테스트는 초록색(pass)으로 변합니다.
하지만 출력값은 여전히 제품의 실제 규칙을 위반할 수 있습니다.
다음과 같은 결과를 반환하는 비용 분류 서비스를 상상해 보십시오:
{
"category": "travel",
"amount": -240,
...
이 객체는 기본 스키마는 만족할지 모르지만, 워크플로 관점에서는 터무니없는 내용일 수 있습니다.
JSON 스키마 (JSON Schema), 정규 표현식 (regex) 규칙 및 골든 파일 (golden files)을 사용하여 LLM의 구조화된 출력을 테스트하는 기술은 다음과 같이 계층적으로 적용할 때 가장 효과적입니다:
- 구문 (Syntax): 출력이 파싱 가능한가?
- 형태 (Shape): 스키마와 일치하는가?
- 제약 조건 (Constraints): 값이 도메인 규칙을 만족하는가?
- 관계 (Relationships): 필드들이 서로 일관적인가?
- 의미론 (Semantics): 결과가 사용자의 작업에 수용 가능한가?
- 안정성 (Stability): 반복 실행 시 출력이 허용 가능한 범위 내에 머무는가?
골든 파일 (Golden files)이 도움이 될 수 있지만, 확률적 출력 (probabilistic output)에 대해 정확히 일치(exact matching)를 요구하는 것은 종종 너무 엄격합니다.
테스트는 단 하나의 신성한 문장을 요구하는 것이 아니라, 허용 가능한 범위를 정의해야 합니다.
인증(Authentication)은 편리함이 사라진 이후에 테스트되어야 합니다
로그아웃 상태에서 시작하여 유효한 자격 증명을 입력하고 대시보드에 도달하는 로그인 테스트는 필요합니다.
하지만 이는 가장 흥미롭지 않은 인증 시나리오이기도 합니다.
운영 환경(Production)에서의 장애는 다음과 같은 상황에서 발생합니다:
- SSO가 잘못된 테넌트(tenant)로 반환될 때;
- MFA(다요소 인증)가 만료될 때;
- 브라우저가 두 번째 탭을 열 때;
- 양식(form) 작성 중에 세션이 만료될 때;
- 리프레시 토큰(refresh tokens)이 거부될 때;
- 재인증(reauthentication)은 성공했지만 로컬 상태(local state)가 오래된(stale) 상태일 때;
- 로그아웃이 한 시스템은 정리하지만 다른 시스템은 정리하지 않을 때.
Endtest를 이용한 SSO, MFA 및 만료된 세션 복구 평가가 유용하려면, 해당 도구가 전체 시퀀스를 보존하고 관찰할 수 있는지 물어야 합니다.
단순히 "사용자가 로그인했다"는 것만으로는 검증(assertion)이 부족합니다.
다음 사항들을 검증해야 합니다:
- 사용자가 의도했던 동작으로 돌아왔는가;
- 전환 과정 중에 민감한 데이터가 노출되지 않았는가;
- 중복 제출이 발생하지 않았는가;
- 올바른 테넌트(tenant)와 역할(role)이 복구되었는가;
- 오래된(stale) 세션 데이터가 정리되었는가;
- 실패 시 복구 가능한 경로를 제공했는가.
세션 복구(Session recovery)는 제품의 일부입니다.
이를 단순히 테스트 설정(test setup)의 일부로 취급하면 버그를 숨기게 됩니다.
결제 실패는 대개 상호작용의 실패입니다
결제(Checkout)는 종종 다음과 같은 깔때기(funnel) 구조로 표현됩니다:
장바구니 → 주소 → 배송 → 결제 → 확인.
하지만 실제 결제는 분기되는 시스템입니다.
할인이 총액을 변경합니다. 배송 규칙은 위치, 재고 및 장바구니 금액에 따라 달라집니다. 결제 시 리다이렉트(redirect)가 필요할 수 있습니다. 사용자가 세부 정보를 입력하는 동안 재고가 변경될 수 있습니다. 실패한 시도가 재시도될 수도 있습니다. 게스트 사용자가 흐름 중간에 로그인할 수도 있습니다.
할인, 배송 규칙 및 복구 경로가 어긋나지 않게 하면서 다단계 결제 흐름을 테스트하는 것의 과제는, 불가능한 테스트 매트릭스(test matrix)를 만들지 않으면서도 리스크를 드러낼 수 있는 조합을 선택하는 것입니다.
유용한 방법 중 하나는 상태를 변경하는 경계(state-changing boundaries)를 식별하는 것입니다:
- 프로모션 적용 (promotion applied);
- 주소 검증 (address validated);
- 배송 방법 선택 (shipping method selected);
- 세금 재계산 (tax recalculated);
- 결제 승인 (payment authorized);
- 주문 확정 (order committed).
그런 다음 이러한 경계의 직전과 직후에 발생하는 실패를 테스트하십시오.
사용자가 재시도할 수 있는가?
합계가 여전히 정확한가?
주문이 두 번 생성되었는가?
할인이 사라졌는가?
장바구니를 여전히 복구할 수 있는 상태로 유지했는가?
이러한 질문들은 모든 필드가 입력을 수락하는지 확인하는 것보다 훨씬 더 큰 확신을 줍니다.
화면이 아닌 모델의 전환 (Model transitions, not screens)
관리 콘솔(admin consoles), 쿠키 제한(cookie restrictions), 필터(filters), AI 출력(AI outputs), 인증(authentication), 그리고 결제(checkout)를 관통하는 공통점은 상태 전환(state transition)입니다.
화면은 스냅샷(snapshot)입니다.
결함은 종종 스냅샷 사이의 인계(handoff) 과정에서 발생합니다.
이는 다음과 같은 실질적인 설계 규칙을 시사합니다:
테스트의 이름을 상태 변화(state change)와 비즈니스적 결과(business consequence)를 바탕으로 명명하십시오.
취약한 이름:
checkout test 14
더 나은 이름:
결제 재시도 후에도 할인이 유지됨 (preserves discount after payment retry)
취약한 이름:
admin permissions
더 나은 이름:
역할 강등 후 편집 권한이 취소됨 (revokes editor controls after role downgrade)
취약한 이름:
search filters
더 나은 이름:
뒤로 가기 탐색 후 쿼리 및 필터가 복구됨 (restores query and filters after back navigation)
더 나은 이름은 팀이 왜 이 테스트가 존재하는지를 명확히 설명하도록 강제합니다.
또한, 로그를 열어보기 전에도 결과(consequence)가 눈에 보이기 때문에 실패 시 담당자를 배정하기가 더 쉬워집니다.
해피 패스(Happy path)는 필요조건이지 충분조건이 아니다
해피 패스(Happy-path) 테스트는 유용한 스모크 테스트(smoke detectors)입니다. 주요 경로가 열려 있는지를 알려줍니다.
하지만 제품의 품질은 사용자가 우회하거나, 상태를 잃거나, 작업을 재시도하거나, 오래된 권한(stale permissions)에 직면하거나, 기술적으로는 유효하지만 실제로는 잘못된 출력을 받는 상황에서 무엇이 발생하는지에 의해 결정되는 경우가 많습니다.
그것이 바로 혼란스러운 중간 단계(messy middle)입니다.
모든 조합을 테스트할 필요는 없습니다.
돈, 신뢰, 접근 권한 또는 사용자의 작업이 손실될 수 있는 전환(transitions) 지점을 식별해야 합니다.
그곳부터 시작하십시오.
그것들이 바로 사람들이 감사함을 느끼며 기억하는 테스트들입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기