Last updated: March 12, 2026

Automated Tests for GTM Data Layer Push Events

Automated Tests or Manual Tests for Your Data Layer Events?

Choosing between manual and automated testing for your Data Layer events depends on your scale and requirements. Let’s explore both approaches to help you make an informed decision.

Manual Testing Methods

When initially setting up your DataLayer events, manual testing is the fastest way to verify your implementation before investing in automation.

1

Verify GTM is Loaded

Open Chrome DevTools by pressing F12 or right-clicking and selecting Inspect.

Click the Console tab. Type window.google_tag_manager to confirm GTM is loaded and see which container IDs are active on the page. If this returns undefined, GTM hasn’t loaded at all; check for script blockers or a missing snippet.

Then type window.dataLayer to see the full array of events pushed so far on the current page. Expand any object to inspect its properties against your expected schema.

Note: If you’re using a custom Data Layer name, use window.yourCustomName instead.

2

Filter Specific Events in Console

Instead of scrolling through the full dataLayer array, filter for the specific event you want to validate:

// Show all ecommerce pushes
window.dataLayer.filter(e => e.ecommerce)

// Show a specific event
window.dataLayer.filter(e => e.event === 'purchase')

// Show the last event pushed
window.dataLayer[window.dataLayer.length - 1]

Check that the ecommerce object matches the expected schema: correct field names, numeric values for price and value, and a non-empty items array.

3

Cross-check GA4 Network Requests

Click the Network tab in DevTools. In the filter box, type collect to show only GA4 requests fired by your GTM tags.

Select a request, open the Payload tab, and find Query String Parameters to verify the event actually reached GA4 with the correct parameters.

Look at the Status column:

  • 2xx (shown in green) = Success
  • 4xx (red) = Bad request
  • 5xx (red) = Server error
  • Failed (red) = Network error, ad blocker, or Google Ads account suspended. Usually with error code “-1”

Using Chrome Extension Debuggers

Browser extensions like AH Debugger significantly streamline the debugging process, automatically validating the schema without requiring you to dig through raw JSON payloads manually.

1

Install and Enable AH Debugger

  1. Install AH Debugger extension from Chrome Web Store,

  2. Click on the puzzle icon on the top right of your browser,

  3. Optionally pin the AH Debugger extension for easy access.

  4. Click on the extension icon

  5. Enable the debugger by clicking on the red toggle

Pin AH Debugger extension
Enable Debugger
2

View DataLayer Events in Console Tab

  1. Open Chrome DevTools by pressing F12 or right-clicking anywhere and selecting Inspect.

  2. Click the Console tab in DevTools and trigger the event on your website.

  3. Check for the event name you want to validate, click to expand it, and check the pushed parameters.

3

View Event in AH Debugger Panel

  1. Open Chrome DevTools by pressing F12 or right-clicking anywhere and selecting Inspect.

  2. Click on AH Debugger panel. If not present, click on the double-arrow on the right and from the dropdown click on AH Debugger.

  3. Use Global and Local search to find specific parameters you want to validate.

  4. Start validating the parameters to ensure they match the expected DataLayer schema.

  • Built-in Tests: If any are present, you will see the results on the right side. Click on the number and a modal with the results will show up.

GA4 Ecommerce DataLayer Push Reference

Before you can test whether your DataLayer pushes are correct, you need to know what “correct” looks like. Below are the exact schemas for every GA4 ecommerce event as defined in Google’s documentation.

One rule that applies to all events: always clear the previous ecommerce object before pushing a new one. Failing to do this causes data from previous events to bleed into subsequent ones.

// Always do this before any ecommerce push
dataLayer.push({ ecommerce: null });

Browsing & Discovery

view_item_list: User sees a list of products

dataLayer.push({ ecommerce: null });
dataLayer.push({
  event: "view_item_list",
  ecommerce: {
    item_list_id: "related_products",   // optional but recommended
    item_list_name: "Related Products", // optional but recommended
    items: [
      {
        item_id: "SKU_12345",           // required (or item_name)
        item_name: "Stan and Friends Tee",
        affiliation: "Google Store",
        coupon: "SUMMER_FUN",
        discount: 2.22,
        index: 0,                       // position in the list
        item_brand: "Google",
        item_category: "Apparel",
        item_category2: "Adult",
        item_list_id: "related_products",
        item_list_name: "Related Products",
        item_variant: "green",
        price: 9.99,                    // must be a number, not a string
        quantity: 1
      }
    ]
  }
});

select_item: User clicks a product from a list

dataLayer.push({ ecommerce: null });
dataLayer.push({
  event: "select_item",
  ecommerce: {
    item_list_id: "related_products",
    item_list_name: "Related Products",
    items: [
      {
        item_id: "SKU_12345",
        item_name: "Stan and Friends Tee",
        index: 0,
        price: 9.99,
        quantity: 1
      }
    ]
  }
});

view_item: User views a product detail page

