본문으로 건너뛰기
중급약 35분

분석 태그 검증 — GA4 이벤트·데이터 레이어·GTM 이 설계대로 수집되는지 확인하기

기능은 멀쩡한데 수집이 깨져 조직 전체가 틀린 숫자로 결정하는 일이 흔하다. GA4 이벤트 이름·매개변수 규칙과 수집 한도를 근거로 측정 계획 자체를 검토하고, dataLayer 푸시를 읽고, 브라우저 네트워크 탭·GTM 미리보기·GA4 DebugView 세 가지로 태그 발사를 직접 교차 검증하는 절차를 익힌다.

  • #GA4
  • #GTM
  • #dataLayer
  • #태그검증
  • #측정계획

개념

아무도 테스트하지 않는 기능

결제 버튼이 안 눌리면 30분 안에 신고가 들어온다. 그런데 결제 버튼을 눌렀을 때 발사돼야 할 purchase 이벤트가 안 나가면 아무도 모른다. 몇 주 뒤 마케팅팀이 "전환율이 이상하다"고 말할 때쯤이면 그 기간의 데이터는 복구할 수 없다. 수집되지 않은 이벤트는 소급해서 만들 수 없기 때문이다.

이 자리가 대체로 비어 있다. 마케터는 설계를 하고, 개발자는 구현을 하고, 설계대로 구현됐는지 확인하는 사람이 정해져 있지 않다. QA 가 그 자리를 가져가면 조직 전체의 의사결정 품질이 올라간다.

이 레슨은 그 검증 절차를 다룬다. 다루는 층은 셋이다.

① 웹 페이지의 dataLayer       개발자가 심은 값 — "무엇을 밀어 넣었나"
        ↓
② 태그 관리자(GTM)            트리거와 태그 — "언제 무엇을 보내기로 했나"
        ↓
③ 분석 도구(GA4)              수집된 결과 — "실제로 무엇이 도착했나"

세 층을 각각 확인할 수 있어야 결함이 어느 층에서 생겼는지 를 말할 수 있다. "GA 에 데이터가 없다"만으로는 개발자도 마케터도 움직이지 못한다.

먼저 설계를 본다 — 측정 계획 검토

구현을 확인하기 전에 설계가 규칙을 지키는지 본다. 요구사항 리뷰(모듈 2)와 같은 일을 이벤트 설계서에 하는 것이다. GA4 의 규칙 중 QA 가 근거로 쓸 만한 것은 이 정도다.

이름 규칙

  • 이벤트 이름은 대소문자를 구분한다. add_to_cart 와 Add_To_Cart 는 서로 다른 이벤트로 집계된다. 설계서에 표기가 섞여 있으면 그 자체가 결함이다
  • 이름은 letter 로 시작하고 영문자·숫자·밑줄만 쓴다. 공백은 쓸 수 없다
  • firebase_, ga_, google_ 로 시작하는 이름은 예약돼 있어 쓸 수 없다. 매개변수 이름은 여기에 더해 밑줄로 시작하거나 gtag. 로 시작할 수 없다
  • page_view, session_start, click, scroll, error 처럼 GA4 가 자동으로 수집하는 이름을 커스텀 이벤트로 다시 쓰면 안 된다. 설계서에서 가장 자주 나오는 위반이다

수집 한도 (현재 GA4 기준, 원문에서 확인한 값)

항목한도
이벤트 이름 길이40자
이벤트당 매개변수 수25개
매개변수 이름 길이40자
매개변수 값 길이100자 (page_title 300, page_referrer 420, page_location 1,000)
속성당 사용자 속성25개 (이름 24자, 값 36자)

값 길이 100자 가 실무에서 자주 걸린다. 상품명·검색어·페이지 제목을 매개변수로 넣는 설계에서 긴 값이 잘려 나가고, 잘린 값은 그대로 집계된다. 설계서에서 "긴 문자열이 들어갈 수 있는 매개변수"를 표시하고 경계값을 시험 항목으로 잡는다 — 경계값 분석(모듈 3)을 태그에 적용하는 것이다.

