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.
Test setup
Section titled “Test setup”Before any testing:
- Open a fresh incognito/private browser window
- Navigate to your site
- Open DevTools (F12 or Cmd+Option+I)
- Keep the Network tab open with “Preserve log” enabled
- Filter network requests for
google-analyticsto isolate GA4 hits
For GTM Preview mode testing:
- Activate Preview mode in GTM for your container
- Enter Preview mode with the same fresh incognito browser session
- 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.
- Open incognito browser, load your site
- Do not interact with the consent banner
- Wait 5 seconds
- Check DevTools → Application → Cookies (your domain):
_gaand_ga_XXXXshould NOT exist - Check Network tab: requests to
google-analytics.com/g/collectshould either not exist (Basic mode) or includegcs=G100with no_ga=parameter (Advanced mode) - Check for
_gcl_aucookie: 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).
Test 2: Consent granted flow
Section titled “Test 2: Consent granted flow”- In the same fresh incognito session, click “Accept All” on the consent banner
- Immediately check cookies:
_gaand_ga_XXXXshould now appear - Check Network tab: new requests to
/g/collectshould appear withgcs=G111and_ga=parameter present - The
_gcl_aucookie 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.
Test 3: Consent denied flow
Section titled “Test 3: Consent denied flow”- Open a new incognito session
- When the banner appears, click “Reject All” or equivalent
- Check cookies: no
_ga,_ga_XXXX,_gcl_aucookies should appear after rejection - In Advanced mode: check that requests to
/g/collectcontinue but still showgcs=G100(denied state maintained) - In Basic mode: verify no requests to
/g/collectexist 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.
Test 4: Returning visitor with existing consent
Section titled “Test 4: Returning visitor with existing consent”- In a normal (non-incognito) browser, grant consent on your site
- Note which cookies were set and their values
- Close the tab completely
- Reopen your site
- Verify that no consent banner appears (CMP recognized returning consent)
- Check in GTM Preview mode: a consent update event should appear early in the event stream, before GA4 tags fire
- Check cookies:
_gacookie 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.
Test 5: Consent withdrawal
Section titled “Test 5: Consent withdrawal”- In a normal browser session with consent granted, open the CMP preference center
- Revoke all consent (without page reload, if your CMP supports this)
- Verify in DevTools: after withdrawal, subsequent user interactions should not generate new GA4 hits (or should generate denied-state hits in Advanced mode)
- Reload the page after withdrawal
- Verify no
_gacookie 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.
GTM Preview mode checks
Section titled “GTM Preview mode checks”Checking the Consent tab
Section titled “Checking the Consent tab”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.
- Open GTM Preview, load your site in the same session
- In the Preview panel, click on the
gtm.jsevent (the first event) - Select the Consent tab
- 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.
What to look for in the consent tab
Section titled “What to look for in the consent tab”Each consent type will show one of:
granted— consent is activedenied— consent is deniedundefined— 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.
Checking tag firing against consent state
Section titled “Checking tag firing against consent state”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.
Network tab deep dive
Section titled “Network tab deep dive”Decoding the gcs parameter
Section titled “Decoding the gcs parameter”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 IDNotably absent: _ga, en (event name), ep.* (event parameters), uid (user ID).
What a full hit looks like (with consent)
Section titled “What a full hit looks like (with consent)”With full consent, hits include:
_p— page ID_s— session numbercid— client ID (UUID from_gacookie)sid— session IDen— event nameep.*— event parameters
GA4 DebugView verification
Section titled “GA4 DebugView verification”GA4’s DebugView shows real-time events from test devices. Use it to verify consent-gated events reach GA4 correctly.
- Activate GA4 DebugView for your device (either via GTM debug mode or by setting
debug_mode: truein GA4 configuration) - Load your site with consent granted
- Verify events appear in DebugView
- Revoke consent (or open a new incognito session with denied state)
- Verify that custom events do NOT appear in DebugView (only minimal pings should arrive in Advanced mode)
Complete consent testing checklist
Section titled “Complete consent testing checklist”Use this checklist for every consent implementation:
Default state (before banner interaction):
- No
_gacookie on first visit - No
_gcl_aucookie on first visit - Network hits are absent (Basic mode) or contain
gcs=G100with no client ID (Advanced mode) - GTM Preview Consent tab shows
deniedfor all required types on first event
Consent granted:
-
_gacookie appears after accepting -
_gcl_aucookie appears if Ads tags are configured - Network hits contain
gcs=G111with client ID present - GA4 events appear in DebugView
Consent denied:
- No
_gaor_gcl_aucookies 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
-
_gacookie 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
undefinedfor 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
Automated testing approaches
Section titled “Automated testing approaches”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.