Skip to content

Testing Your Consent Implementation

Testing consent implementations is harder than testing regular analytics because you are verifying the absence of things as much as their presence. A broken consent setup does not throw errors — it silently sends data it should not, or silently fails to send data it should. Neither produces an obvious signal.

This article gives you a systematic protocol for catching both failure modes.

Before any testing:

  1. Open a fresh incognito/private browser window
  2. Navigate to your site
  3. Open DevTools (F12 or Cmd+Option+I)
  4. Keep the Network tab open with “Preserve log” enabled
  5. Filter network requests for google-analytics to isolate GA4 hits

For GTM Preview mode testing:

  1. Activate Preview mode in GTM for your container
  2. Enter Preview mode with the same fresh incognito browser session
  3. Load your site in that session

Test 1: Default denied state (first visit)

Section titled “Test 1: Default denied state (first visit)”

This test verifies that a brand-new visitor generates no identifying data before seeing and accepting the consent banner.

  1. Open incognito browser, load your site
  2. Do not interact with the consent banner
  3. Wait 5 seconds
  4. Check DevTools → Application → Cookies (your domain): _ga and _ga_XXXX should NOT exist
  5. Check Network tab: requests to google-analytics.com/g/collect should either not exist (Basic mode) or include gcs=G100 with no _ga= parameter (Advanced mode)
  6. Check for _gcl_au cookie: should NOT exist

Expected result for Basic mode: Zero requests to Google collection endpoints.

Expected result for Advanced mode: Requests to /g/collect present but with gcs=G100 (or G101/G110 depending on your consent structure) and no client ID parameters.

If test fails: Default consent state is not being set correctly. Check that your gtag('consent', 'default', {...}) call appears before the GTM snippet in your page source (View Source, not DevTools — DevTools may execute scripts differently).

  1. In the same fresh incognito session, click “Accept All” on the consent banner
  2. Immediately check cookies: _ga and _ga_XXXX should now appear
  3. Check Network tab: new requests to /g/collect should appear with gcs=G111 and _ga= parameter present
  4. The _gcl_au cookie should appear if Google Ads tags are configured

If test fails: The consent update (gtag('consent', 'update', {...})) is not firing correctly after banner interaction. Check your CMP integration.

  1. Open a new incognito session
  2. When the banner appears, click “Reject All” or equivalent
  3. Check cookies: no _ga, _ga_XXXX, _gcl_au cookies should appear after rejection
  4. In Advanced mode: check that requests to /g/collect continue but still show gcs=G100 (denied state maintained)
  5. In Basic mode: verify no requests to /g/collect exist at all

If test fails: The consent update for the rejected state is not firing, or the update is not mapping correctly to denied values.

Section titled “Test 4: Returning visitor with existing consent”
  1. In a normal (non-incognito) browser, grant consent on your site
  2. Note which cookies were set and their values
  3. Close the tab completely
  4. Reopen your site
  5. Verify that no consent banner appears (CMP recognized returning consent)
  6. Check in GTM Preview mode: a consent update event should appear early in the event stream, before GA4 tags fire
  7. Check cookies: _ga cookie should be present with the same value as before the tab close

If test fails: The CMP is not restoring consent state on page reload. Returning visitors may be experiencing the default denied state on every visit.

  1. In a normal browser session with consent granted, open the CMP preference center
  2. Revoke all consent (without page reload, if your CMP supports this)
  3. Verify in DevTools: after withdrawal, subsequent user interactions should not generate new GA4 hits (or should generate denied-state hits in Advanced mode)
  4. Reload the page after withdrawal
  5. Verify no _ga cookie is set after reload

Note: GA4’s _ga cookie may still be present in the browser after consent is withdrawn — it was legitimately set when consent was granted. The key behavior to test is that new hits are not generated after withdrawal, and on the next page load the cookie is not re-set.

In GTM Preview mode, every event in the timeline has a Consent tab in the detail panel. Use it to verify consent state at each moment in the page lifecycle.

  1. Open GTM Preview, load your site in the same session
  2. In the Preview panel, click on the gtm.js event (the first event)
  3. Select the Consent tab
  4. Verify: all consent types should show denied (for EU users before CMP interaction)

After interacting with the consent banner, click on the next event in the timeline and verify the consent tab shows the updated state.