dataLayer.push({ ecommerce: null });
dataLayer.push({
  event: "view_item",
  ecommerce: {
    currency: "USD",   // required
    value: 9.99,       // required: value of the item viewed, not cart total
    items: [
      {
        item_id: "SKU_12345",
        item_name: "Stan and Friends Tee",
        item_brand: "Google",
        item_category: "Apparel",
        item_variant: "green",
        price: 9.99,
        quantity: 1
      }
    ]
  }
});

Cart Interactions

add_to_cart: User adds item(s) to cart

dataLayer.push({ ecommerce: null });
dataLayer.push({
  event: "add_to_cart",
  ecommerce: {
    currency: "USD",  // required
    value: 19.98,     // required: price × quantity of items being added
    items: [
      {
        item_id: "SKU_12345",
        item_name: "Stan and Friends Tee",
        item_brand: "Google",
        item_category: "Apparel",
        item_variant: "green",
        price: 9.99,
        quantity: 2   // value above should reflect this quantity
      }
    ]
  }
});

remove_from_cart: User removes item(s) from cart

dataLayer.push({ ecommerce: null });
dataLayer.push({
  event: "remove_from_cart",
  ecommerce: {
    currency: "USD",
    value: 9.99,
    items: [
      {
        item_id: "SKU_12345",
        item_name: "Stan and Friends Tee",
        price: 9.99,
        quantity: 1
      }
    ]
  }
});

view_cart: User views the cart page

dataLayer.push({ ecommerce: null });
dataLayer.push({
  event: "view_cart",
  ecommerce: {
    currency: "USD",
    value: 22.98,   // total value of all items currently in cart
    items: [
      {
        item_id: "SKU_12345",
        item_name: "Stan and Friends Tee",
        price: 9.99,
        quantity: 1
      },
      {
        item_id: "SKU_67890",
        item_name: "Google Grey Women's Tee",
        price: 12.99,
        quantity: 1
      }
    ]
  }
});

Checkout Process

Important: GA4 does not use numbered checkout steps like Universal Analytics did. You must use these exact event names or the default Checkout Journey exploration report will remain empty.

begin_checkout: User starts the checkout process

dataLayer.push({ ecommerce: null });
dataLayer.push({
  event: "begin_checkout",
  ecommerce: {
    currency: "USD",
    value: 22.98,
    coupon: "SUMMER_FUN",  // optional
    items: [ /* all items in cart */ ]
  }
});

add_shipping_info: User selects a shipping method

dataLayer.push({ ecommerce: null });
dataLayer.push({
  event: "add_shipping_info",
  ecommerce: {
    currency: "USD",
    value: 22.98,
    coupon: "SUMMER_FUN",
    shipping_tier: "Ground",  // suggested: e.g. "Ground", "Air", "Next-day"
    items: [ /* all items in cart */ ]
  }
});

add_payment_info: User selects a payment method

dataLayer.push({ ecommerce: null });
dataLayer.push({
  event: "add_payment_info",
  ecommerce: {
    currency: "USD",
    value: 22.98,
    coupon: "SUMMER_FUN",
    payment_type: "Credit Card",  // suggested: e.g. "Credit Card", "PayPal"
    items: [ /* all items in cart */ ]
  }
});

purchase: Transaction completed

dataLayer.push({ ecommerce: null });
dataLayer.push({
  event: "purchase",
  ecommerce: {
    transaction_id: "T_12345",  // required: must be unique per transaction
    affiliation: "Online Store",
    value: 28.97,               // required: total revenue inc. tax & shipping
    tax: 4.90,
    shipping: 5.99,
    currency: "USD",            // required
    coupon: "SUMMER_SALE",
    items: [
      {
        item_id: "SKU_12345",
        item_name: "Stan and Friends Tee",
        affiliation: "Online Store",
        coupon: "SUMMER_FUN",
        discount: 2.22,
        item_brand: "Google",
        item_category: "Apparel",
        item_variant: "green",
        price: 9.99,
        quantity: 2
      }
    ]
  }
});

refund: Order refunded (full or partial)

dataLayer.push({ ecommerce: null });
dataLayer.push({
  event: "refund",
  ecommerce: {
    transaction_id: "T_12345",  // required
    affiliation: "Online Store",
    value: 28.97,
    tax: 4.90,
    shipping: 5.99,
    currency: "USD",
    coupon: "SUMMER_SALE",
    items: [
      // For a full refund: leave items array empty []
      // For a partial refund: include only the items being refunded
      {
        item_id: "SKU_12345",
        item_name: "Stan and Friends Tee",
        price: 9.99,
        quantity: 1
      }
    ]
  }
});

The items Array: Common Rules for All Events

ParameterRequiredNotes
item_idYes**Required if item_name is absent
item_nameYes**Required if item_id is absent
priceSuggestedMust be a number, not a string
quantitySuggestedDefaults to 1 if omitted
item_categorySuggestedUp to item_category5 supported
item_brandSuggested
item_variantSuggested

