A/B/n testing package for use within the Laravel 5 framework

v2.0.0 2018-08-14 04:24 UTC


A Laravel 5 a/b/n testing package.


  • PHP >= 7.0
  • Laravel 5.4, 5.5


  1. Add "heaps-good-services/variant": "^2.0" to your composer.json file.
  2. Run "composer update".
  3. Run "php artisan". If the variant commands do not show up then you'll need to add the service provider "HeapsGoodServices\Variant\Providers\ServiceProvider" to the Package Service Providers section of the config/app.php providers array.
  4. Run 'php artisan vendor:publish --provider="HeapsGoodServices\Variant\Providers\ServiceProvider"' to publish files.
  5. Register the newly published service provider in your providers array: App\Providers\VariantServiceProvider


Experiments are registered in the boot method of the VariantServiceProvider. The experiments are then available for use throughout the application.

Register Experiments:

Register an experiment to test the affect of a piece of text on the conversion rate of a sign up page.

    ->addVariation('welcome')// A welcoming message.
    ->addVariation('free_ipad')// Free IPad on sign up.
    ->addVariation('not_welcome', 9);// Deter the user from signing up.


The higher the weight, the higher the likelyhood that specific variation will be selected from the random pool.

    ->addVariation('welcome', 3)
    ->addVariation('deter', 9);

The weights correspond to the number of tickets that variation has in the lottery. In the example given above the 'welcome' variation has a 3/13 probabiliy of being chosen.

Experiment Types

There are user and system experiments. User experiments require verification before data is propagated to the aggregate results. System experiments are stored directly in the aggregate results.

To register a system experiment set the 'isSystemExperiment' parameter to true.

$variant->registerExperiment('sms_gateway_reliability', true)


The Variant facade is available everywhere using the helper function 'variant()'.

Adding the verification tags

The verification tags help to verify human requests and stop bots from skewing the results.


{!! variant()->getVerificationTags() !!}


An interaction represents the start of a specific experiment instance. The interactions are limited to one per user experiment regardless of how many times an interaction is triggered.



$variationName = interact('sign_up_message');

if($variationName === 'deter') {
    $signUpMessage = 'We don't want you on our site. Leave Now.';
} else if($variationName === 'free_ipad') {
    $signUpMessage = 'Recieve a free IPad with every sign up.';
} else {
    $signUpMessage = 'Welcome to my website. Please sign up below.';


In Blade

        We don't want you on our site. Leave Now.
        Free Ipad with every sign up.
        We welcome you with open arms.

The switch directive is only available from Laravel 5.5. For earlier versions you can do the following:

@if(interact('sign_up_message') === 'deter')
    We don't want you on our site. Leave Now.
@elseif(interact('sign_up_message') === 'free_ipad')
    Free Ipad with every sign up.
    We welcome you with open arms.



function store(Request $request) {

The conversions are limited to one per user experiment regardless of how many times a conversion is triggered.

Example System Experiment


function makeSmsGateway(string $smsGatewayName): SmsGatewayInterface {
    switch($smsGatewayName) {
        case 'superstar_sms_company':
            return new SuperStarSMSGateway(...);
        case 'hindenburg_sms_systems':
            return new HindenburgSMSGateway(...);


function handle(SmsGatewayFactory $smsGatewayFactory) {
    $variation = variant()->getExperiment('sms_gateway_reliability')
    if($smsGatewayFactory->makeSmsGateway($variation->getName())->send(...)) {

Console Commands

There are console commands to provide transparency into the experiments.

List Experiments

List the experiments and their variations.


php artisan variant:experiments


| Name                    | Variations                                   |
| sign_up_message         | welcome,free_ipad,deter                |
| sms_gateway_reliability | superstar_sms_company,hindenburg_sms_systems |

Get Statistics

Get the statistics for one or all experiments.


# All Experiment Stats
php artisan variant:get-stats

# Single Experiments Stats
php artisan variant:get-stats sms_gateway_reliability

Output for sms_gateway_reliability experiment:

Experiment: sms_gateway_reliability
| Variation              | Weight | Interactions | Conversions | Conversion Rate (%) |
| superstar_sms_company  | 1      | 1007         | 1005        | 99.8%               |
| hindenburg_sms_systems | 1      | 993          | 202         | 20.3%               |
| Totals                 | 2      | 2000         | 1207        | 60.4%               |

Clear Statistics

Clear the statistics for a single experiment.

php artisan variant:clear sms_gateway_reliability


The functions 'interact' and 'convert' will suppress exceptions where as the functions 'interact_or_fail' and 'convert_or_fail' will not suppress exceptions.