Optimizely will be sunsetting Full Stack Experimentation on July 29, 2024. See the recommended Feature Experimentation migration timeline and documentation.

Dev GuideAPI Reference
Dev GuideAPI ReferenceUser GuideLegal TermsGitHubDev CommunityOptimizely AcademySubmit a ticketLog In
Dev Guide

Run feature tests with variables

Feature variables enable you to avoid hard-coding variables in your application. Instead of updating the variables by deploying, you can update them remotely in the Optimizely app. For more information about what feature variables are, see Feature variables.

Once you have run a basic feature test (see Run basic feature tests), you can increase the power of your experiments by adding remote feature configurations, or feature variables.

Setup Overview

  1. Create and configure a basic feature test. See Run basic feature tests.
  2. To use feature variables in a feature test, first create a variable key with a default value for the feature in the Optimizely app. See Create feature variables.
  3. Add new values for the variable in the feature test in the Optimizely app. See Run basic feature tests.
  4. Integrate the example code with your application. See Implement a feature variable. Make sure the events you want to measure are properly instrumented for your experiment.

Add variables to a feature test

In the Optimizely app, take these steps to add variables to your feature test:

  1. (Prerequisite): Create a feature variable. See Create feature variables.
  2. Navigate to the Experiments tab. Select the feature test that uses the feature for which you just created a variable.
  3. Experiment variations auto-populate with any feature variables you created for that feature. For each variation, assign the values you want to test to the variable keys. The common practice is to leave one variation with the feature flag off as a a control. Users exposed to that control variation get the default variable values.
  4. (Optional) Edit the Variation Key and Description fields under Variations.
  5. Adjust the Traffic Distribution as needed. Optimizely automatically splits traffic evenly across all variations in an experiment by default.
  6. Toggle variations On.
606

Assign new values to the feature variable in the experiment

📘

Note

Test configurations evaluate before rollouts. If you run a feature test and a rollout at the same time, rules for feature tests are evaluated first. Feature rollouts are evaluated second. For more information, see Interactions between feature tests and rollouts.

Implement a feature variable

You need to integrate the feature variable with your application code, so that Optimizely can assign the correct variable value to a given user. Take these steps:

  1. Copy the sample GetFeatureVariable code generated in the dashboard for your feature variable.

  2. Edit your code so that, if the experimental feature is enabled for a given user, your application uses the output of GetFeatureVariable to configure your user's experience. In other words, you enable Optimizely to dynamically assign variable values to users if the feature flag is active.

In this example, the experiment uses a sorting algorithm and with pagination for displaying products to a user.

/**
 * Look for getFeatureVariableString() and getFeatureVariableInteger() 
 * in the following code.
 *
 * Fetch feature flag value for the "sorting_algorithm" feature.
 * Then specify default value for feature config variable.
 * Here we use two different variable values, essentially creating
 * a multi-variate test so we can test out the combinatorial effects
 * of the various configurations
 */
Boolean isSortingAlgoEnabled = optimizelyClient.isFeatureEnabled(
                                 "sorting_algorithm", 
                                 "user-1"
                               );
String sortingProperty = "name";
Integer pageLimit = 10;
if (isSortingAlgoEnabled) {
  /**
   * If feature is enabled, fetch dynamic feature config value to toggle
   * the property used to sort items. The value of the variable is determined
   * by the value specified by the Feature Test or Feature Rollout that 
   * "user-1" was assigned.
   */
  sortingProperty = optimizelyClient.getFeatureVariableString(
                      "sorting_algorithm", 
                      "sorting_propery", 
                      "user-1"
                    );
  pageLimit = optimizelyClient.getFeatureVariableInteger(
                "sorting_algorithm", 
                "page_limit", 
                "user-1"
              );
}

/** 
 * Fetch products and pass the sorting property as well as the number
 * of products to fetch
 */
