Multi-Variate Test has been a part of Sitecore DMS for quite some time. It basically allows marketers to vary a component’s datasource or a rendering itself and see which variation does better as measured in the overall engagement value. Testing is a big deal these days and Sitecore 8 attempts to disrupt the status-quo with the new Content Testing feature (aka Page Tests) that I will look into in the next installment of my Sitecore 8 Developer’s Notes (here’s part 1). Before I do so:
[su_note note_color=”#fafafa”]Let’s take a look at how MVT evolved and how parts of page’s layout details were not exactly shared even before Sitecore 8[/su_note]
7.0 / 7.1
A test variation is recorded in the presentation details as an attribute of the rendering node:
<r uid="{EF1B9B61-12B0-4A5D-8149-1FEEF9EA7AD8}" ds="{ACCFD363-A6DD-4613-8674-5D09451096FA}" id="{06A2C3F0-13BE-498A-BD6C-30337FA1FEB9}" mvt="{2F505D5B-2760-4A0E-8B07-BCA6EC3A38FE}" ph="Main" />
The mvt
attribute points to the test definition item under /sitecore/system/Marketing Center/Test Lab
. It will be parsed out in Sitecore.Layouts.RenderingReference
(simplified):
private void ParseDefinition(RenderingDefinition definition) { // ... this.settings.MultiVariateTest = RenderingReference.ParseMultiVariateTest(definition, this.renderingItem); // .. } ... private static string ParseMultiVariateTest(RenderingDefinition renderingDefinition, RenderingItem renderingItem) { // ... string multiVariateTest = renderingDefinition.MultiVariateTest; // ... return multiVariateTest ?? string.Empty; } ... [XmlAttribute("mvt")] public string MultiVariateTest { get; set; }
And then when the time comes for mvc.customizeRendering
pipeline to apply MVT it will:
Item variableItem = args.PageContext.Database.GetItem(renderingReference.Settings.MultiVariateTest);
It works and the MVT definition is shared just like the entire layout details are.
7.2
Things changed in 7.2. I am not sure how well it’s known (let alone documented) but MVT in 7.2 is language-specific. That same test variation will be recorded differently in 7.2:
<r uid="{EF1B9B61-12B0-4A5D-8149-1FEEF9EA7AD8}" ds="{ACCFD363-A6DD-4613-8674-5D09451096FA}" id="{06A2C3F0-13BE-498A-BD6C-30337FA1FEB9}" mvt="en={2F505D5B-2760-4A0E-8B07-BCA6EC3A38FE}" ph="Main" />
If you go ahead and create another language version for that page item and open it in Page Editor you won’t see the active test. You can now create a different test for the same component and it will be recorded like this:
<r uid="{EF1B9B61-12B0-4A5D-8149-1FEEF9EA7AD8}" ds="{ACCFD363-A6DD-4613-8674-5D09451096FA}" id="{06A2C3F0-13BE-498A-BD6C-30337FA1FEB9}" mvt="en={2F505D5B-2760-4A0E-8B07-BCA6EC3A38FE}&ru-RU={38B34DBC-6D3C-439F-92AF-D0C2EBCB3AB3}" ph="Main" />
It is indeed language-specific. The problem is – the MVC code that’s using it was not invited to the party. 7.2 has a known defect and MVT doesn’t work in MVC. The mvt
attribute is still directly translated into the MultiVariateTest
attribute and no database can find an item for en={GUID}
. The fix suggested by Ben is a little intrusive and SCORE provides support for using MVT with Sitecore MVC in 7.2 a little differently (feel free to contact me if you’re interested in details).
7.5
MVT is still language-specific in the otherwise shared layout details but the MVC code finally caught up. Here’s a one line change that makes all the difference:
private void ParseDefinition(RenderingDefinition definition) { // ... this.settings.MultiVariateTest = RenderingReference.ParseMultiVariateTest(definition, this.renderingItem); // .. } ... private static string ParseMultiVariateTest(RenderingDefinition renderingDefinition, RenderingItem renderingItem) { // ... string variateTestForLanguage = MultiVariateTestingExtensions.GetMultiVariateTestForLanguage(renderingDefinition, language); // ... return multiVariateTest ?? string.Empty; } ... [XmlAttribute("mvt")] public string MultiVariateTest { get; set; }
That new helper method is actually available in 7.2. It’s just the MVC didn’t get the memo. And all it does is:
return WebUtil.ParseQueryString(multiVariateTest)[language.Name]
The MVT is working again in MVC.
8.0
8.0 makes a big move. A whole new ball game with the __Final Renderings
field (aka versioned layouts). And not only that, there’s a big move towards testing page variations and suggesting what tests to run automatically. I will sure write about it like I promised already but what about good old MVT? Still there. Downgraded back to its original semantic. That same test variation we looked at will be recored as:
<r uid="{EF1B9B61-12B0-4A5D-8149-1FEEF9EA7AD8}" ds="{ACCFD363-A6DD-4613-8674-5D09451096FA}" id="{06A2C3F0-13BE-498A-BD6C-30337FA1FEB9}" mvt="{2F505D5B-2760-4A0E-8B07-BCA6EC3A38FE}" ph="Main" />
It’s not written to the shared __Renderings
though. It’s now part of the __Final Renderings
so no need to version it individually. The MVC team didn’t need a memo this time. The rendering reference / definition parsing code has also been reverted back to:
// ... string multiVariateTest = renderingDefinition.MultiVariateTest; // ...
We have arrived. I hope you enjoyed the journey!
[su_divider][/su_divider]
p.s. There’s something else I noticed in 8. Something I haven’t seen before – Personalization Test:
[XmlAttribute("pt")] public string PersonalizationTest { get; set; }
… Next Time!