Each consent type will show one of:

  • granted — consent is active
  • denied — consent is denied
  • undefined — no default was set for this type (this is a problem)

undefined means your gtag('consent', 'default') call did not include this type. Tags may fire as if consent were granted for undefined types. Set explicit values for all seven types.

In Preview mode, click on any tag and look at the Consent section in the tag details. This shows:

  • Whether the tag checked consent
  • Which consent types were evaluated
  • Whether those types were granted or denied when the tag fired

If a tag fires with denied consent that it should have required, either the tag’s consent settings are misconfigured or the consent update arrived after the tag already fired.

The gcs parameter in GA4 hit URLs encodes consent state. Format: G{ads}{analytics} where each character is 1 (granted) or 0 (denied).

Common values:

  • G100 — both denied (default denied EU configuration working correctly)
  • G101 — analytics granted, ads denied (analytics-only consent)
  • G110 — ads granted, analytics denied (uncommon)
  • G111 — both granted (full consent)

What a correct denied-state hit looks like

Section titled “What a correct denied-state hit looks like”

In Advanced mode, denied-state hits are minimal. A correct ping looks like:

https://www.google-analytics.com/g/collect?v=2&tid=G-XXXXXXXX
&gcs=G100 ← consent state: both denied
&gcd=11l1l1l1 ← consent default configuration
&npa=1 ← non-personalized ads flag
&dma=1 ← digital markets act flag (EU)
&cid= ← empty: no client ID
&sid= ← empty: no session ID

Notably absent: _ga, en (event name), ep.* (event parameters), uid (user ID).

With full consent, hits include:

  • _p — page ID
  • _s — session number
  • cid — client ID (UUID from _ga cookie)
  • sid — session ID
  • en — event name
  • ep.* — event parameters

GA4’s DebugView shows real-time events from test devices. Use it to verify consent-gated events reach GA4 correctly.

  1. Activate GA4 DebugView for your device (either via GTM debug mode or by setting debug_mode: true in GA4 configuration)
  2. Load your site with consent granted
  3. Verify events appear in DebugView
  4. Revoke consent (or open a new incognito session with denied state)
  5. Verify that custom events do NOT appear in DebugView (only minimal pings should arrive in Advanced mode)

Use this checklist for every consent implementation:

Default state (before banner interaction):

  • No _ga cookie on first visit
  • No _gcl_au cookie on first visit
  • Network hits are absent (Basic mode) or contain gcs=G100 with no client ID (Advanced mode)
  • GTM Preview Consent tab shows denied for all required types on first event

Consent granted:

  • _ga cookie appears after accepting
  • _gcl_au cookie appears if Ads tags are configured
  • Network hits contain gcs=G111 with client ID present
  • GA4 events appear in DebugView

Consent denied:

  • No _ga or _gcl_au cookies after explicit rejection
  • Basic mode: zero network hits to Google collection
  • Advanced mode: hits continue with gcs=G100, no client ID

Returning visitor:

  • No consent banner shown on second visit with existing consent
  • Consent update appears early in GTM Preview timeline
  • _ga cookie has the same value as the previous session

Consent update timing:

  • GTM Preview shows consent update before first GA4 tag fires
  • No events in GTM Preview show undefined for any consent type

Non-Google tags:

  • Meta Pixel, LinkedIn, TikTok, etc. do not fire when advertising consent is denied
  • Verify via Network tab: no requests to pixel endpoints without consent

For high-stakes implementations, manual testing is insufficient. Consider:

Cypress / Playwright E2E tests: Write automated tests that assert cookie absence before consent, presence after, and correct network request patterns.

// Example Cypress test (pseudocode)
describe('Consent Mode', () => {
it('does not set _ga cookie before consent', () => {
cy.visit('/', { clearCookies: true });
cy.wait(2000); // Wait for CMP to load without interacting
cy.getCookie('_ga').should('be.null');
});
it('sets _ga cookie after accepting consent', () => {
cy.visit('/', { clearCookies: true });
cy.get('[data-testid="accept-all-consent"]').click();
cy.getCookie('_ga').should('not.be.null');
});
});

ObservePoint or Trackingplan: Purpose-built tools for automated consent compliance auditing across your pages.