ArrayList<Product> products = productProvider.get(sortingProperty, pageLimit);
/**
 * Look for GetFeatureVariableString() and GetFeatureVariableInteger() 
 * in the following code.
 *
 * Fetch feature flag value for the "sorting_algorithm" feature.
 * Then specify default value for feature config variable.
 * Here we use two different variable values, essentially 
 * creating a multi-variate test so we can test out the 
 * combinatorial effects of the various configurations
 */
var optimizelyClient = new Optimizely(datafile);
bool isSortingAlgoEnabled = optimizelyClient.IsFeatureEnabled(
                                 "sorting_algorithm", 
                                 "user-1"
                               );
string sortingProperty = "name";
int? pageLimit = 10;
if (isSortingAlgoEnabled)
{
    /**
     * If feature is enabled, fetch dynamic feature config value to toggle
     * the property used to sort items. The value of the variable is determined
     * by the value specified by the Feature Test or Feature Rollout that  
     * "user-1" was assigned.
     */
    sortingProperty = optimizelyClient.GetFeatureVariableString(
                        "sorting_algorithm", 
                        "sorting_propery", 
                        "user-1"
                      );
    pageLimit = optimizelyClient.GetFeatureVariableInteger(
                  "sorting_algorithm", 
                  "page_limit", 
                  "user-1"
                );
}

/**
 * Fetch products and pass the sorting property as well as the number of 
 * products to fetch
 */
ArrayList<Product> products = productProvider.Get(sortingProperty, pageLimit);
/**
 * Look for getFeatureVariableString() and getFeatureVariableInteger() 
 * in the following code.
 *
 * Fetch feature flag value for the "sorting_algorithm" feature.
 * Then specify default value for feature config variable.
 * Here we use two different variable values, essentially creating
 * a multi-variate test so we can test out the combinatorial effects
 * of the various configurations
 */

Boolean isSortingAlgoEnabled = optimizelyClient.isFeatureEnabled(
                                 "sorting_algorithm", 
                                 "user-1"
                               );
String sortingProperty = "name";
Integer pageLimit = 10;
if (isSortingAlgoEnabled) {
  /**
   * If feature is enabled, fetch dynamic feature config value to toggle
   * the property used to sort items. The value of the variable is determined
   * by the value specified by the Feature Test or Feature Rollout that 
   * "user-1" was assigned.
   */
  sortingProperty = optimizelyClient.getFeatureVariableString(
                      "sorting_algorithm", 
                      "sorting_propery", 
                      "user-1"
                    );
  pageLimit = optimizelyClient.getFeatureVariableInteger(
                "sorting_algorithm", 
                "page_limit", 
                "user-1"
              );
}

/** 
 * Fetch products and pass the sorting property as well as the number
 * of products to fetch
 */
ArrayList<Product> products = productProvider.get(sortingProperty, pageLimit);
/**
 * Look for getFeatureVariableString() and getFeatureVariableInteger()
 * in the following code.
 *
 * Fetch feature flag value for the 'sorting_algorithm' feature.
 * Then specify default value for feature config variable.
 * Here we use two different variable values, essentially creating
 * a multi-variate test so
 * we can test out the combinatorial effects of the various 
 * configurations.
 */
const isSortingAlgoEnabled = optimizelyClient.isFeatureEnabled(
                               'sorting_algorithm', 
                               'user-1'
                             )
let sortingProperty = 'name'
let pageLimit = 10
if (isSortingAlgoEnabled) {
  /**
   * If feature is enabled, fetch dynamic feature config value to toggle
   * the property used to sort items. The value of the variable is determined
   * by the value specified by the Feature Test or Feature Rollout that 
   * 'user-1' was assigned.
   */
  sortingProperty = optimizelyClient.getFeatureVariableString(
                      'sorting_algorithm', 
                      'sorting_propery', 
                      'user-1'
                    )
  pageLimit = optimizelyClient.getFeatureVariableInteger(
                'sorting_algorithm', 
                'page_limit', 
                'user-1'
              )
}

/** 
 * Fetch products and pass the sorting property as well as the number of 
 * products to fetch.
 */
