구조 검사가 통과해도 화면 검토는 남습니다
flat props를 검사하는 AST 테스트와 초기 로딩의 중복 API 검사. 각각 무엇을 확인하는지 구분하고, 이전 글의 UI 불변 증명 표현을 바로잡았어요.
컴포넌트의 props를 정리하고 패키지를 옮길 때, 검사 결과에 초록불이 켜지면 안심하기 쉬웠어요. 하지만 구조 규칙을 지켰다는 결과만으로 화면까지 같다고 말할 수는 없었습니다. 무엇을 자동으로 확인하고 무엇을 직접 봐야 하는지, 검사의 역할부터 구분했어요.
2026년 9월 8일 정정: 이전 글의 ‘SHA-256으로 UI 불변을 증명했다’는 설명과 관련 수치는 근거를 다시 확인하지 못해 제외했어요. 현재 코드에서 확인한 지문은 API 요청을 구분하는 용도입니다. 아래에는 확인 가능한 구조 검사와 브라우저 검증의 역할을 정리합니다.

반복되는 컨벤션을 검사로 옮겼어요
도메인 객체의 필드를 props로 하나씩 펼치는 방식처럼, 리뷰마다 같은 이야기를 하는 패턴이 있었어요. 그래서 TypeScript Compiler API로 컴포넌트와 props 타입 구조를 읽고, 정해 둔 위반을 찾아내는 검사를 만들었습니다.
이름이 비슷한 필드만 세는 것으로는 부족해요. 다른 파일에서 참조한 타입도 살펴야 하고, 작은 공용 UI의 합당한 props까지 도메인 컴포넌트의 위반으로 처리하면 안 되니까요. 명시적 위반과 검토가 필요한 경우를 나누고 예외도 다뤘어요.
검사 코드와 사례 테스트는 component-api-contract.audit.ts, component-api-contract.architecture.test.ts에 있어요. 저장소 검사에서 위반이 남으면 테스트가 실패하고, 이 검사를 PR 정적 검사에 연결했습니다.
검사기도 정상 코드를 잘못 막을 수 있어요
위반 예시를 잡는지만 확인하면 검사기가 지나치게 넓게 막는 문제를 놓칠 수 있어요. 정상 구조, 타입 참조, 예외 판정도 테스트하는 이유입니다. 검사가 실패했을 때는 호출부의 계약과 실제 코드를 함께 읽어야 해요.
| 확인하는 사례 | 기대하는 판단 |
|---|---|
| 도메인 필드를 흩어 놓은 명시적 위반 | 위반으로 보고하고 실패 |
| 정상적인 도메인 객체 props | 구조를 인정하고 통과 |
| 참조 타입과 공용 UI의 예외 | 실제 계약에 맞게 판정 |
| 규칙만으로 단정하기 어려운 구조 | 사람이 검토할 근거 제공 |
규칙을 통과했다고 설계가 전부 옳다는 뜻은 아니에요. 레이어 방향과 공개 경계, 컴포넌트 책임까지 판단하려면 변경 맥락을 봐야 합니다. 자동 검사는 그 리뷰에서 반복되는 확인을 맡아요.
구조 검사와 네트워크 검사는 다른 질문을 해요
브라우저에서는 사이드바와 홈처럼 같은 데이터를 사용하는 곳의 캐시 재사용도 확인하고 싶었어요. Playwright로 페이지 초기 로딩 요청을 수집하고, HTTP method·정규화된 URL·본문을 기준으로 같은 요청이 반복되는지 비교하는 검사를 연결했습니다.
여기에 쓰는 요청 지문은 두 요청이 같은지를 구분하기 위한 값이에요. JSX의 렌더 결과나 화면 픽셀의 동일성을 증명하는 값이 아닙니다. 같은 SHA-256이라는 이름을 쓰더라도 무엇을 입력으로 비교하는지가 중요해요.
검사의 대상과 관측 구간도 제한돼요. 초기 로딩 검사가 통과했다고 전체 사용자 행동에서 중복 요청이 없거나, 모든 캐시 정책이 정확하다고 확대해서 말할 수는 없습니다.
화면 검토는 여전히 남아요
구조를 바꾼 뒤에는 주요 동작과 상태 전환, 화면의 표시 결과를 별도로 확인해야 해요. 정적 검사, 브라우저 테스트, 직접 검토가 각각 다른 문제를 다루기 때문입니다. 검사 수가 많다는 사실보다 각 검사가 놓치는 범위를 아는 편이 더 유용했어요.
이번 정리는 2026년 9월 8일의 코드와 설정 확인을 바탕으로 했어요. 모든 테스트를 다시 실행한 성공 기록이나 과거의 화면 무변경 증거를 대신하는 자료는 아닙니다.
지금은 자동 검사 결과를 설명할 때 ‘무엇이 안전하다’보다 ‘어느 규칙과 구간을 확인했다’를 먼저 말하려고 해요. 브라우저 쪽에서 실제로 수집하는 대상은 브라우저가 뭘 받아가는지에서 이어집니다.


