A/B testing ([legacy](🔗)) lets editors create variations for a number of page elements (blocks, images, content, buttons, and form fields), then compare which variation performs best. It measures the number of conversions from the original (control) versus the variation (challenger). The one generating the most conversions during the test period is promoted to the design for that page. A/B testing has several predefined conversion goals, and you can also create custom conversion goals.
See also [Delivery & Experimentation](🔗) for information on the **Optimizely delivery and experimentation platform** for websites, mobile apps, smart devices, and back-end code. With this, you can A/B test everything from search results and promotions, to recommendations and payment options. You can also A/B test user interface variations, to optimize and personalize website messaging.

## Requirements
No additional license fee.[](🔗)
An Optimizely Content Management System (CMS) installation.
See [App platform compatibility](🔗) for package and version information.Â
## Install
[Install through GitHub](🔗)
## Documentation
[Optimizely A/B testing (legacy) - user guide](🔗)
Blog: [The A/B testing addon for Optimizely CMS is now open-source](🔗) by Kevin Shea
## Technical limitation
The underlying tool used by A/B testing to render preview images of the changes under test has the following technical limitations:
Media queries defined on link elements are ignored
Media queries defined on import rules are ignored
This limitation results in the styles, which would ordinarily be restricted to particular types of media, being applied to screen media and therefore appearing in the preview images that are generated.
However, the functionality respects media queries that are defined directly within the CSS. So, a workaround for these situations is to wrap the existing contents of the linked CSS source file in a print media query.
For example, let's imagine that a file named _print.css_ is linked to a page with a media attribute for print.
And imagine that _print.css_ currently contains the following:
Applying such a workaround would require you to simply wrap the existing statements in a media query:
The attribute can remain on the element as well, if that is preferable for other technical concerns.
## Key performance indicator
A key performance indicator (KPI) in Optimizely records when a visitor on a website performs a desired action, such as clicking on an ad or a button, or completing a sale. The functionality is used for example in A/B testing of content.
You can create custom KPIs, using goal objects in the KPI framework, to use in Optimizely A/B testing or in any other package that relies on creating instance-based goal objects.
To create a custom KPI, implement the `IKpi
` interface located in the `EPiServer.Marketing.KPI.Manager.DataClass
` namespace.
### Cookie usage in A/B testing
The AB testing package has one cookie per test the user visits in the format of:
**EPI-MAR-<Content GUID>**
"Content GUID" is the Optimizely GUID for the content under test. Inside the cookie, the state of the visitor against the running test is stored. That is, the version the visitor should see if returning to a test item while the test is still running, if they have yet to view the content in question, and the various goals the visitor has converted on, or has yet to convert on.
Cookie Name | Purpose |
EPI-MAR-{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx:xx} | Analytical/performance functionality. Records a visitors interaction with a running website optimization test, to ensure that a visitor has a consistent experience. Persistent (variable according the test). Typically optimization tests are short-lived (one week).The cookie is removed after the test has completed. |
See [Cookies](🔗) for information about other cookies in the Optimizely platform.
### IKpi methods
 IKpi methods |  Description |
`Guid Id ` | The Id of the Kpi instance. Used to identify between multiple instances of the same type of Kpi. |
`string FriendlyName ` | Display name of the Kpi. Used for any calling package to identify the KPI type in a user-friendly manner. |
`string Description ` | Describes what the KPI does so that it can be displayed to the user. |
`string UiMarkup ` | The HTML form inputs required to create an instance of the KPI. The `Validate ` method uses this to store relevant information the KPI needs to properly evaluate. Inputs require a name attribute to retrieve the value and pass it to the Validate method. |
`string UiReadOnlyMarkup ` | The HTML fragment used for displaying the user-generated input that created the instance of the KPI. |
`void Validate(Dictionary\<string, string> kpiData) ` | Reads a dictionary of input generated from the `UiMarkup ` to create a KPI instance. Keys in the kpiData Dictionary match the name property of the inputs in the UiMarkup. Store values that need to be retrieved later for use in the Evaluate method as class properties. Generate a `KpiValidationException ` when the data is not in a valid format so that the calling method can handle validation errors. |
`event EventHandler EvaluateProxyEvent ` | Called by packages using this Kpi, the `EvaluateProxyEvent ` attaches the passed-in event proxy to the .Net event the Kpi cares about. When the proxy is attached, it calls `Evaluate ` with the proper sender and event arguments so that the KPI can determine if a conversion occurred. |
`IKpiResult Evaluate(object sender, EventArgs e) ` | Determines if a conversion occurred when the proper .Net event is executed. The passed-in EventArgs should be cast to the expected EventArgs type to check the Kpi’s instance data against the event specific data. |
`DateTime CreatedDate ` | Determines when the Kpi instance was created. |
`DateTime ModifiedDate ` | Determines when the Kpi instance is modified. |
`ResultComparison ` | Indicates how the Kpi Evaluation result object should be interpreted when trying to decide if a result is better than another instance of the result. Used specifically for indicating whether a greater or lesser result is desired. |
`void Initialize ` | Called by external packages when the KPI needs to set up dependencies that occur outside of construction. Designed to do any extra setup for the KPI such as listening for setup events outside of the normal Evaluate event handler. |
`void Uninitialize ` | Called by external packages when the KPI needs to clean up dependencies that are set up during the Initialize method. |
`string KpiResultType ` | Informs external packages what type of KPI result evaluate will return. |
### IClientKpi
`IClientKpi
` is an interface for marking a custom KPI that should be run on the client browser to convert an A/B test. It consists of only one method for retrieving the client JavaScript that needs to be presented in the browser to indicate when a conversion takes place.
IClientKpi method | Description |
`string ClientEvaluationScript ` | Returns a JavaScript function to be executed in a visitor’s browser to indicate when a conversion has occurred. This function’s first parameter should be a success callback function to execute when a conversion has occurred. |
Note
The function returned by this method should be immediately invoked when loaded in the target page.
Example script to return:
### Serialization
Calling packages such as A/B testing package rely on Microsoft’s _System.Runtime.Serialization_’s attributes to inform the user interface of a Kpi type’s information. The [`DataContract
`] attribute should be on the class implementing the IKpi interface and the [`DataMember
`] attribute on fields that should be sent to the user interface.