전자상거래 이벤트는 필수 매개변수가 정해져 있다. purchase 는 currency·value·transaction_id·items 가 필요하고, add_to_cart·begin_checkout 은 currency·value·items 가 필요하다. value 는 상품별 price * quantity 의 합이며 배송비·세금은 제외한다. transaction_id 가 유일하지 않으면 매출이 중복 집계된다 — 레슨 6에서 이 문제를 정면으로 다룬다.

1층 — dataLayer 읽기

GTM 을 쓰는 사이트는 페이지의 값을 dataLayer 라는 배열에 밀어 넣고, GTM 이 그것을 읽어 태그를 발사한다. 구매 완료 페이지의 푸시는 보통 이렇게 생겼다.

window.dataLayer = window.dataLayer || [];
 
// 이전 이벤트의 ecommerce 객체를 먼저 비운다 (값이 섞이는 것을 막는 Google 권장 절차)
window.dataLayer.push({ ecommerce: null });
 
window.dataLayer.push({
  event: 'purchase',
  ecommerce: {
    transaction_id: 'T-880123',
    value: 52000,
    tax: 4727,
    shipping: 3000,
    currency: 'KRW',
    coupon: 'WELCOME10',
    items: [
      { item_id: 'SKU-1001', item_name: '무선 마우스', price: 26000, quantity: 1 },
      { item_id: 'SKU-2044', item_name: '키보드 커버', price: 26000, quantity: 1 }
    ]
  }
});

QA 는 브라우저 콘솔에서 이 배열을 직접 볼 수 있다.

// 현재까지 쌓인 전체
dataLayer
 
// 마지막 푸시만
dataLayer[dataLayer.length - 1]
 
// purchase 이벤트만
dataLayer.filter(d => d.event === 'purchase')

여기서 확인할 것.

  • 값이 비어 있지 않은가 — undefined·빈 문자열·0 이 들어간 매개변수는 수집돼도 쓸모가 없다
  • 타입이 맞는가 — value: '52000'(문자열)과 value: 52000(숫자)은 다르다. 문자열이면 집계에서 문제가 된다
  • 화면 값과 같은가 — value 가 실제 결제 금액과 맞는지, items 의 수가 주문 상품 수와 같은지. 여기서 레슨 1의 조회 와 대조하면 완벽하다
  • 몇 번 푸시됐는가 — 같은 purchase 가 두 번 들어 있으면 그게 곧 매출 중복이다. 새로고침·뒤로가기로 재현해 본다

2층 — GTM 미리보기로 "발사됐는가" 확인

GTM 컨테이너에 접근 권한이 있다면 미리보기 모드가 가장 정확하다. 절차는 이렇다(현재 콘솔 기준).

  1. GTM 작업공간(Workspace) 오른쪽 위의 미리보기(Preview) 를 누른다
  2. Tag Assistant 가 새 탭에서 열린다. 확인할 사이트 URL 을 입력하고 Connect 를 누른다
  3. 사이트가 새 창에서 열리고 "Connected" 표시가 뜬다. Tag Assistant 로 돌아와 Continue 를 누르면 디버그 화면이 나온다
  4. 사이트에서 검증할 동작을 수행한다(장바구니 담기, 결제 완료 등)
  5. 디버그 화면 왼쪽의 이벤트 목록 에서 해당 이벤트를 클릭한다

그 시점에서 볼 것이 넷이다.

탭무엇을 확인하나
Tags Fired발사돼야 할 태그가 실제로 발사됐는가
Tags Not Fired발사되지 않은 태그와 그 이유(어느 트리거 조건이 안 맞았는가)
Variables태그가 읽은 변수 값. 여기서 undefined 가 보이면 원인이 확정된다
Data Layer그 이벤트 시점의 dataLayer 상태

"Tags Not Fired" 를 보는 것이 핵심이다. 발사 안 된 태그의 트리거 조건을 펼치면 어느 조건에서 걸렸는지 를 보여 준다. 대부분의 수집 결함이 여기서 끝난다 — 트리거 조건이 페이지 경로를 /order/complete 로 걸어 뒀는데 실제 경로가 /order/complete/ 였다든가 하는 식이다.

3층 — GA4 DebugView 로 "도착했는가" 확인

