A/B-Testing mit Node
Wolfgang Dirscherl / pixelio.de
Basti
• Sebastian Springer
• aus München
• arbeite bei MaibornWolff GmbH
• https://github.com/sspringer82
• @basti_springer
• JavaScript Entwickler
A/B-Testing
Frontend-Testing
ExpressAB
Feature Flags
Sixpack
Agenda
Rainer Sturm / pixelio.de
Thommy Weiss / pixelio.de
A/B-Testing?
A/B-Testing?
Von einem bestimmten Feature werden zwei
unterschiedliche Versionen an Benutzer ausgespielt, um zu
sehen, welche Variante das gewünschte Ziel besser erfüllt.
Multivarianten-Testing
Beim Multivarianten-Testing werden parallel mehrere
Versionen und eine Kontrollversion ausgespielt, um zu
prüfen, welche besser performt.
Vorteil: Das Ergebnis liegt wesentlich schneller vor als beim
A/B-Testing
Nachteil: es werden mehr Nutzer benötigt, um aussagekräftig
zu sein
Was kann man testen?
lichtkunst.73 / pixelio.de
Was kann man testen?
Grundsätzlich kann nahezu jeder Aspekt einer Applikation
getestet werden. Die Spanne reicht von angepassten
Layouts über eine veränderte Seitenstruktur bis hin zu
unterschiedlichen Workflows.
Je nachdem, wie tief in die Applikation eingegriffen werden
soll, müssen unterschiedliche Werkzeuge verwendet
werden.
Vorgehensweise
1. Hypothese(n)
2. Umfang des Experiments festlegen
3. Unterschiedliche Varianten implementieren
4. Ausspielen
5. Tracken
6. Auswerten
7. Die bessere Version verwenden
Die Hypothese
Wenn wir unsere Registrierung von einem großen Formular
in mehrere Tabs aufteilen, werden innerhalb von 4 Wochen
20% mehr Felder ausgefüllt.
Die Hypothese
Die Hypothese muss möglichst klar und messbar formuliert
werden. Damit kann der Erfolg des Experiments gemessen
werden.
Multivarianten
Manchmal kann man keine konkrete Hypothese formulieren,
sondern muss beispielsweise die Positionierung eines Buttons
oder Formulars einfach ausprobieren.
Hier kommen Multivarianten-Tests zum Einsatz.
Umfang festlegen
Peter Reinäcker / pixelio.de
Den Umfang festlegen
Experimente sollten immer zeitlich begrenzt werden.
Je mehr parallele Tests laufen, desto unübersichtlicher wird
die Situation. Außerdem können sich Experimente gegenseitig
beeinflussen.
Der Umfang muss so gewählt werden, dass aussagekräftige
Daten geliefert werden.
Implementieren
w.r.wagner / pixelio.de
Frontendbasierte Tests
Frontendbasierte Tests
Die Seitenstruktur wird mit einem JavaScript-Framework
entsprechend des Tests angepasst.
Was kann ich damit testen?
Diese Art von Tests beschränkt sich vor allem auf strukturelle
Manipulationen der Seite.
Serverseitige Strukturen oder Datenbankanpassungen sind
nicht möglich.
Optimizely
Optimizely ist ein klassisches frontendbasiertes Werkzeug
für A/B- und multivarianten-Tests. Es gibt sowohl eine
(eingeschränkte) freie als auch eine kostenpflichtige
Version.
Mittlerweile gibt es auch Erweiterungen für andere
Plattformen wie Node
Verteilung
• Prozentuale Verteilung
• Browser
• Sources
• Cookies
• Request Parameters
• Geo/Language
Arbeitsweise
https://help.optimizely.com/Build_Campaigns_and_Experiments/How_Optimizely_Works%3A_Snippet_order_of_execution_and_JavaScript_evaluation_timing
Code Snippet
function callbackFn(activate, options) {
var utils = window.optimizely.get('utils');
var $ = window.optimizely.get('jquery');
utils.waitForElement('button').then(function(el) {
if ($('button').length > 0) {
activate();
}
});
}
Optimizely
Vorteile
Leichtgewichtig und
schnell umzusetzen
Kann auch von Frontend-
Entwicklern

