Now Packing Magic

    pickpick

    5.0.6 • Public • Published

    pickpick

    An A/B testing engine

    CircleCI Coverage Status npm latest version

    To use this engine, create one or more experiments and stick them in a container. Each experiment is composed of a bunch of variations which are randomly picked/served to you. Once you obtain a variation, use it to render some content or make some sort of a decision.

    The container's job is to select the correct experiments for each visitor based on each experiment's targeting expression. Thusly, to get a variation one would call pick() twice, once on the container and once on the experiment.

    Further information about the targeting experssion syntax can be found here: pickpick-targeting-compiler

    Also, please take a look at our examples

    example

    npm i -S pickpick

    Let's say we have a website with two pages buy and index and we want to run 3 experiments:

    • on the buy page test color button
    • on the buy page test price
    • on the index page test text
    const { Experiment, ExperimentContainer } = require('pickpick')
     
    // first create the experiments:
     
    let e1 = Experiment.create({
        name: 'buy page button color experiment',
        id: '953d6fe0',
        variations: [
            { object: '#ff0000', weight: 4 },
            { object: '#ff0000', weight: 1 },
            { object: '#00ff00', weight: 1 }
        ],
        targeting: '_.path in ["buy", "index"]'
    })
     
    let e2 = Experiment.create({
        name: 'buy page price experiment',
        id: 'a40f09ac',
        variations: [
            { object: 25 },
            { object: 35 },
            { object: 45 }
        ],
        targeting: '_.path !== "home" && page !== "foo"'
    })
     
    let e3 = Experiment.create({
        name: 'index text experiment',
        id: 'ac49ef42',
        variations: [
            { object: 'hi' },
            { object: 'hello' },
            { object: 'welcome' }
        ],
        targeting: '_.path === "index"'
    })
     
    // now create a container:
    let experiments = [e1, e2, e3]
    let container = ExperimentContainer.create({ experiments })
     
    // simulate a visitor that needs a determination about which variation of which experiment he gets:
    let visitor = { page: 'index' }
    for (let i = 0; i < 10; i++) {
        let experiment = container.pick(visitor)
     
        if (!experiment) {
            // no experiment that targets this user
            // handle this with defaults
            console.log('default goes here')
        } else {
     
            console.log(`selected experiment '${experiment.name}' for '${JSON.stringify(visitor)}'`)
            let variation = experiment.pick()
            console.log(`selected variation is ${variation}`)
        }
    }

    API

    Table of Contents

    Experiment

    lib/Experiment.js:34-171

    An A/B test experiment contains one or more variations and a definition of targeting.

    Experiments are serializable and can be created using classes from this engine or object literals. For example:

    const { Experiment } = require('pickpick')
     
    const e1 = Experiment.create({
        name: 'my experiment',
        id: 'foo',
        variations: [
            { object: 1, weight: 1 },
            { object: 2, weight: 1 },
            { object: 3, weight: 1 }
        ],
        targeting: '_.geo === "US"'
    })

    Parameters

    • $0 Object
      • $0.name
      • $0.id
      • $0.variations (optional, default [])
      • $0.targeting (optional, default Targeting.default())
      • $0.userData

    pick

    lib/Experiment.js:66-68

    randomly select one variation from the Variations set

    Returns Variant the value contained within the selected variation

    match

    lib/Experiment.js:76-78

    check if this experiment matches the input targeting

    Parameters

    Returns Boolean

    add

    lib/Experiment.js:84-95

    add another variation to this experiment

    Parameters

    iterator

    lib/Experiment.js:116-118

    iterate over the variations contained in this experiment

    Targeting

    lib/Targeting.js:11-80

    Targeting

    Parameters

    match

    lib/Targeting.js:31-39

    check if the input data is matched by this targeting instance

    Parameters
    • inputTargeting Object is normally a simple js object

    Returns Boolean

    expression

    lib/Targeting.js:45-47

    access this Targeting's expression

    Returns String

    iterator

    lib/Targeting.js:52-54

    iterate over the features that participate in the targeting

    has

    lib/Targeting.js:61-63

    check if a feature is part of this targeting instance

    Parameters
    • feature String a name of a feature, e.g geo

    Returns Boolean

    Variation

    lib/Variation.js:9-99

    A variation attaches weight to a piece of data. Variations are used in Experiments and ExperimentContainers

    Parameters

    • $0 Object
      • $0.object
      • $0.weight (optional, default 1)

    ExperimentContainer

    lib/ExperimentContainer.js:38-239

    Contains one or more experiments and routes traffic evenly to each of them based on their targeting. The following is an example of using a container to host several experiments, pick on thats appropriate for a single visitor's targeting and then access a variation from the selected experiment:

    const { ExperimentContainer, Experiment } = require('pickpick')
     
    const experiments = [
            Experiment.create(...),
            Experiment.create(...),
            Experiment.create(...)
    ]
     
    const container = ExperimentContainer.create({ experiments })
     
    let experiment = container.pick({ geo: 'US', page: 'index.html '})
    if (experiment) {
        let variation = experiment.pick()
        // do something with the variation data
    } else {
        console.log('no experiments that match this targeting were found')
    }

    Parameters

    • __seed number just for testing / predictable engine results

    add

    lib/ExperimentContainer.js:77-102

    Add an experiment to this container. Inside a container experiments must have unique ids. This method can accept different kinds of experiment expressions:

    • an instance of Experiment:
    container.add(Experiment.create(...))
    • An instance of Variation where it's object is an Experiment: ```js container.add(Variation.create(Experiment.create(...))) ````
    • An instance of Variation where it's object is an Expriment defined as an object literal:
    container.add(Variation.create({... experiment data ...}))
    • A variation object literal wrapping an experiment object literal, this is useful in deserialization scenarios:
    container.add({ object: {... experiment data }, weight: 5 })
    Parameters
    • experiments ...any

    pick

    lib/ExperimentContainer.js:131-151

    The pick method accepts a targeting object and randomly selects an experiment from a set of experiments that match the targeting specification.

    By default, selection is random and even, however, bias can be applied by specifying a weight when adding an experiment to the container (see ExperimentContainer.add())

    Weights are considered at the moment of selection from the current set of matching experiments, therefor, careful planning of targeting is required to achieve accurate traffic distribution betwee experiments.

    For example, consider two experiments, E1, that targets { geo: 'US', page: '*' } and E2 that targets { geo: 'US', page: 'index.html' }. If both had the weight 1, given the following stream of visitors:

    { geo: 'US', page: 'sale.html' }
    { geo: 'US', page: 'index.html' }
    { geo: 'US', page: 'sale.html' }
    { geo: 'US', page: 'index.html' }
    

    Then it is more likely that E1 will receive more traffic than E2 since E1 competes with E2 evenly on index.html page but not on sale.html

    Parameters

    Returns Experiment an experiment that matches this targeting or null if none is found.

    targetingFeatures

    lib/ExperimentContainer.js:159-161

    An iterator over all the targeting features from all the experiments added to this container

    Returns Iterator

    iterator

    lib/ExperimentContainer.js:175-177

    iterate over all the experiments in this container:

    let container = ExperimentContainer.create(...)
    
    for (let experiment of container) {
    	console.log(experiment.id)
    	}
    

    Returns ObjectIterator

    has

    lib/ExperimentContainer.js:184-188

    check if this container contains the specified experiment

    Parameters
    • experiment Expriment

    Returns Boolean

    hasId

    lib/ExperimentContainer.js:195-201

    check if this container contains an experiment using an id

    Parameters

    Returns Boolean

    toJSON

    lib/ExperimentContainer.js:208-215

    serialize this container with all it's experiments

    Returns Object

    Keywords

    none

    Install

    npm i pickpick

    DownloadsWeekly Downloads

    0

    Version

    5.0.6

    License

    MIT

    Unpacked Size

    61 kB

    Total Files

    22

    Last publish

    Collaborators

    • it-ironsrc
    • kessler