const products = productProvider.get(sortingProperty, pageLimit)
/**
 * Look for getFeatureVariableString() and getFeatureVariableInteger()
 * in the following code.
 *
 * Fetch feature flag value for the 'sorting_algorithm' feature.
 * Then specify default value for feature config variable.
 * Here we use two different variable values, essentially creating
 * a multi-variate test so
 * we can test out the combinatorial effects of the various
 * configurations.
 */
const isSortingAlgoEnabled = optimizelyClient.isFeatureEnabled(
  "sorting_algorithm",
  userId
);
let sortingProperty = "name";
let pageLimit = 10;
if (isSortingAlgoEnabled) {
  /**
   * If feature is enabled, fetch dynamic feature config value to toggle
   * the property used to sort items. The value of the variable is determined
   * by the value specified by the Feature Test or Feature Rollout that
   * 'user-1' was assigned.
   */
  sortingProperty = optimizelyClient.getFeatureVariableString(
    "sorting_algorithm",
    "sorting_propery",
    userId
  );
  pageLimit = optimizelyClient.getFeatureVariableInteger(
    "sorting_algorithm",
    "page_limit",
    userId
  );
}

/**
 * Fetch products and pass the sorting property as well as the number of
 * products to fetch.
 */
// TODO: implement me
// const products = productProvider.get(sortingProperty, pageLimit);
/**
 * Look for getFeatureVariableString() and getFeatureVariableInteger() 
 * in the following code.
 *
 * Fetch feature flag value for the "sorting_algorithm" feature.
 * Then specify default value for feature config variable.
 * Here we use two different variable values, essentially creating
 * a multi-variate test so we can test out the combinatorial effects
 * of the various configurations
 */

BOOL isSortingAlgoEnabled = [optimizely isFeatureEnabledWithFeatureKey: @"sorting_algorithm"
                                                 userId:@"user-1"];

NSString *sortingProperty = @"name";
NSNumber *pageLimit = @(10);
if (isSortingAlgoEnabled) {
  	/**
   	 * If feature is enabled, fetch dynamic feature config value to toggle
     * the property used to sort items. The value of the variable is determined
     * by the value specified by the Feature Test or Feature Rollout that 
     * "user-1" was assigned.
     */
    sortingProperty = [optimizely getFeatureVariableStringWithFeatureKey: @"sorting_algorithm"
																			variableKey:@"sorting_propery"
																			userId:@"user-1"
                       								error:nil];

  	if (sortingProperty == nil) {
			// error
		}
  
    pageLimit = [optimizely getFeatureVariableIntegerWithFeatureKey:@" sorting_algorithm"
																			variableKey:@"page_limit"
     																	userId:@"user-1"
      																error:nil];
  
    if (pageLimit == nil) {
			// error
		}
}

/** 
 * Fetch products and pass the sorting property as well as the number
 * of products to fetch
 */
NSArray *products = [productProvider getWithSortingProperty: sortingProperty,
                       												pageLimit: pageLimit.intValue)
/**
 * Look for get_feature_variable_string() and 
 * get_feature_variable_integer() in the following code.
 * 
 * Fetch feature flag value for the 'sorting_algorithm' feature.
 * Then specify default value for feature config variable.
 * Here we use two different variable values, essentially creating
 * a multi-variate test so we can test out the combinatorial effects
 * of the various configurations.
 */
$isSortingAlgoEnabled = $optimizelyClient->isFeatureEnabled(
                          'sorting_algorithm', 
                          'user-1'
                        );
$sortingProperty = 'name';
$pageLimit = 10;
if ($isSortingAlgoEnabled) {
 /**
  * If feature is enabled, fetch dynamic feature config value to toggle
  * the property used to sort items. The value of the variable is determined
  * by the value specified by the Feature Test or Feature Rollout that 'user-1'
  * was assigned.
  */
  $sortingProperty = $optimizelyClient->get_feature_variable_string(
                       'sorting_algorithm', 
                       'sorting_propery', 
                       'user-1'
                     );
  $pageLimit = $optimizelyClient->get_feature_variable_integer(
                 'sorting_algorithm', 
                 'page_limit', 
                 'user-1'
               );
}

