dbstudios / analyst
受GitHub的Scientist启发的功能测试库
2.0.1
2016-01-27 22:41 UTC
Requires
- php: >= 5.6
Requires (Dev)
- phpunit/phpunit: 5.1.*
- satooshi/php-coveralls: 1.0.*
This package is auto-updated.
Last update: 2024-09-19 09:40:51 UTC
README
Analyst
一个受GitHub的Scientist启发的PHP功能测试库。
请注意,这个README是一个正在进行中的工作,可能包含不完整的信息。
安装
$ composer require dbstudios/analyst
我该如何分析?
让我们假设你有一个大型网络应用,你正在改变验证用户访问页面权限的方式。
class MyController { public function isAllowed(User $user, $slug) { return Experiment::create('user-allowed') ->setContext([ 'user' => $user, // context ignores keys, however it's helpful to use keys to "flag" what each variable means 'slug' => $slug, ]) ->control(function(User $user, $slug) { return $user->isAdmin() || $user->getPermissions()->contains('view.page.' . $slug); }) ->candidate(function(User $user, $slug) { return $user->getPermissionProvider()->isAccessAllowed($slug); }) ->run(); } }
就是这样!Experiment
类的run
方法将始终返回你的控制结果。你的控制和候选者都将运行,Analyst将记录这两段代码发生的情况。在下一节中,我们将看看你可以如何使用这些信息。
发布实验结果
如果我们不对从实验中获得的信息进行处理,测试多个代码路径就毫无意义。这就是发布发挥作用的地方。你所要做的就是在一个自定义的Experiment
类中实现那个publish
方法。
class MyExperiment extends Experiment { private $db; private $stmt; public function __construct(PDO $db, $name = 'experiment') { parent::__construct($name); $this->db = $db; $this->stmt = $db->prepare('insert into experiment_results (name, timestamp, behavior, is_control, execution_time, result) values(:experiment, UTC_TIMESTAMP(), :behavior, :control, :duration, :result)'); $this->stmt->bindValue(':experiment', $name); } public function publish(Result $result) { $behaviors = $result->getCandidates(); array_unshift($candidates, $result->getControl()); $this->db->beginTransaction(); foreach ($behaviors as $behavior) { $this->stmt->bindValue(':behavior', $behavior->getName()); $this->stmt->bindValue(':control', $behavior === $result->getControl(), PDO::PARAM_BOOL); $this->stmt->bindValue(':duration', $behavior->getDuration()); $this->stmt->bindValue(':result', serialize($behavior->getResult()); $this->stmt->execute(); } $this->db->commit(); } public static function create($db, $name = 'experiment') { return new MyExperiment($db, $name); } }
现在,如果我们把之前关于用户权限的例子重写为使用我们的自定义MyExperiment
类,它看起来会是这样。
class MyController { public function isAllowed(User $user, $slug) { return MyExperiment::create($this->getConnection(), 'user-allowed') // set up context, control, and candidate... ->run(); } }
在上面的例子中,我们创建了自己的Experiment
实现,命名为MyExperiment
。我们确保我们有一个数据库连接(使用PHP的PDO
类),并使用publish
方法将数据写入其中。然后,当我们在我们控制器示例中运行实验时,我们只需要向MyExperiment
的create
静态方法提供额外的参数(这是我们自行实现的,以便允许额外的构造函数参数)。
每次实验运行完毕后,Analyst都会始终调用用于分析所使用的实验的publish
方法。我们的选项不仅限于简单的数据库插入。你可能会决定使用像Monolog这样的库将数据记录到文件中,或者你可能将其发送到云服务。这取决于你!