GTM 에서 발사됐어도 GA4 에 도착했다는 보장은 없다. 마지막 확인은 DebugView 다.

디버그 모드를 켜는 방법(공식 문서 기준)

  • Tag Assistant / GTM 미리보기 를 쓰면 디버그 모드가 자동으로 켜진다. 가장 간단한 방법이다
  • gtag.js 직접 구현이면 설정에 debug_mode 를 넣는다 — gtag('config', 'G-XXXXXXX', { 'debug_mode': true });
  • GTM 이면 Google 태그 설정 또는 개별 이벤트 태그에 debug_mode 매개변수를 true 로 넣는다
  • 끄려면 매개변수를 제거한다. false 로 바꾸는 것으로는 꺼지지 않는다 — 문서에 명시된 주의사항이다

보는 곳: GA4 속성의 관리(Admin) → 데이터 표시(Data display) → DebugView. 콘솔 메뉴 이름은 바뀔 수 있으므로, 못 찾으면 관리 화면에서 "DebugView" 를 검색한다.

화면은 세 부분이다.

  • 초 단위 스트림 — 최근 60초의 이벤트가 순서대로 흐른다. 이벤트를 클릭하면 매개변수와 값이 펼쳐진다
  • 분 단위 스트림 — 최근 30분의 분당 이벤트 수
  • 상단 이벤트·사용자 속성 — 빈도 높은 이벤트와 현재 사용자 속성 상태

기기 선택기가 있어 여러 기기를 구분해 볼 수 있다. 한 가지 함정이 있는데, 동의 모드(consent mode)나 클라이언트 측 개인정보 통제가 적용돼 있고 사용자가 분석 쿠키에 동의하지 않았다면 이벤트가 나타나지 않는다. "DebugView 에 안 보인다"가 곧 "태그가 깨졌다"는 아니다. 동의 배너를 어떤 상태로 두고 테스트했는지를 항상 기록한다.

층을 건너뛰지 않는 확인 — 네트워크 탭

세 층 중 어디서 끊겼는지 가장 빨리 알려 주는 것이 개발자 도구 네트워크 탭이다(모듈 9 레슨 10). GA4 는 수집 요청을 collect 경로로 보내므로 필터에 collect 를 넣으면 잡힌다(도메인은 지역·설정에 따라 다를 수 있으니 경로 조각으로 거르는 편이 안전하다).

요청을 클릭해 쿼리 문자열이나 페이로드를 보면 실제 전송된 값이 보인다. 자주 보는 키는 이 정도다.

키뜻
tid측정 ID (G- 로 시작). 운영과 테스트 속성이 바뀌지 않았는지 확인하는 열쇠
en이벤트 이름
ep.*이벤트 매개변수 (문자열)
epn.*이벤트 매개변수 (숫자)
cid클라이언트 ID

tid 확인은 습관으로 만들 가치가 있다. 스테이징에서 테스트한 데이터가 운영 속성으로 들어가 실적을 오염시키는 사고 가 드물지 않다.

판정표 — 어느 층에서 끊겼나

dataLayerGTM 미리보기DebugView판정
푸시 없음이벤트 없음없음프런트엔드 구현 누락 — 개발팀
푸시 있음Tags Not Fired없음트리거 조건 오류 — GTM 담당
푸시 있음Tags Fired없음전송 차단(동의·광고 차단기·CSP) 또는 측정 ID 오류
푸시 있음Tags Fired있으나 값이 다름변수 매핑 오류 — GTM 담당
푸시 값이 틀림Tags Fired틀린 값 그대로데이터 원천 오류 — 개발팀

이 표 한 장이 이 레슨의 결론이다. 결함 리포트에 어느 행에 해당하는지 를 적으면 담당이 자동으로 정해진다.

실무에서 왜 필요한가

수집 결함은 되돌릴 수 없다 는 점에서 다른 결함과 성격이 다르다. 기능 결함은 고치면 그 이후 사용자가 정상 경험을 하지만, 3주간 수집되지 않은 purchase 이벤트는 영원히 빈칸이다. A/B 테스트를 그 기간에 돌렸다면 실험 결과도 함께 버려야 한다.