The Case for Automation

If you’re reading this, you probably understand the time investment required for proper Data Layer regression testing.

Whether you use debugger extensions like AH Debugger or rely on window.dataLayer in your console, manual testing becomes difficult to scale. Consider these challenges:

  • Multiple Websites: How do you efficiently test across different properties?
  • Event Complexity: What happens when you have dozens of events and numerous user journeys?
  • Consistency: How do you ensure testing coverage remains comprehensive as your implementation grows?

Why Not DIY Automation?

If you’re technically inclined, you might consider building your own solution using JavaScript. While possible, this approach has significant drawbacks:

  • Each website requires custom implementation
  • Maintenance becomes tedious as requirements evolve
  • Basic checks (like verifying GTM loads) are relatively simple, but comprehensive event validation is complex

The AI Testing Trap

Using AI for Data Layer testing might seem attractive, but it introduces problems:

  • Token Costs: Each event validation requires substantial context, leading to high token consumption and costs that scale with your event count
  • Reliability: AI hallucinations can produce false positives or miss critical issues
  • Consistency: Results may vary between test runs

Setting Up Automated Tests with AssertionHub

AssertionHub eliminates the need for coding knowledge while providing comprehensive Data Layer testing. You can create reusable tests that work across multiple websites without recreating them for each property.

AssertionHub Continuous Analytics Monitoring Flow

Built-in Browser Recorder

AssertionHub includes a built-in recorder. Enter your website URL, hit Start Recording, and navigate as a real user: add products to cart, go through checkout, complete a purchase. Every interaction is automatically added to the step list.

You can also describe steps in plain text and let AI handle the rest: type “add the first product to cart” and the AI picks the right element at execution time. No DOM knowledge needed.

When a site update breaks a selector, an AI fallback generates an alternative automatically; you review and decide whether to save it.

AssertionHub Built-in Recorder

How to Start Automating Your Data Layer Events

After starting your free trial, follow these steps to record your first user journey:

Think of it like simulating an actual user’s path through your website.

  1. Create New User Journey: Click “New User Journey”
  2. Record Your Session:
    • Enter the website URL to record
    • Start your recording
    • The right panel displays detected Google Tag Manager Data Layer push events
  3. Select Events to Monitor:
    • Choose the events you want to track
    • Click to create a test for each event: every captured metric is pre-filled, no guessing field names
  4. AI-Assisted Test Creation:
    • Not sure which metrics matter? Describe what you want to validate in plain text
    • The AI selects the right metrics; you review and confirm
  5. Finalize Recording:
    • Complete your recording
    • Add the test for each Data Layer event on the step where you expect it to fire
  6. Run and Review:
    • Execute your user journey
    • Review the test results
AssertionHub Test Creation from Captured DataLayer Event
AssertionHub User Journey Test Results

Optional: Continuous Monitoring

For ongoing validation, you can:

  • Schedule user journeys to run daily
  • Add your email for notifications
  • Integrate with Slack for team alerts

This ensures your Data Layer implementation remains reliable as your website evolves, without manual intervention.

Frequently Asked Questions

How often should I test my GTM Data Layer implementation?
For manual testing, test during initial implementation, after major changes and at least on a monthly-basis.

For automated testing, set to run tests daily or on every deployment.
What's the difference between manual and automated Data Layer testing?
Manual testing involves checking events in your browser console or with debugger extensions - it's quick for one-off checks but time-consuming for comprehensive testing.

Automated testing runs custom and built-in tests automatically, catching issues across multiple user journeys without manual intervention.
Can I test GTM Data Layer events without coding skills?
Yes. For manual testing, you can use window.dataLayer in your browser console or extensions like AH Debugger. For automated testing, tools like AssertionHub let you create tests without writing code using a visual interface.
How do I know if a Data Layer event fired correctly?
Check three things: (1) The event appears in your Data Layer with the correct event name, (2) All required parameters are present with correct values, (3) The event fires at the right moment in the user journey.

Extensions like AH Debugger make this verification process much faster.
Do I need to test every single Data Layer event?
Focus on business-critical events first: conversions, add to cart, form submissions, and user authentication. Then expand to secondary events. Automated testing makes it feasible to test everything, while manual testing should prioritize high-impact events.
How long does it take to set up automated Data Layer testing?
With no-code tools like AssertionHub, you can record your first user journey and create tests in under 10 minutes. Setting up comprehensive coverage for all critical user journeys typically takes 1-2 hours, compared to hours of manual testing for each release.
Can automated testing catch all Data Layer issues?
It depends on your test coverage. With comprehensive automated tests covering all user journeys and edge cases, you'll catch virtually all issues: missing events, incorrect parameters, duplicates, and timing problems. Manual testing is mainly needed to investigate unexpected failures or test new scenarios you haven't automated yet.

You might be interested in

Powered by beluacode Logo