packico / abtest
灵活且不依赖框架的AB测试库。
Requires
- php: >=5.4.0
- colinmollenhour/credis: 1.7.*
- mobiledetect/mobiledetectlib: ^2.8
Requires (Dev)
- codacy/coverage: dev-master
- mockery/mockery: 0.9.*
- phpunit/php-code-coverage: 2.2.*
- phpunit/phpunit: 4.8.*
This package is auto-updated.
Last update: 2022-01-21 22:17:18 UTC
README
#Pachico/Abtest
灵活且不依赖框架的AB测试库。
它包含内置功能,但接受自定义行为注入。
目录
##通过composer安装
composer require pachico/abtest
简单场景
该包旨在强大且完全可配置,但在理想情况下,您可能只需这样的实现
use \Pachico\Abtest; $abtest_engine = new Abtest\Engine( new Abtest\Config\FromFile('path/to/config.php') );
与测试的交互将非常简单
if ($abtest_engine->getTest('your-test')->isParticipant()) { ... if (1 === $abtest_engine->getTest('your-test')->getVersion()) { // Variation version code } else { // Control version code } }
主要概念
在深入示例之前,描述该库中的主要角色非常重要。
配置器
这些类加载测试及其依赖项,并向 Engine 提供一个配置对象。您可以指定配置文件的路径,提供数组或使用链式版本设置它。
测试
测试 是在您的 Web 应用程序中运行的单独的 A/B 测试。此库允许您拥有尽可能多的测试,每个测试都具有独特的特性。
分割
分割 类根据它们自己的逻辑为每个 A/B 测试分配一个版本,每个新用户都有自己的版本。此库包含概率实现。这些可以设置为一个简单的数组,使用 ArrayProbability([50, 50]) 或从 Redis 中获取以实现更动态的节流,使用 RedisArrayProbability()。
内存
我们称 内存 为将存储用户测试版本的类。对于大多数情况,将值存储在 cookie 中就足够了,但是,通常将其存储在会话中。大多数框架都有自己的会话实现,因此此库不提供内置的会话实现,因为它们可能不兼容。如果您需要/需要特定的会话实现,请告诉我。
分段
在运行测试时,您可能不希望对所有受众都运行测试,而只想针对使用特定设备、语言或来源国家的用户。指定分段不是强制性的,但如果需要,可以使用基于用户代理的内部分段 ByDevice()。如果需要自定义分段,可以轻松编写一个实现 SegmentationInterface 的分段并注入。
跟踪
如果不能跟踪AB测试的结果,那么AB测试就毫无意义。跟踪类是负责为分析目的注册AB测试的类。这个库包含一个名为GoogleExperiments
的类,它可以返回要包含在要跟踪的网页中的跟踪代码,以便在Google Analytics中进行跟踪。更多的Tracking
实现需要使用TrackingInterface
并简单注入。
API
为了简化,我们在示例中省略了命名空间的使用\Pachico\Abtest。
use \Pachico\Abtest;
实例化和配置器
Engine类需要传递一个配置器给它来构造
/* @var $configurator Config\ConfiguratorInterface */ $engine = new Abtest\Engine($configurator);
从配置文件
您可以通过提供包含测试和依赖项定义的配置文件的路径来提供配置文件。
$engine = new Abtest\Engine( new Abtest\Config\FromFile('path/to/config.php') );
配置文件可能如下所示
use \Pachico\Abtest\Segmentation, \Pachico\Abtest\Split, \Pachico\Abtest\Tracking, \Pachico\Abtest\Memory; // Configuration array return [ // Array containing each test 'tests' => [ // First test name 'TEST_FOO' => [ // Segmentation policy // (in this case, only desktop devices) 'segmentation' => new Segmentation\ByDevice('desktop'), // Traffic splitting policy // (in this case, random 33% chances each version) 'split' => new Split\ArrayProbability([50, 50, 50]), // Tracking id for Google Experiments 'tracking_id' => 'ID_FOO', ], // Second test name 'TEST_BAR' => [ // Segmentation policy // (in this case, only mobile devices) 'segmentation' => new Segmentation\ByDevice('mobile'), // Traffic splitting policy // (in this case, fetches in Redis chances) 'split' => new Split\RedisArrayProbability('test_bar', 'ABTESTS:', ['host' => '127.0.0.1']), // Tracking id for Google Experiments 'tracking_id' => 'ID_BAR', ] ], // Storage memory for users // (in this case, cookie based) 'memory' => new Memory\Cookie('abtests'), // Tracking class // (in this case, Google Experiments) 'tracking' => new Tracking\GoogleExperiments(true) ];
一开始可能看起来很复杂,但这种粒度级别提供了灵活性和实现您自己的策略和功能的能力。将其视为某种依赖注入容器。
为了方便(并避免拼写错误),您可以在
Config\ConfiguratorInterface
中找到表示配置键的常量,例如('tests','segmentation'等)。
从配置数组
您也可以将典型配置文件的内容传递给适当的配置器
/* @var $config array */ $engine = new Abtest\Engine( new Abtest\Config\FromArray($config) );
配置文件的内容如上所述,在从配置文件中。
链式配置器
您可能会发现使用链式类创建配置更方便。
$configurator = new Abtest\Config\Chainable( new Abtest\Memory\Cookie('ABTESTS'), new Abtest\Tracking\GoogleExperiments(true) ); $configurator ->addTest('test1', new Abtest\Split\ArrayProbability([50, 50]), null, 'test1_tracking_id') ->addTest('test2', new Abtest\Split\ArrayProbability([50, 50]), null, 'test2_tracking_id'); $engine = new Abtest\Engine($configurator);
拆分器
从数组中获取概率
如果您想有一个随机的概率拆分策略,您可以使用ArrayProbability
类。
new Abtest\Split\ArrayProbability([50, 50]);
用户落在特定版本的概率由分配给每个版本的整数确定。控制是第一个数组值,变体1是第二个值,依此类推。==是的,这意味着您可以有无限的变化,每个变化都有特定的权重。==
上面的示例表示一个具有控制版本
和一个变体
的测试,其中每个版本都有50%的机会被选中。
使用像[100, 100]或[500, 500]这样的数字也是如此,因为概率是相对于所有变体的总和进行加权的。
从Redis中的数组获取概率
使用这个类,您可以从Redis中获取概率数组。您可能想要这样做,以避免仅仅为了改变拆分策略而进行版本发布。
new Split\RedisArrayProbability('test_key', 'ABTESTS:', [ 'host' => '127.0.0.1' ]),
内部,它实现了Credis,即使您没有安装php扩展也能连接到Redis(尽管推荐这样做,以提高性能)。您可以为Redis中的所有键指定前缀和连接参数。查看phpdoc以获取有关要发送的参数的更多详细信息。
作为替代,您也可以注入Redis连接,而不是配置数组
new Split\RedisArrayProbability('test_key', 'ABTESTS:', $redis_connection),
自定义拆分器
您始终可以创建自己的分割器。您只需要实现 Split\SplitInterface 并从配置/ors 中注入它们。
分割
分割允许您为每个 A/B 测试选择受众。这个库允许您通过用户的设备类型来过滤用户。
按设备
要按设备过滤,只需使用
new Segmentation\ByDevice(Segmentation\ByDevice::DEVICE_NOT_MOBILE)
其他过滤器包括
Segmentation\ByDevice::DEVICE_DESKTOP; Segmentation\ByDevice::DEVICE_TABLET; Segmentation\ByDevice::DEVICE_MOBILE; Segmentation\ByDevice::DEVICE_NOT_DESKTOP; Segmentation\ByDevice::DEVICE_NOT_MOBILE;
它内部使用 Mobile_Detect 库,因此可以过滤得更多。
自定义分割
您始终可以创建自己的分割。您只需要实现 Segmentation\SegmentatIoninterface 并从配置/ors 中注入它们。
内存
这些类将用户版本存储在用户空间中。
Cookie
此类将在用户的浏览器中存储他们参与的每个测试的版本。
new Memory\Cookie('ABTESTS', 2592000)
第一个参数表示将保存版本的 cookie 名称,第二个参数是给定 cookie 的 TTL(以秒为单位)。
自定义内存
您始终可以创建自己的内存类。您只需要实现 Memory\MemoryInterface 并从配置/ors 中注入它们。
跟踪
跟踪可能会返回跟踪代码,将结果保存到某个地方,或者实现您需要的任何操作。
Google Experiments
Google Experiments 需要打印 JavaScript 以匹配会话和版本。
new Tracking\GoogleExperiments(true);
当将 true 传递给构造函数时,它将返回 GoogleExperiments 的 JavaScript 源代码。
当使用此跟踪时,需要提供 tracking_id 参数给测试。如果没有提供,这是默认的跟踪策略。
结果将由
echo $engine->track();
提供,结果将类似于以下内容
<script src="//#/cx/api.js"></script> <script>cxApi.setChosenVariation(0, 'colour_tracking_id');</script> <script>cxApi.setChosenVariation(1, 'size_tracking_id');</script>
自定义跟踪
您始终可以创建自己的跟踪类。您只需要实现 Tracking\TrackingInterface 并从配置/ors 中注入它们。
引擎和测试
一旦实例化了引擎,您可以通过这种方式访问每个单独的测试
$engine->getTest('yourtest');
对于每个测试,您可以询问用户是否参与测试
$engine->getTest('yourtest')->isParticipant();
以及用户正在哪个版本的测试中
$abtest_engine->getTest('yourtest')->getVersion();
版本将是整数,其中 0 是您的控制版本,1 是第一个变体,等等。
##示例
请查看 examples 文件夹以查看实际案例场景。
联系和贡献
请随时通过 nanodevel@gmail.com 或在 Github 上联系我,以修复错误、提出疑问、提出请求或进行贡献。
加油