2022-05-20 18:52:32 +02:00
|
|
|
# A/B Testing
|
|
|
|
|
|
|
|
## Overview
|
|
|
|
|
|
|
|
Murph contains a basic tools to create A/B Tests.
|
|
|
|
|
|
|
|
The logic of the implement follows this logic:
|
|
|
|
|
|
|
|
* A node can be configured to enable A/B Test. You also define a code to set the name of the test
|
|
|
|
* When Murph receives a request, an event is dispatched and contains an `App\Core\Ab\AbTestInterface` object
|
|
|
|
* You must create an event subscriber and set variations defined by
|
2022-05-21 20:24:12 +02:00
|
|
|
- a name (a string)
|
|
|
|
- a value (whatever you want)
|
|
|
|
- a percentage chance (optional)
|
2022-05-20 18:52:32 +02:00
|
|
|
* Then a variation is picked and saved in user cookies
|
|
|
|
* Finally, you can retrieve the picked variation PHP side and template side
|
|
|
|
|
|
|
|
## Configure the node
|
|
|
|
|
|
|
|
Go the navigation and edit the tested node:
|
|
|
|
|
|
|
|
* Enable A/B testing
|
|
|
|
* Define a code (eg: `example_test`)
|
|
|
|
|
|
|
|
![](/_static/img/abtest.png)
|
|
|
|
|
|
|
|
## The Event Subscriber
|
|
|
|
|
|
|
|
The event subscriber helps you to define each variation and the TTL.
|
|
|
|
|
2023-02-09 21:50:06 +01:00
|
|
|
```php-inline title="src/EventSubscriber/MyAbTestEventSubscriber.php"
|
2022-05-20 18:52:32 +02:00
|
|
|
namespace App\EventSubscriber;
|
|
|
|
|
|
|
|
use App\Core\EventSubscriber\AbEventSubscriber as EventSubscriber;
|
|
|
|
use App\Core\Event\Ab\AbTestEvent;
|
|
|
|
|
|
|
|
class MyAbTestEventSubscriber extends EventSubscriber
|
|
|
|
{
|
|
|
|
public function onInit(AbTestEvent $event)
|
|
|
|
{
|
|
|
|
if ($event->getTest()->getName() !== 'example_test') {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
$event->getTest()
|
|
|
|
->addVariation('test_1', 'Value #1', 20) // 20% of chance
|
|
|
|
->addVariation('test_2', 'Value #2', 30) // 30% of chance
|
|
|
|
->addVariation('test_3', 'Value #3', 50) // 50% of chance
|
|
|
|
->setDuration(3600 * 24) // duration of the cookie in seconds
|
|
|
|
;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function onRun(AbTestEvent $event)
|
|
|
|
{
|
|
|
|
// executed if a variation is newly picked
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
## The result
|
|
|
|
|
|
|
|
you can retrieve the test and the variation picked in PHP side and in template side.
|
|
|
|
|
2023-02-09 21:50:06 +01:00
|
|
|
```php-inline
|
2022-05-20 18:52:32 +02:00
|
|
|
use App\Core\Ab\AbContainerInterface;
|
|
|
|
|
|
|
|
public function foo(AbContainerInterface $testContainer)
|
|
|
|
{
|
|
|
|
if ($testContainer->has('example_test')) {
|
|
|
|
$test = $testContainer->get('example_test');
|
|
|
|
|
|
|
|
$result = $test->getResult(); // eg: "test_2"
|
|
|
|
$value = $test->getResultValue(); // eg: "Value #2"
|
|
|
|
|
|
|
|
// ...
|
|
|
|
}
|
|
|
|
|
|
|
|
// ...
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2023-02-09 21:50:06 +01:00
|
|
|
```twig
|
2022-05-20 18:52:32 +02:00
|
|
|
{% if ab_test_exists('example_test') %}
|
|
|
|
{% set test = ab_test('example_test') %}
|
|
|
|
{% set result = ab_test_result('example_test') %}
|
|
|
|
{% set value = ab_test_value('example_test') %}
|
|
|
|
|
|
|
|
{# ... #}
|
|
|
|
{% endif %}
|
|
|
|
```
|
2022-05-21 20:24:12 +02:00
|
|
|
|
|
|
|
## Global A/B Test
|
|
|
|
|
|
|
|
If you need to perform an A/B test everywhere, you need to create a specific listener:
|
|
|
|
|
2023-02-09 21:50:06 +01:00
|
|
|
```php-inline title="src/EventListener/CustomAbListener.php"
|
2022-05-21 20:24:12 +02:00
|
|
|
namespace App\EventListener;
|
|
|
|
|
|
|
|
use App\Core\EventListener\AbListener as EventListener;
|
|
|
|
use Symfony\Component\HttpFoundation\Request;
|
|
|
|
use Symfony\Component\HttpKernel\Event\RequestEvent;
|
|
|
|
|
|
|
|
class CustomAbListener extends EventListener
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* {@inheritdoc}
|
|
|
|
*/
|
|
|
|
protected function supports(Request $request): bool
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* {@inheritdoc}
|
|
|
|
*/
|
|
|
|
protected function getAbTestCode(): string
|
|
|
|
{
|
|
|
|
return 'my_global_ab_test_code';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
`CustomAbListener` must be registred:
|
|
|
|
|
2023-02-09 21:50:06 +01:00
|
|
|
```yaml title="config/services.yml"
|
2022-05-21 20:24:12 +02:00
|
|
|
services:
|
|
|
|
# ...
|
|
|
|
|
|
|
|
App\EventListener\CustomAbListener;
|
|
|
|
tags:
|
|
|
|
- { name: kernel.event_listener, event: kernel.request }
|
|
|
|
- { name: kernel.event_listener, event: kernel.response }
|
|
|
|
```
|