durchgeführt werden
Unabhängig vom
Backend
Änderungen sind
nicht persistent
Nicht versioniert
Quellcode wird nach der
Auslieferung manipuliert
Zusätzlicher Overhead
Nachteile
Tests mit Node.js
In einer Node.js-Webapplikation können A/B-Tests direkt
integriert werden. Das hat den Vorteil dass bereits auf dem
Server entschieden werden kann, welche Variante
ausgespielt wird.
A/B-Tests mit Express
https://github.com/omichelsen/express-ab
Für das Web Application Framework Express gibt es eine
Middleware, die die Steuerung der Experimente übernimmt.
Diese Experimente basieren auf den Routen der Applikation.
A/B-Tests mit Express
npm install express express-ab cookie-parser
Als Middleware kann express-ab jederzeit auch in eine
bestehende Express-Applikation integriert werden.
const express = require('express');
const cookieParser = require('cookie-parser');
const ab = require('express-ab');
const app = express();
app.use(cookieParser());
const profileTest = ab.test('Profile Test');
app.get('/', profileTest(), (req, res) => {
res.send('variant A');
});
app.get('/', profileTest(), (req, res) => {
res.send('variant B');
});
app.listen(8080);
Express-ab
Über die Informationen im Cookie des Benutzers wird die
jeweilige Variante zugeordnet, sodass ein Benutzer stets die
selbe Variante erhält.
Verteilung
Die Varianten eines Experiments können unterschiedlich
gewichtet werden:
profileTest(null, 0.2)
Dieses Experiment wird in 20% der Anfragen ausgespielt.
Insgesamt sollte die Summe der Varianten 1 Ergeben.
Experiments
Google Experiments
Express-ab kann auch mit Google Experiments verwendet
werden. Dabei handelt es sich um einen Teil von Google
Analytics, der dazu verwendet werden kann Multivarianten-
Tests durchzuführen.
Mit express-ab kann man sowohl auf die Experiment-ID als
auch auf die jeweilige Variante zugreifen und diese auch an
den Browser fürs Tracking weiterreichen.
Google Experiments
Google Experiments
const profileTest = ab.test('Profile Test', { id:
'123456789' });
app.get('/', profileTest(), (req, res) => {
// res.locals.ab.name - 'Profile Test'
// res.locals.ab.id - '123456789'
// res.locals.ab.variantId - 0
res.send('variant A');
});
Tiefere Integration
Mit den Informationen, welche Variante ausgespielt wird,
können auch innerhalb der Applikationslogik umgesetzt
werden.
Unterschiedliche Models
class Controller {
getProfile(req, res) {
let model;
switch (res.locals.ab.variantId ) {
case 0:
model = new RefProfileModel();
break;
case 1:
model = new PerfProfileModel();
break;
default:
model = new ProfileModel();
break;
}
res.render('profile', model);
}
}
Im Template
res.render('profile', {variant: res.locals.ab.variantId});
<% if (variant === 0) { %>
<a href="javascript:void(0)" id="submit">Submit</a>
<% } else if (variant === 1) {%>
<button id="submit">Submit</button>
<% } %>
Feature Flags
S. Hofschlaeger / pixelio.de
Feature Flags
Feature Flags sind eine weitere Variante, um unter anderem A/
B-Tests durchzuführen.
Im einfachsten Fall ist ein solches Feature-Flag eine Abfrage
im Code, die anhand einer Konfiguration den Code-Block
ausführt oder nicht.
Feature Flags
app.get('/profile', async (req, res) => {
const data = {};
if (await config.isEnabled('newConfig')) {
res.render('newProfile.ejs', data);
} else {
res.render('profile.ejs', data);
}
});
Feature Flags
const fs = require('fs');
const util = require('util');
const readFile = util.promisify(fs.readFile);
module.exports = {
async isEnabled(feature) {
const content = await readFile('config.json',
'utf-8');
const contentObj = JSON.parse(content);
return contentObj.hasOwnProperty(feature) &&
contentObj[feature];
}
}
Feature Flags
Nachdem ein Feature Flag nicht mehr benötigt wird, sollte
zumindest die Abfrage entfernt werden.
Aufräumen
Sixpack
Alexander Klaus / pixelio.de
Sixpack
Sixpack ist ein Open Source A/B-Testing-Framework das
unabhängig von Sprache und Plattform ist. Die Server-
Komponente ist in Python geschrieben. Es gibt Client-
Bibliotheken unter anderem auch für Node.
Sixpack Web UI
Sixpack
const sixpack = require('sixpack-client');
const session = new sixpack.Session();
session.participate('test-exp', ['alt-one', 'alt-two'],
(err, res) => {
if (err) {
throw err;
}
let alt = res.alternative.name
if (alt === 'alt-one') {
console.log('default: ' + alt);
} else {
console.log(alt);
}
});
Optimizely
Optimizely bietet nicht nur die Möglichkeit das Frontend zu
“verbiegen”, sondern stellt auch APIs für verschiedene
Sprachen und Plattformen wie Node.js zur Verfügung.
npm install optimizely-server-sdk
Optimizely
const optimizely = require('optimizely-server-sdk');
const optimizelyClient = optimizely.createInstance({ datafile:
datafile });
const variation = optimizelyClient.activate(‘profile', userId);
if (variation === 'variant A') {
// Execute code for variation A
} else if (variation === 'variant B') {
// Execute code for variation B
} else {
// Execute default code
}
optimizelyClient.track("my_conversion", userId);
Auswertung
S. Hofschlaeger / pixelio.de
Tracking und Auswertung
Der mitunter wichtigste Teil eines Experiments ist seine
Auswertung. Zu diesem Zweck bieten die verschiedenen
Werkzeuge Möglichkeiten zur Auswertung. Sowohl
Optimizely als auch Sixpack und Google Experiments
verfügen über eine grafische Oberfläche.
Fallstricke
Kurt Michel / pixelio.de
Fallstricke
Komplexität
Laufzeit
Teilnehmer
Zeitraum
Komplexität
Einzelne A/B- oder Multivarianten-Tests sind relativ gut
kontrollierbar.
Sind viele Experimente in einer großen Applikation parallel
aktiv, sollten diese an einer zentralen Stelle verwaltet werden.
Wenn möglich sollten verschachtelte Experimente vermieden
werden. Derartige Konstellationen können sich gegenseitig
beeinflussen und verfälschen unter Umständen die
Ergebnisse.
Laufzeit
Die Laufzeit muss so gewählt werden, dass die Ergebnisse
aussagekräftig sind.
Werden mehrere Experimente hintereinander geschaltet,
sollten Sie auch über die gleiche Laufzeit verfügen.
Teilnehmer
Damit ein Experiment ausgewertet werden kann, müssen
genügend Benutzer die an den verschiedenen Varianten
teilnehmen.
Dies ist wichtig, damit nicht wenige Teilnehmer das Ergebnis
verfälschen.
Zeitraum
Experimente sollten in einem möglichst neutralen Zeitraum
stattfinden.
In einem Online-Shop ist der Traffic in der Weihnachtszeit am
höchsten. Diese Zeit ist auch nicht immer repräsentativ.
Fragen?
Rainer Sturm / pixelio.de
KONTAKT
Sebastian Springer
sebastian.springer@maibornwolff.de
MaibornWolff GmbH
Theresienhöhe 13
80339 München
@basti_springer
https://github.com/sspringer82

A/B Testing mit Node.js

  • 1.
    A/B-Testing mit Node WolfgangDirscherl / pixelio.de
  • 2.
    Basti • Sebastian Springer •aus München • arbeite bei MaibornWolff GmbH • https://github.com/sspringer82 • @basti_springer • JavaScript Entwickler
  • 3.
  • 4.
    Thommy Weiss /pixelio.de A/B-Testing?
  • 5.
    A/B-Testing? Von einem bestimmtenFeature werden zwei unterschiedliche Versionen an Benutzer ausgespielt, um zu sehen, welche Variante das gewünschte Ziel besser erfüllt.
  • 7.
    Multivarianten-Testing Beim Multivarianten-Testing werdenparallel mehrere Versionen und eine Kontrollversion ausgespielt, um zu prüfen, welche besser performt. Vorteil: Das Ergebnis liegt wesentlich schneller vor als beim A/B-Testing Nachteil: es werden mehr Nutzer benötigt, um aussagekräftig zu sein
  • 8.
    Was kann mantesten? lichtkunst.73 / pixelio.de
  • 9.
    Was kann mantesten? Grundsätzlich kann nahezu jeder Aspekt einer Applikation getestet werden. Die Spanne reicht von angepassten Layouts über eine veränderte Seitenstruktur bis hin zu unterschiedlichen Workflows. Je nachdem, wie tief in die Applikation eingegriffen werden soll, müssen unterschiedliche Werkzeuge verwendet werden.
  • 10.
    Vorgehensweise 1. Hypothese(n) 2. Umfangdes Experiments festlegen 3. Unterschiedliche Varianten implementieren 4. Ausspielen 5. Tracken 6. Auswerten 7. Die bessere Version verwenden
  • 11.
    Die Hypothese Wenn wirunsere Registrierung von einem großen Formular in mehrere Tabs aufteilen, werden innerhalb von 4 Wochen 20% mehr Felder ausgefüllt.
  • 12.
    Die Hypothese Die Hypothesemuss möglichst klar und messbar formuliert werden. Damit kann der Erfolg des Experiments gemessen werden.
  • 13.
    Multivarianten Manchmal kann mankeine konkrete Hypothese formulieren, sondern muss beispielsweise die Positionierung eines Buttons oder Formulars einfach ausprobieren. Hier kommen Multivarianten-Tests zum Einsatz.
  • 14.
  • 15.
    Den Umfang festlegen Experimentesollten immer zeitlich begrenzt werden. Je mehr parallele Tests laufen, desto unübersichtlicher wird die Situation. Außerdem können sich Experimente gegenseitig beeinflussen. Der Umfang muss so gewählt werden, dass aussagekräftige Daten geliefert werden.
  • 16.
  • 17.
  • 18.
    Frontendbasierte Tests Die Seitenstrukturwird mit einem JavaScript-Framework entsprechend des Tests angepasst.
  • 19.
    Was kann ichdamit testen? Diese Art von Tests beschränkt sich vor allem auf strukturelle Manipulationen der Seite. Serverseitige Strukturen oder Datenbankanpassungen sind nicht möglich.
  • 21.
    Optimizely Optimizely ist einklassisches frontendbasiertes Werkzeug für A/B- und multivarianten-Tests. Es gibt sowohl eine (eingeschränkte) freie als auch eine kostenpflichtige Version. Mittlerweile gibt es auch Erweiterungen für andere Plattformen wie Node
  • 22.
    Verteilung • Prozentuale Verteilung •Browser • Sources • Cookies • Request Parameters • Geo/Language
  • 23.
  • 24.
    Code Snippet function callbackFn(activate,options) { var utils = window.optimizely.get('utils'); var $ = window.optimizely.get('jquery'); utils.waitForElement('button').then(function(el) { if ($('button').length > 0) { activate(); } }); }
  • 25.
  • 26.
    Vorteile Leichtgewichtig und schnell umzusetzen Kannauch von Frontend- Entwicklern
 durchgeführt werden Unabhängig vom Backend
  • 27.
    Änderungen sind nicht persistent Nichtversioniert Quellcode wird nach der Auslieferung manipuliert Zusätzlicher Overhead Nachteile
  • 29.
    Tests mit Node.js Ineiner Node.js-Webapplikation können A/B-Tests direkt integriert werden. Das hat den Vorteil dass bereits auf dem Server entschieden werden kann, welche Variante ausgespielt wird.
  • 30.
    A/B-Tests mit Express https://github.com/omichelsen/express-ab Fürdas Web Application Framework Express gibt es eine Middleware, die die Steuerung der Experimente übernimmt. Diese Experimente basieren auf den Routen der Applikation.
  • 31.
    A/B-Tests mit Express npminstall express express-ab cookie-parser Als Middleware kann express-ab jederzeit auch in eine bestehende Express-Applikation integriert werden.
  • 32.
    const express =require('express'); const cookieParser = require('cookie-parser'); const ab = require('express-ab'); const app = express(); app.use(cookieParser()); const profileTest = ab.test('Profile Test'); app.get('/', profileTest(), (req, res) => { res.send('variant A'); }); app.get('/', profileTest(), (req, res) => { res.send('variant B'); }); app.listen(8080);
  • 33.
    Express-ab Über die Informationenim Cookie des Benutzers wird die jeweilige Variante zugeordnet, sodass ein Benutzer stets die selbe Variante erhält.
  • 34.
    Verteilung Die Varianten einesExperiments können unterschiedlich gewichtet werden: profileTest(null, 0.2) Dieses Experiment wird in 20% der Anfragen ausgespielt. Insgesamt sollte die Summe der Varianten 1 Ergeben.
  • 35.
  • 36.
    Google Experiments Express-ab kannauch mit Google Experiments verwendet werden. Dabei handelt es sich um einen Teil von Google Analytics, der dazu verwendet werden kann Multivarianten- Tests durchzuführen. Mit express-ab kann man sowohl auf die Experiment-ID als auch auf die jeweilige Variante zugreifen und diese auch an den Browser fürs Tracking weiterreichen.
  • 37.
  • 38.
    Google Experiments const profileTest= ab.test('Profile Test', { id: '123456789' }); app.get('/', profileTest(), (req, res) => { // res.locals.ab.name - 'Profile Test' // res.locals.ab.id - '123456789' // res.locals.ab.variantId - 0 res.send('variant A'); });
  • 39.
    Tiefere Integration Mit denInformationen, welche Variante ausgespielt wird, können auch innerhalb der Applikationslogik umgesetzt werden.
  • 40.
    Unterschiedliche Models class Controller{ getProfile(req, res) { let model; switch (res.locals.ab.variantId ) { case 0: model = new RefProfileModel(); break; case 1: model = new PerfProfileModel(); break; default: model = new ProfileModel(); break; } res.render('profile', model); } }
  • 41.
    Im Template res.render('profile', {variant:res.locals.ab.variantId}); <% if (variant === 0) { %> <a href="javascript:void(0)" id="submit">Submit</a> <% } else if (variant === 1) {%> <button id="submit">Submit</button> <% } %>
  • 42.
  • 43.
    Feature Flags Feature Flagssind eine weitere Variante, um unter anderem A/ B-Tests durchzuführen. Im einfachsten Fall ist ein solches Feature-Flag eine Abfrage im Code, die anhand einer Konfiguration den Code-Block ausführt oder nicht.
  • 44.
    Feature Flags app.get('/profile', async(req, res) => { const data = {}; if (await config.isEnabled('newConfig')) { res.render('newProfile.ejs', data); } else { res.render('profile.ejs', data); } });
  • 45.
    Feature Flags const fs= require('fs'); const util = require('util'); const readFile = util.promisify(fs.readFile); module.exports = { async isEnabled(feature) { const content = await readFile('config.json', 'utf-8'); const contentObj = JSON.parse(content); return contentObj.hasOwnProperty(feature) && contentObj[feature]; } }
  • 46.
    Feature Flags Nachdem einFeature Flag nicht mehr benötigt wird, sollte zumindest die Abfrage entfernt werden.
  • 47.
  • 48.
  • 49.
    Sixpack Sixpack ist einOpen Source A/B-Testing-Framework das unabhängig von Sprache und Plattform ist. Die Server- Komponente ist in Python geschrieben. Es gibt Client- Bibliotheken unter anderem auch für Node.
  • 50.
  • 51.
    Sixpack const sixpack =require('sixpack-client'); const session = new sixpack.Session(); session.participate('test-exp', ['alt-one', 'alt-two'], (err, res) => { if (err) { throw err; } let alt = res.alternative.name if (alt === 'alt-one') { console.log('default: ' + alt); } else { console.log(alt); } });
  • 53.
    Optimizely Optimizely bietet nichtnur die Möglichkeit das Frontend zu “verbiegen”, sondern stellt auch APIs für verschiedene Sprachen und Plattformen wie Node.js zur Verfügung. npm install optimizely-server-sdk
  • 54.
    Optimizely const optimizely =require('optimizely-server-sdk'); const optimizelyClient = optimizely.createInstance({ datafile: datafile }); const variation = optimizelyClient.activate(‘profile', userId); if (variation === 'variant A') { // Execute code for variation A } else if (variation === 'variant B') { // Execute code for variation B } else { // Execute default code } optimizelyClient.track("my_conversion", userId);
  • 55.
  • 56.
    Tracking und Auswertung Dermitunter wichtigste Teil eines Experiments ist seine Auswertung. Zu diesem Zweck bieten die verschiedenen Werkzeuge Möglichkeiten zur Auswertung. Sowohl Optimizely als auch Sixpack und Google Experiments verfügen über eine grafische Oberfläche.
  • 58.
  • 59.
  • 60.
    Komplexität Einzelne A/B- oderMultivarianten-Tests sind relativ gut kontrollierbar. Sind viele Experimente in einer großen Applikation parallel aktiv, sollten diese an einer zentralen Stelle verwaltet werden. Wenn möglich sollten verschachtelte Experimente vermieden werden. Derartige Konstellationen können sich gegenseitig beeinflussen und verfälschen unter Umständen die Ergebnisse.
  • 61.
    Laufzeit Die Laufzeit mussso gewählt werden, dass die Ergebnisse aussagekräftig sind. Werden mehrere Experimente hintereinander geschaltet, sollten Sie auch über die gleiche Laufzeit verfügen.
  • 62.
    Teilnehmer Damit ein Experimentausgewertet werden kann, müssen genügend Benutzer die an den verschiedenen Varianten teilnehmen. Dies ist wichtig, damit nicht wenige Teilnehmer das Ergebnis verfälschen.
  • 63.
    Zeitraum Experimente sollten ineinem möglichst neutralen Zeitraum stattfinden. In einem Online-Shop ist der Traffic in der Weihnachtszeit am höchsten. Diese Zeit ist auch nicht immer repräsentativ.
  • 64.
  • 65.
    KONTAKT Sebastian Springer sebastian.springer@maibornwolff.de MaibornWolff GmbH Theresienhöhe13 80339 München @basti_springer https://github.com/sspringer82