A/B Testing
TO-DO before releasable
- Implement automatic impression tracking
- Finalize tooling
- Find a better name
Getting started
For a minimal setup six elements are needed: ABRoot
, withABTest
and VariantA
/VariantB
along with an ABManger
with an ABTestSuite
and an ABUser
A.jsx
;; { thisprops; } { return <div onClick=thishandleClick>Variant A</div> ; } A;
B.jsx
;; { thisprops; } { return <div onClick=thishandleClick>Variant B</div> ; } B;
App.jsx
;;;; <div> <VariantA name="test1" autoTrackImpression> <A /> </VariantA> <VariantB name="test2" autoTrackImpression> <B /> </VariantB> </div>;
test1.js
; ;
index.jsx
;;;;; const manager = user: testSuite = ;manager;manager; ReactDOM
Using different components
Another usefull feature is to be able to serve different components depending on which test bucket the user is in. This can be done using the createABTest
higher order function
A.jsx
<div>VariantA value</div>
B.jsx
<div>VariantB value</div>
Component.jsx
;;; name: 'test1' VariantA: A VariantB: B
Now when rendering <Component value="hello" />
, the user which are presented the original version will see "VariantA hello" and user presented with the alternative version will see "VariantB hello".
User information
In order to figure out if users is in a given group, a set of user trades need to be provided. The test split is stateless, so therefore it can not store any information about previous a/b buckets a user has fallen into, and therefor this needs to be something which can be figured out based on values about the current user.
These are set by calling setUserInfo
on the manager object, which was passed to ABRoot
. When these values change, all A/B splits, currently presented to the user will be re-evaluated, and if a user changes bucket, these changes are reflected.
; const manager = ... user: ;;manager; const root = <ABRoot manager=manager> </ABRoot>
Tests
Test Suites
Creating a custom test
; { return userInfoisLoggedIn; } { return userInfoid % 2; } manager;
Services
The component comes with a few different service types preloaded and provides the tools for creating custom service
Creating a service
; { super; thisendpoint = endpoint; } async { const response = await ; return response; } async { const data = ; data; return ; } async { await this; } async { await this; } const manager = ... service: const root = <ABRoot manager=manager> </ABRoot>