/** 
 * Fetch products and pass the sorting property as well as the number of
 * products to fetch.
 */
$products = $productProvider->get($sortingProperty, $pageLimit);
# Look for get_feature_variable_integer() and
# get_feature_variable_string() in the following code.

# Fetch feature flag value for the 'price_filter' algorithm feature.
# Then specify default value for feature config variable.
# Here we use two different variable values, essentially creating
# a multi-variate test so we can test out the combinatorial effects
# of the various configurations.

attributes = {'plan_type': 'silver'}

is_price_algo_enabled = optimizely_client.is_feature_enabled(
    'price_filter_attrib',
    user_id,
    attributes
)

min_price = 1000
price_limit = 'high'
if is_price_algo_enabled:
    # If feature is enabled, fetch dynamic feature config value to toggle
    # the property used to price items. The value of the variable is determined
    # by the value specified by the Feature Test or Feature Rollout that
    # user was assigned.
    min_price = optimizely_client.get_feature_variable_integer(
        'price_filter_attrib',
        'min_price',
        user_id,
        attributes
    )
    price_limit = optimizely_client.get_feature_variable_string(
        'price_filter_attrib',
        'price_limit',
        user_id,
        attributes
    )
# Look for get_feature_variable_string() and get_feature_variable_integer()
# in the following code.

# Fetch feature flag value for the 'sorting_algorithm' feature.
# Then specify default value for feature config variable.
# Here we use two different variable values, essentially creating a 
# multi-variate test so we can test out the combinatorial effects of
# the various configurations.
is_sorting_algo_enabled = optimizely_client.is_feature_enabled(
                            'sorting_algorithm', 
                            'user-1'
                          )
sorting_property = 'name'
page_limit = 10
if is_sorting_algo_enabled
  # If feature is enabled, fetch dynamic feature config value to toggle
  # the property used to sort items. The value of the variable is determined
  # by the value specified by the Feature Test or Feature Rollout that 
  # 'user-1' was assigned.
  sorting_property = optimizely_client.get_feature_variable_string(
                       'sorting_algorithm', 
                       'sorting_propery', 
                       'user-1'
                     )
  page_limit = optimizely_client.get_feature_variable_integer(
                 'sorting_algorithm', 
                 'page_limit', 
                 'user-1'
               )
end

# Fetch products and pass the sorting property as well as the number of 
# products to fetch.
products = product_provider.get(sorting_property, page_limit)
/**
 * Look for getFeatureVariableString() and getFeatureVariableInteger() 
 * in the following code.
 *
 * Fetch feature flag value for the "sorting_algorithm" feature.
 * Then specify default value for feature config variable.
 * Here we use two different variable values, essentially creating
 * a multi-variate test so we can test out the combinatorial effects
 * of the various configurations
 */
 
do {
  let isSortingAlgoEnabled = optimizely.isFeatureEnabled(featureKey: "sorting_algorithm",
                                                    	userId: "user-1")
                                                      
  var sortingProperty = "name"
	var pageLimit = 10
	if isSortingAlgoEnabled {
  	/**
   	 * If feature is enabled, fetch dynamic feature config value to toggle
     * the property used to sort items. The value of the variable is determined
     * by the value specified by the Feature Test or Feature Rollout that 
     * "user-1" was assigned.
     */
 		sortingProperty = try optimizely.getFeatureVariableString(featureKey: "sorting_algorithm",
																								variableKey: "sorting_propery",
																								userId: "user-1")
                                                                                		pageLimit = try optimizely.getFeatureVariableInteger(featureKey: "sorting_algorithm",
																								variableKey: "page_limit",
																								userId: "user-1")
	}

	/** 
   * Fetch products and pass the sorting property as well as the number
   * of products to fetch
   */
	let products = productProvider.get(sortingProperty, pageLimit)

} catch {
   // error
}