영향 범위도 넓다. 수집 데이터는 마케팅 예산 배분, 기능 우선순위, 투자 보고, 광고 최적화에 쓰인다. 중복 purchase 로 전환이 1.4배 부풀려지면 그 숫자를 근거로 광고비가 더 집행된다. QA 가 릴리스 전에 30분 확인해서 막을 수 있는 일이다.

실무 감각으로 하나 덧붙이면, 릴리스 체크리스트에 태그 확인을 한 줄 넣는 것만으로도 절반은 잡힌다. 태그는 프런트엔드 리팩터링에서 가장 잘 깨진다. 버튼을 감싸는 DOM 구조가 바뀌면 GTM 의 클릭 트리거가 조용히 죽고, 기능 테스트는 전부 통과한다.

채용시장에서의 위치

"GA·GTM 이해" 또는 "데이터 기반 QA"는 커머스·플랫폼·그로스 조직 공고에서 우대사항으로 자주 보이지만, 이걸 실제로 검증해 본 QA 는 드물다. 면접에서 판정표를 설명할 수 있으면 그 자체로 차별점이 된다 — "dataLayer, GTM 미리보기, DebugView 를 각각 확인해서 어느 층에서 끊겼는지 나눠 리포트했습니다"는 문장은 마케팅·개발 양쪽과 일해 본 사람만 쓸 수 있다.

프로덕트 애널리스트·그로스 QA·데이터 QA 로 넘어가는 다리이기도 하다(모듈 45). 제품 지표를 읽는 쪽으로 가려면 그 지표가 어떻게 수집되는지 를 먼저 알아야 하고, 순서가 반대인 사람은 숫자를 의심할 줄 모른다.

실습 과제

과제 1 — dataLayer 관찰 (25분)

GTM 을 쓰는 커머스 사이트 아무 곳이나 연다(개발자 도구 콘솔에서 dataLayer 를 쳐서 배열이 나오면 쓰는 곳이다).

  1. 상품 상세 → 장바구니 담기 → 결제 화면까지 이동하며 각 단계에서 dataLayer[dataLayer.length - 1] 을 찍어 기록한다
  2. 이벤트 이름·매개변수 이름·값 타입을 표로 정리한다
  3. GA4 이름 규칙(대소문자·예약 이름·예약 접두사)과 값 길이 100자 한도 에 비추어 위반 후보를 표시한다
  4. 같은 이벤트가 중복 푸시되는 구간이 있는지 새로고침·뒤로가기로 확인한다

자기 제품에 접근 권한이 있으면 그쪽이 훨씬 좋다. 3번에서 하나라도 나오면 그게 첫 결함이다.

과제 2 — 세 층 교차 검증 (35분)

GTM·GA4 접근 권한이 있는 환경에서 전환 이벤트 하나(purchase 또는 회원가입 완료)를 골라 세 층을 모두 확인하고 표를 채운다. 권한이 없다면 무료 GA4 속성과 GTM 컨테이너를 직접 만들고 간단한 HTML 페이지에 붙여 같은 절차를 돌린다. 이 실습은 개인 계정으로 끝까지 할 수 있다.

확인 지점관찰 값설계서 값일치
dataLayer 푸시
GTM Tags Fired 여부
GTM Variables 값
네트워크 탭 tid·en
DebugView 이벤트·매개변수

불일치가 나오면 판정표에서 어느 행인지 적는다. 전부 일치하면 동의 배너를 거부 상태로 바꾼 뒤 다시 돌려 본다. 그때의 차이가 동의 모드의 영향이다.

과제 3 — 측정 계획 리뷰 (20분)

담당 제품의 이벤트 설계서를 구한다(없으면 과제 1에서 관찰한 이벤트로 역으로 설계서를 만든다). 다음 기준으로 리뷰 의견을 5개 이상 쓴다.

  • 예약 이름·예약 접두사 사용 여부
  • 대소문자 표기 일관성
  • 필수 매개변수 누락(전자상거래 이벤트)
  • 값 길이 100자를 넘길 수 있는 매개변수
  • 매개변수 25개 한도에 가까운 이벤트
  • 같은 의미인데 이벤트마다 이름이 다른 매개변수

