elazar/phantestic

一个小型PHP测试框架

0.3.0 2015-10-21 23:30 UTC

This package is auto-updated.

Last update: 2024-08-29 03:58:05 UTC


README

一个旨在简单、快速、现代和灵活的小型PHP测试框架。

目前处于非常初级的alpha状态。您可以随意尝试,但请注意可能会出现错误。

Build Status Code Climate

安装

使用 Composer

{
    "require-dev": {
        "elazar/phantestic": "^0.2"
    }
}

组件

测试加载器 加载要运行的测试。它可以实现 \Traversable (即实现 \IteratorAggregate\Iterator 的类实例,例如 \Generator),以便可迭代加载的测试。

测试运行器 使用测试加载器加载测试,运行它们,并在过程中发出多个事件,测试处理器 可以拦截并对此作出反应。

例如,LocalRunner 在与测试运行器相同的PHP进程中运行测试。其构造函数接受两个参数:要使用的测试加载器和实现 HandlerInterface 的测试处理器对象数组。

当调用其 run() 方法时,LocalRunner 处理向测试处理器对象注入一个 事件发射器,这使得这些对象可以为可能相关的任何事件向发射器注册回调。

一个测试处理器的示例是 CliOutputHandler,它将执行测试的结果输出到 stdout,并在所有测试运行完毕后输出失败摘要。

配置运行器

没有默认的测试运行器;必须根据项目需求进行配置。

以下是一个示例运行器配置。

$classmap_path = '../vendor/composer/autoload_classmap.php';
$loader = new \Phantestic\Loader\ClassmapFileObjectLoader($classmap_path);
$handlers = [ new \Phantestic\Handler\CliOutputHandler ];
$runner = new \Phantestic\Runner\LocalRunner($loader, $handlers);
$runner->run();

ClassmapFileObjectLoader 根据类映射文件的内容定位测试,例如由几个 Composer 命令的 -o 标志生成的文件。默认情况下,它查找以 Test.php 结尾的类文件,实例化类,并调用以 test 开头的方法。可以使用 ClassmapFileObjectLoader 的构造函数参数更改用于根据文件、类和方法名称筛选测试方法以及生成测试用例对象的回调。

编写测试

理论上,测试可以是任何可调用的东西可调用的。测试加载器可能会限制这种可调用的类型(例如,ClassmapFileObjectLoader只支持实例方法)。测试加载器会将测试回调包装在一个实现了TestInterface的类的实例中,例如默认的Test实现。

可以通过抛出异常来指示失败。其他状态可以通过抛出Result的子类的实例来指示。Test将错误转换为异常,并认为任何未捕获的异常都表示失败。同样,未抛出任何异常表示成功。

// src/Adder.php
class Adder
{
    public function add($x, $y)
    {
        return $x + $y;
    }
}

// tests/AdderTest.php
class AdderTest
{
    public function testAdd()
    {
        $adder = new Adder;
        $result = $adder->add(2, 2);
        if ($result != 4) {
            throw new \RangeException('2 + 2 should equal 4');
        }
    }
}

编写测试处理器

测试处理器实现了HandlerInterface,它有一个单独的方法:setEventEmitter()。此方法接收一个EventEmitterInterface的实例作为其唯一参数。在其setEventEmitter()的实现中,测试处理器可以使用此参数来注册事件回调。以下是一个示例,取自CliOutputHandler,它将自己注册为几个事件的回调。

public function setEventEmitter(EventEmitterInterface $emitter)
{
    $emitter->on('phantestic.test.failresult', [$this, 'handleFail']);
    $emitter->on('phantestic.test.passresult', [$this, 'handlePass']);
    $emitter->on('phantestic.tests.before', [$this, 'beforeTests']);
    $emitter->on('phantestic.tests.after', [$this, 'afterTests']);
}

支持的事件可能因所使用的测试加载器和运行器而异。

LocalRunner

  • phantestic.tests.before:在运行任何测试之前,测试运行器作为参数
  • phantestic.tests.after:所有测试运行之后,测试运行器作为参数
  • phantestic.test.before:在每次测试之前,测试用例和运行器作为参数
  • phantestic.test.after:每次测试之后,测试用例和运行器作为参数
  • phantestic.test.failresult:当测试失败时,测试用例和运行器作为参数
  • phantestic.test.passresult:当测试通过时,测试用例和运行器作为参数
  • phantestic.test.RESULT:当测试的结果不是通过或失败时,其中RESULT是扩展Result的类的简短名称,测试用例和运行器作为参数

ClassmapFileObjectLoader

  • phantestic.loader.loaded:当加载测试用例时,测试用例和关联的测试类名以及测试方法名作为参数

与PHPUnit的区别

测试可以是类的实例方法,但不必是,因为单个测试可以是任何可调用的东西。如果您选择使用实例方法进行测试

  • 没有等效于PHPUnit_Framework_TestCase的东西。如果您愿意,可以创建自己的基类,但这不是必需的。
  • 没有等效于setUp()tearDown()的东西。考虑使用__construct()__destruct()或与支持phantestic.test.beforephantestic.test.after的加载器一起使用测试处理器。
  • 如果您希望使用与PHPUnit相同的标准来定位测试,并且您正在使用Composer,只需使用ClassmapFileObjectLoader,并在实例化时指定只包含类映射文件路径即可。
  • 断言只是当期望条件未满足时抛出异常的方法。考虑使用Peridot推荐的补充库,如这些库
  • 原生不支持模拟。考虑使用补充库,如PhakeMockery
  • 原生不支持数据库种子和断言。考虑使用补充库,如PhactoryFaker