A/B Testing mit Node.js

Post on 21-Jan-2018

237 views 0 download

Transcript of A/B Testing mit Node.js

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 Snippetfunction 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 Experimentsconst 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 Modelsclass 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 Flagsapp.get('/profile', async (req, res) => { const data = {};

if (await config.isEnabled('newConfig')) { res.render('newProfile.ejs', data); } else { res.render('profile.ejs', data); } });

Feature Flagsconst 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

Sixpackconst 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

Optimizelyconst 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ätEinzelne 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