각 의견에 "확인 방법" 을 한 줄씩 붙인다. 리뷰 의견은 확인 방법이 있어야 반영된다.

자가 체크리스트

  • dataLayer·GTM·GA4 세 층의 역할을 구분해 설명할 수 있다
  • GA4 이벤트 이름 규칙(대소문자 구분·예약 접두사·예약 이름)으로 설계서를 검토할 수 있다
  • 이벤트 이름 40자·매개변수 25개·값 100자 같은 수집 한도를 시험 항목으로 바꿀 수 있다
  • 콘솔에서 dataLayer 를 읽어 값·타입·중복 푸시를 확인할 수 있다
  • GTM 미리보기를 연결해 Tags Fired / Not Fired 와 그 이유를 읽을 수 있다
  • GA4 디버그 모드를 켜고 끄는 방법을 알고, false 로는 꺼지지 않는다는 점을 안다
  • DebugView 의 초 단위·분 단위 스트림에서 이벤트와 매개변수를 확인할 수 있다
  • 네트워크 탭에서 collect 요청을 잡아 tid·en·매개변수를 확인할 수 있다
  • 테스트 데이터가 운영 측정 ID 로 들어가지 않는지 확인하는 습관이 있다
  • 판정표로 결함이 어느 층에서 생겼는지 지목하고 담당을 정할 수 있다

흔한 실수

  • GA4 보고서에서 확인하려 한다. 표준 보고서는 처리에 시간이 걸린다. 실시간 검증은 DebugView 와 네트워크 탭으로 한다.
  • 동의 배너 상태를 기록하지 않는다. 동의를 안 한 상태면 이벤트가 안 보이는 것이 정상이다. 이 구분 없이 "수집 안 됨"으로 등록하면 반려된다.
  • 광고 차단기를 켠 브라우저로 검증한다. 요청 자체가 막힌다. 검증용 프로필을 따로 둔다.
  • debug_mode 를 false 로 바꿔 껐다고 믿는다. 매개변수를 제거해야 꺼진다.
  • 측정 ID(tid)를 확인하지 않는다. 테스트 이벤트가 운영 속성에 들어가 실적을 오염시킨다.
  • dataLayer 값의 타입을 안 본다. 숫자여야 할 value 가 문자열이면 집계가 깨진다.
  • 한 번 발사되는 것만 확인하고 끝낸다. 새로고침·뒤로가기·재시도에서 중복 발사되는지가 더 큰 문제다(레슨 6).

참고 자료

낯선 말 풀이

이 레슨에 나온 약어입니다. 본문에서도 처음 나올 때 점선으로 표시해 두었습니다 (제목과 링크 글자는 그대로 둡니다).

QA — 품질보증
만든 것이 쓸 만한지 확인하고, 애초에 덜 망가지게 만드는 방법을 정하는 일. "테스트"는 그 일의 일부다.
컨테이너 — 컨테이너
이 커리큘럼에서 두 가지로 쓰인다. ① 프로그램과 그것을 돌리는 데 필요한 것들을 한 상자에 담아, 어느 컴퓨터에서나 똑같이 돌아가게 만든 것 ② 화면에서 여러 요소를 하나로 묶는 바깥 틀. 서버·배포 이야기면 ①, 화면·접근성 이야기면 ②다.
URL — 인터넷 주소
웹에서 무언가의 위치를 가리키는 주소 한 줄.
ID — 식별자
무엇 하나를 다른 것과 구별하기 위해 붙인 이름이나 번호.
CSP — 클라우드 사업자
서버와 저장소를 빌려 주는 회사. 빌린 쪽과 빌려준 쪽의 책임 경계가 정해져 있다.
DOM — 문서 객체 모델
웹 화면을 프로그램이 다룰 수 있게 나무 구조로 바꿔 놓은 것. 화면의 현재 상태를 담고 있다.
HTML — 하이퍼텍스트 표시 언어
웹 화면의 뼈대를 적는 글자 형식. 제목·문단·버튼 같은 역할을 꺾쇠 괄호로 표시한다.

용어집 전체 보기