Important: This method has been replaced by the Experience OS Impact report. Use this article for only for help with experiments currently in progress using GCG.
The global control test is a method for measuring the overall impact of your experimentation program. The measurement is done using an A/B test that splits your overall traffic into two groups – users who receive personalized Dynamic Yield experiences and those who don’t – and compares them. This latter group is the global control group, or GCG.
This article describes several options for implementing GCG in API campaigns. Discuss with your account team which ones make sense for you.
Setting up a GCG requires the following steps:
Step 1: Allocate users to the GCG
Step 2: Add experiences to the GCG
Step 3: Set up reporting for the GCG
Step 1: Allocate users to the global control group
There are two options for assigning users to either the global control or Dynamic Yield experiences group.
Option A: Determine allocation in your codebase and pass it to Dynamic Yield (recommended)
- Implement code like the following examples within your codebase so that it runs before the first API request to the Dynamic Yield Choose endpoint. Check whether the user already has the "_dy_cs_gcg" cookie, and if not, decide which version of GCG they receive.
const express = require('express');
const cookieParser = require('cookie-parser');
const app = express();
const port = 3000;
app.get('/', (req, res) => {
res.send('Hello World!');
});
app.use(cookieParser());
app.use((req, res, next) => {
if (!req.cookies._dy_cs_gcg) {
const control_percentage = 5;
const isControl = Math.floor(Math.random() * 100) < control_percentage;
const gcValue = isControl ? 'Control Group' : 'Dynamic Yield Experiences';
res.cookie('_dy_cs_gcg', gcValue, { // store a new gcg value cookie
expires: new Date(Date.now() + 31540000000000), // Set a 1 year expiration for the new cookie
});
}
next();
});
app.listen(port, () => {
console.log(`Example app listening on port ${port}`);
});
<?php declare(strict_types=1);
class GroupType
{
/**
* Cookie name
*/
protected $_cookieName = '_dy_cs_gcg';
/**
* Group type
*/
protected $_groupType = null;
/**
* Get user group type
* @return string
*/
public function getGroupType(): string
{
if (!isset($_COOKIE[$this->_cookieName])) {
$controlPercentage = 5;
$isControl = rand(1, 100) < $controlPercentage;
$this->_groupType = $isControl ? 'Control Group' : 'Dynamic Yield Experiences';
setcookie($this->_cookieName, $this->_groupType, time() + (86400 * 365), '/');
} else {
$this->_groupType = $_COOKIE[$this->_cookieName];
}
return $this->_groupType;
}
}
from flask import Flask, render_template, make_response, request, Response
import requests
import random
import datetime
app = Flask(__name__)
COOKIE_KEY = '_dy_cs_gcg'
@app.before_request
def gcg_interceptor() -> None:
if not request.cookies.get(COOKIE_KEY):
control_percentage = 5
is_control = random.randint(1, 100) <= control_percentage
gc_value = 'Control Group' if is_control else 'Dynamic Yield Experiences'
expire_date = datetime.datetime.now() + datetime.timedelta(days=365)
request.gc_cookie = (COOKIE_KEY, gc_value, expire_date)
@app.route('/')
def render_demo_page() -> Response:
resp = make_response(render_template('demopage.html'))
if hasattr(request, 'gc_cookie'):
key, value, expiration = request.gc_cookie
resp.set_cookie(key, value, expires=expiration)
return resp
@app.route('/get-dy-content')
def get_dy_content() -> Response:
if (request.cookies.get(COOKIE_KEY) == 'Control Group'):
return make_response('', 204)
else:
# CALL TO DY API CAMPAIGN
- Use the value of gcValue in the pageAttributes option of all your choose requests to tell Dynamic Yield whether this user should be placed into the Control Group or the Dynamic Yield Experience group.
curl --request POST \
--url https://dy-api.com/v2/serve/user/choose \
--header 'content-type: application/json' \
--header 'DY-API-Key: baadc6ba740a352c9106dc7857a7eb9c' \
--data '{
"user": {
"dyid": "-4350463893986789401",
"dyid_server": "-4350463893986789401"
},
"session": {"dy": "ohyr6v42l9zd4bpinnvp7urjjx9lrssw"},
"selector": {"names": ["PDP Top Banner"]},
"context": {
"page": {
"type": "PRODUCT",
"data": ["7383723-010"],
"location": "https://sugoi-ne.com/men-pants/p7383723-010",
"locale": "en_US"
},
"device": {
"userAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",
"ip": "54.100.200.255"
},
"pageAttributes": { "globalControlGroup": "Dynamic Yield Experiences" }
},
}'
- In your response to the browser, set the correct value for the "_dy_cs_gcg" cookie as a response header with a 1-year expiration date, as shown in the NodeJS example. This cookie can eventually be used for any client-side experiences you plan to add to the GCG (see Adding client-side experiences to the GCG).
Option B: Make an API request for the GCG before making other API requests
This option is less streamlined, as it requires two separate API calls to Dynamic Yield for new users before rendering.
- Create a new Custom API campaign and name the campaign Global Control Test.
- Create an experience with the name Global Control Test.
- Create a variation called Dynamic Yield Experiences with the following JSON:
{"_dy_cs_gcg":"Dynamic Yield Experiences"}
- Create another variation called Control Group with the following JSON:
{ "_dy_cs_gcg" : "Control" }
- Set the allocation to 95% for Dynamic Yield Experiences and 5% for Control Group.
- Publish the campaign.
- Upon the first pageview, check whether the user already has the "_dy_cs_gcg" cookie, and if they don't, make an API request for only the Global Control Test campaign. Use the value of "_dy_cs_gcg" in the pageAttributes option of the choose request for the remaining campaigns on the page.
- In your response to the browser, set the correct value for the "_dy_cs_gcg" cookie as a response header, with a 1-year expiration date. This cookie can eventually be used for any client-side experiences you plan to add to the GCG (see Adding client-side experiences to the GCG).
Step 2: Add experiences to the GCG
Adding an experience to the GCG is different depending on whether it's an API or script experience.
API experiences
Go to the API experience you want to add to the global control test, and use the Custom Attribute targeting condition to target it to the Dynamic Yield Experiences group.
Client-side experiences
Step 1: Create the evaluator
The evaluator is used to target experiences to the Dynamic Yield Experience group or the Control Group.
-
Create an evaluator with the name Global Control Test Group.
-
Set the value type to String.
-
Set Expected Values to Dynamic Yield Experiences and Control Group.
-
Insert the code:
(function () {
return DYO.Q.Promise(function (resolve, reject) {
var GCG_STORAGE_NAME = '_dy_cs_gcg';
var STORAGE_TYPE = 'cookieStorage';
window.DY.CS = window.DY.CS || {};
if (window.DY.CS.inGlobalControl) {
resolve(window.DY.CS.inGlobalControl);
return true;
}
getGCCookie();
function getGCCookie() {
var GCValue = window.DYO.StorageUtils.get(GCG_STORAGE_NAME, [STORAGE_TYPE]);
if (GCValue) {
window.DY.CS.inGlobalControl = GCValue;
resolve(GCValue);
} else {
setTimeout(function () {
getGCCookie();
}, 50);
}
}
});
})();
-
Save the evaluator.
Step 2: Target your experiences to the evaluator
Step 3: Set up reporting for the GCG
If you decide on Option B: Make an API request for the GCG before making other API requests for GCG allocation, you'll use the experience created for allocation for your reporting on the global control test, so no other steps are needed.
However, if you go with the recommended Option A: Determine allocation in your codebase and pass it to Dynamic Yield, create a Custom API campaign using the following settings to set up reporting for your GCG test:
- Name the campaign Global Control Test.
- Create an experience with the name Dynamic Yield Experiences.
- Target this experience using the Custom Attribute to Dynamic Yield Experiences.
- Add one variation with 100% traffic allocation containing the following JSON code:
{ "Dynamic Yield Experiences" : "true" }
- Create a second experience with the name Control Group.
- Target this experience using the Custom Attribute to Control Group.
- Add one variation with 100% traffic allocation containing the following JSON code:
{"Control" : "true" }
- Publish.
- Be sure to call this API campaign at least once per session for each user. You don't need to use the response of this call for anything, it's called to register an impression for this campaign so that there's tracking for overall GCG performance.