Skip to main content
  1. Blog Post/

Test API . Unit testing for Google Tag Manager Custom Templates

5 min · 1504 words
Table of Contents

Google Tag Manager team has just added, in a stealth mode, a new Test API for the Custom Templates. This Test API will allow us to define some Unit Tests in order to be able to automate the testing of our template before publishing them.

You will find a new tab within the templates editor named "test" where you will be able to run some code before the tests start, and then add a set of unit test to run each time you want to test your library.

For those who are not much into the programming according to the Wikipedia a Unit Test is:

In computer programmingunit testing is a software testing method by which individual units of source code, sets of one or more computer program modules together with associated control data, usage procedures, and operating procedures, are tested to determine whether they are fit for use.[1]

https://en.wikipedia.org/wiki/Unit_testing

In essence, they're automated tests that make sure that a certain part of program execution, a unit, is working as expected. For example, if we were writing some unit tests for a page, we would be writing some Unit tests for example for checking if the contact form works, another to check if the add to card works, another one for testing if the search engine works, or if the current pages contain some specific elements.

According to Google Tag Manager support pages, each test can provide sample input values, mock function calls, and assert code behaviors. ( More details GTM Tests ) .

Unit Tests are also exported/imported, so this would help people that need to tweak any template to have their new code tested if the original author provided all the needed unit tests for testing the template.

Setting up the Unit Testing may look like a tedious and time-wasting task the first time you have to deal with it, but with the time you'll widely recover all the time invested ( NOT WASTED ) while setting up the tests.

This new Test API doesn't need to be initialized as the other ones since it's run within its own section of the editor and its looks it's already enabled there and it provided 5 new API's we can use to defined and run our unit tests:

assertApi Returns a matcher object that can be used to fluently make assertions about the given API.
assertThat The assertThat API is the one in charge to check if some specific value/variable matches the one we are expecting. GTM used Google's Truth library as a model for this. Having one asset failing doesn't affect other test cases.
fail This will force the test to fail and return a giving message if any is provided.
mock The mock API will allow us to override/replace the current sandbox API's behavior
runCode Calling this method will run the code for the current template,

I'm trying to show some simple examples of how these APIs work with examples. If you want to dig deeper I suggest you going to the official developer site for the Test API for a further read: https://developers.google.com/tag-manager/templates/api#runcode

assertAPI

assertApi(apiName)

This API will return a matcher object that we will able to use to make asserts against the given API.

For example, each tag execution must contain one call to gtmOnSuccess. Would make no sense having 2 calls to success within a single tag execution that could mean that we're firing it at some point when it's may not be true. Let's write an API assertion to check that gtmOnSuccess is being called just once.

This is our test current custom tag code

// dummmmyyyy template
data.gtmOnSuccess();
const log = require('logToConsole');
log('data =', data);

data.gtmOnSuccess();

There're not many details about the currently supported subjects for this assertion tests. I'll try to keep the following table updated as long as I find/test them out.

Available subjects list

wasCalled(number of calls)
wasNotCalled()

assertThat

This API will allow making the assertions against our variables or subjects. It has been designed based on the Truth library by Google, which is a library for running assertion tests for Java and Android. You can find more info in the official URL: https://truth.dev/

I'm not sure if all the subjects available on truth and that been currently modeled into the Test API For GTM, but you can find a list of officially provided one in the project GitHub repository, in case you're curious about it: https://github.com/google/truth/tree/master/core/src/main/java/com/google/common/truth

assertThat(actual, opt_message)

For this let's imagine that we have a variable that we expect to be returning "SIMO" as a string, ok?. For this test, we'll write a small variable that returns "DAVID" instead of our expected value in order to test an assertion.

// assetThat API Test
// No Needed Libraries
// return "SIMO"
return "DAVID";

Now, we'll write a simple test that run an assert to test that the value returned by the variable actually is "DAVID"

There're not many details about the currently supported matched subjects for this assertion tests. I'll try to keep the following table updated as long as I find/test them out.

Available subjects list

isEqualTo(expected)
isNotEqualTo(expected)

fail

fail(opt_message)

mock

This API will allow us to replace or override the current Sandbox API's functionality.
Let use the following Custom Variable Code

mock(apiName, returnValue);
// Mock API Test
// Add Needed Libraries
const log = require('logToConsole');
const encodeUri = require('encodeUri');

const testValue = encodeUri("http://www.google.es");
log('testValue=', testValue);

return testValue;

If we run variable we would expect to have the testValue to be the URL encoded, but we've mocked the encodeUri API in our test to return a fixed value:

runCode

This API actually takes care of running our template code. It optionally accepts a data object as a parameter and it will return a value if we're testing a Variable or undefined in any other case.

runCode(data)
runCode({
  measurementID: 'G-XXXXXXXX' 
});

Passing an object data will allow us to set some values for the current tag/variable without the need to manually fill the data into the template fields.

In the example above the data.measurementID variable will hold the value 'G-XXXXXXX' even w didn't populate our field.

Wrapping up

Google Tag Manager is giving us the perfect tool ( as a start ) for being able to have some fail-proof containers and code. AFAIK it seems the library is supporting some basic matchers, but I expect them to be expanded in the future ( or documented! ).