为PHP 5.3+提供的简单、现代且直观的单元测试框架

该包的官方仓库似乎已不存在,因此该包已被冻结。

3.3.0 2018-03-15 22:46 UTC

README

atoum's logo

atoum Package version Build Status Build status Coverage Status StyleCI Gitter

一个简单、现代且直观的PHP单元测试框架!

类似于SimpleTest或PHPUnit,atoum 是一个针对 PHP 语言的特定单元测试框架。然而,它从一开始就被设计为以下想法:

  • 可以快速实现
  • 简化测试开发
  • 允许编写可靠、易读和清晰的单元测试。

为了实现这一目标,它大量使用由PHP提供的功能,为开发者提供了一种全新的编写单元测试的方式。因此,它可以非常容易地安装和集成到现有项目中,因为它只包含一个单个PHAR存档,这是开发者的唯一入口点。此外,得益于其流畅的接口,它允许以接近自然语言的方式编写单元测试。它还通过智能使用匿名函数和闭包,使得在测试中实现存根变得更加容易。《atoum》默认情况下,在单独的PHP进程中执行每个单元测试,以确保隔离。当然,它也可以无缝地用于持续集成,并且由于其设计,它很容易满足特定需求。《atoum》在执行测试时不会影响性能,因为它已被开发出来,在允许加快测试执行的同时,具有较小的内存占用。它还可以生成XUnit格式的单元测试执行报告,这使得它与诸如Jenkins等持续集成工具兼容。《atoum》还可以生成代码覆盖率报告,以便监督单元测试。最后,尽管它主要在UNIX上开发,但它也可以在Windows上运行。

为什么选择《atoum》?

  • 《atoum》的安装非常简单:安装,从GitHub克隆,下载其PHAR,或者简单地使用composer
  • 《atoum》在测试执行期间提供了高级别的安全性,通过在各自的PHP进程中隔离每个测试方法,确保测试的安全性。当然,这个特性是默认提供的,无需安装任何额外的扩展。
  • 《atoum》在并行环境中运行测试,利用现代多核CPU的优势,尽可能快地运行测试套件。
  • 《atoum》提供了一组功能齐全的、自然且富有表现力的断言,使得测试尽可能易于阅读。以下是一个示例。
<?php

$this
    ->integer(150)
        ->isGreaterThan(100)
        ->isLowerThanOrEqualTo(200)
;
  • 《atoum》支持类似BDD的语法,具有许多结构化关键词。
<?php

$this
    ->given($testedInstance = new testedClass())
    ->and($testedClass[] = $firstValue = uniqid())
    ->then
        ->sizeof($testedInstance)->isEqualTo(1)
        ->string($testedClass[0])->isEqualTo($firstValue)
;
  • 《atoum》提供了一个简单而强大的存根引擎
<?php

$this
    ->given($testedInstance = new testedClass())
    ->and($aMock = new \mock\foo\bar()) // here a mock of the class \foo\bar is created dynamically
    ->and($this->calling($aMock)->doOtherThing = true) // each call to doOtherThing() by the instance will return true
    ->and($testedInstance->setDependency($aMock))
    ->then
        ->boolean($testedInstance->doSomething())->isTrue()
        ->mock($aMock)
            ->call('doOtherThing')->withArguments($testedInstance)->once() // Asserts that the doOtherThing() method of $aMock was called once
;
  • 《atoum》提供了一个清晰的API,用于断言异常。
<?php

$this
    ->given($testedInstance = new testedClass())
    ->and($aMock = new \mock\foo\bar()) // here a mock of the class \foo\bar is created dynamically
    ->and($this->calling($aMock)->doOtherThing->throw = $exception = new \exception()) // Call to doOtherThing() will throw an exception
    ->and($testedInstance->setDependency($aMock))
    ->then
        ->exception(function() use ($testedInstance) { $testedInstance->doSomething(); })
            ->isIdenticalTo($exception)
;
  • 《atoum》还允许您模拟原生PHP函数。同样,这也是默认提供的。
<?php

$this
    ->given($this->function->session_start = false)
    ->and($session = new testedClass())
    ->then
        ->exception(function () use ($session) { $session->start(); })
            ->isInstanceOf('project\namespace\exception')
            ->hasMessage('Unable to start session')
        ->function('session_start')->wasCalled()->once()
;
  • 《atoum》能够生成TAP、clover、xUnit等多种报告,可以轻松集成到Jenkins或其他任何持续集成工具中。
  • 《atoum》支持数据提供者
  • 《atoum》的测试支持自动运行:只需包含atoum运行器,并使用php path/to/test/file.php启动您的测试。
  • 《atoum》的配置文件仅使用PHP编写(没有XML、YAML或其他格式),提供了最佳的可扩展性。
<?php

$script->addDefaultArguments('--test-it', '-ncc');

$runner->addTestsFromDirectory(__DIR__ . '/tests/units/classes');

$testGenerator = new mageekguy\atoum\test\generator();
$testGenerator
    ->setTestClassesDirectory(__DIR__ . '/tests/units/classes');
    ->setTestClassNamespace('mageekguy\atoum\tests\units');
    ->setTestedClassesDirectory(__DIR__ . '/classes');
    ->setTestedClassNamespace('mageekguy\atoum')
    ->setRunnerPath(__DIR__ . '/scripts/runner.php')
;

$runner->setTestGenerator($testGenerator);
  • 《atoum》提供了一个自动测试模板生成器。
  • 《atoum》提供了一个循环模式,可以轻松重新触发失败的测试。
  • 《atoum》还包含许多其他有趣的功能,您将在使用过程中逐渐发现。

使用 atoum 的先决条件

atoum 绝对需要 PHP >= 5.6.0 或更高版本才能运行。在 UNIX 上,为了检查您是否安装了正确的 PHP 版本,您只需在终端中运行以下命令

$ php -v | grep -oE 'php 5\.3\.(?:[3-9]|[1-9][0-9])|5\.[4-6]\.[0-9]+|[5-7]\.[0-9]+\.[0-9]+'

如果显示 PHP 5.6.x 或等效版本,则表示已安装正确的 PHP 版本。如果您想使用 atoum 的 PHAR 存档,还需要 PHP 来访问 phar 模块,该模块通常默认可用。在 UNIX 上,为了检查是否安装了此模块,您只需在终端中运行以下命令

$ php -m | grep -i phar

如果显示 Phar 或等效版本,则表示模块已正确安装。要生成 Xunit 格式的报告,需要 xml 模块。在 UNIX 上,为了检查是否安装了此模块,您只需在终端中运行以下命令

$ php -m | grep -i xml

如果显示 Xml 或等效版本,则表示模块已正确安装。如果您希望监控单元测试对代码的覆盖率,则需要 Xdebug 2.3 模块。在 UNIX 上,为了检查是否安装了此模块,您只需在终端中运行以下命令

$ php -v | grep -oi 'xdebug'

如果显示 Xdebug 或等效版本,则表示模块已正确安装。

5 分钟即可投入使用的单元测试框架!

第 1 步:安装 atoum

您只需下载 其 PHAR 存档 并将其存储在您希望的位置,例如 /path/to/project/tests/atoum.phar。此 PHAR 存档包含通过 atoum 的所有单元测试的最新开发版本。atoum 的源代码也通过 GitHub 仓库 提供。要检查 atoum 是否与您的配置正确工作,您可以执行其所有单元测试。为此,您只需在终端中运行以下命令

$ php atoum.phar --test-it

第 2 步:编写您的测试

使用您首选的文本编辑器,创建文件 path/to/project/tests/units/helloWorld.php 并添加以下代码

<?php

namespace vendor\project\tests\units;

require_once 'path/to/atoum.phar';

include_once 'path/to/project/classes/helloWorld.php';

use mageekguy\atoum;
use vendor\project;

class helloWorld extends atoum\test
{
    public function testSay()
    {
        $helloWorld = new project\helloWorld();

        $this->string($helloWorld->say())->isEqualTo('Hello World!');
    }
}

第 3 步:使用命令行运行您的测试

启动终端并运行以下命令

$ php path/to/test/file[enter]

您应该得到以下结果或等效结果

> atoum version XXX by Frédéric Hardy.
Error: Unattended exception: Tested class 'vendor\project\helloWorld' does not exist for test class 'vendor\project\tests\units\helloWorld'

第 4 步:编写与您的测试对应的类

再次使用您首选的文本编辑器,创建文件 path/to/project/classes/helloWorld.php 并添加以下代码

<?php

namespace vendor\project;

class helloWorld
{
    public function say()
    {
        return 'Hello World!';
    }
}

第 5 步:再次运行您的测试

在相同的终端中,再次运行以下命令

$ php path/to/test/file[enter]

您应该得到以下结果或等效结果

> atoum version 288 by Frédéric Hardy.
> Run vendor\project\tests\units\helloWorld...
[S___________________________________________________________][1/1]
=> Test duration: 0.00 second.
=> Memory usage: 0.25 Mb.
> Total test duration: 0.00 second.
> Total test memory usage: 0.25 Mb.
> Code coverage value: 100.00%
> Running duration: 0.08 second.
> Success (1 test, 1 method, 2 assertions, 0 error, 0 exception)!

第 6 步:完成您的测试,并从第 3 步重新开始循环

<?php

namespace vendor\project\tests\units;

require_once 'path/to/atoum.phar';

include_once 'path/to/project/classes/helloWorld.php';

use mageekguy\atoum;
use vendor\project;

class helloWorld extends atoum\test
{
    public function test__construct()
    {
        $helloWorld = new project\helloWorld();

        $this
            ->string($helloWorld->say())->isEqualTo('Hello!')
            ->string($helloWorld->say($name = 'Frédéric Hardy'))->isEqualTo('Hello ' . $name . '!')
        ;
    }
}

进一步学习

atoum 的文档仍在编写中。任何有助于改进它的帮助都将受到欢迎。然而,如果您想立即进一步探索 atoum 的可能性,我们建议

  • 在您的终端中运行以下命令之一:php atoum.phar -h,或命令 php scripts/runner.php -h,
  • 探索 atoum 源代码中的 configurations 目录的内容,因为它包含配置文件样本,
  • 探索 atoum 源代码中的 tests/unit/classes 目录的内容,因为它包含所有单元测试,
  • 阅读关于它的(法语)会议幻灯片,可在网上找到,
  • 阅读(法语)wiki
  • 加入 Freenode 网络上的 ##atoum IRC频道,
  • 通过邮箱地址 support[AT]atoum(DOT)org 提出问题。

故障排除

atoum 的 PHAR存档似乎无法工作

在这种情况下,您首先想做的就是确认您是否有存档的最新版本。您只需重新下载它即可。如果它仍然不起作用,请在终端窗口中运行以下命令

$ php -n atoum.phar -v

如果您得到 atoum 的版本号,那么问题来自您的 PHP配置。在大多数情况下,原因可能在于与 PHAR 格式不兼容的扩展,或者作为安全措施阻止执行 PHAR 存档的扩展。例如,ioncube 扩展似乎与 PHAR 存档不兼容,因此如果您正在使用它,您必须通过在 php.ini 中取消注释以下行来禁用它,通过使用 ; 字符来添加前缀

zend_extension = /path/to/ioncube_loader*.*

suhosin 扩展阻止执行 PHAR 存档,因此必须修改其默认配置才能使用 atoum,您可以在 php.ini 文件中添加以下行

suhosin.executor.include.whitelist="phar"

最后,如果在运行 atoum 时屏幕显示类似 ???% 的字符,这将是由于您的 php.ini 文件中的 detect_unicode 指令设置为 1。要修复问题,您只需通过编辑您的 php.ini 文件或通过以下命令运行 atoum 将它设置为 0

$ php -d detect_unicode=0 atoum.phar [options]

如果这三个操作不允许 atoum 工作,我们建议您将详细描述您的配置和问题的电子邮件发送到地址 support[AT]atoum(DOT)org。您还可以在 Freenode 网络上的 ##atoum IRC 频道上寻求 atoum 开发人员的帮助。

错误:常量 __COMPILER_HALT_OFFSET__ 已经在 /path/to/atoum.phar 中定义

这个错误来自 atoum PHAR 存档在您的代码中使用 includerequire 在多个地方包含的事实。要修复这个问题,您只需使用 include_oncerequire_once 仅包含存档,以确保它不会被多次包含。

APC 似乎与 atoum 不兼容

APC 是一个免费、开源且健壮的框架,用于缓存和优化 PHP 中间代码,以 PHP 扩展的形式发布。在测试使用 APC 的类时,您可能会得到一些错误消息,显示 apc_fetch 函数无法检索值。与所有 PHP 扩展一样,APC 有一些配置选项可以启用它

  • apc.enabled 是否启用或禁用 APC。
  • apc.enable_cli,是否启用或禁用 PHP CLI 的 APC。

为了使用 APCatoum,您必须将 apc.enabledapc.enable_cli 设置为 1,否则,它不会为 atoum 所使用的 PHP CLI 版本启用。

在模拟对象时出现段错误

当使用 atoum 和模拟对象时,有时会收到来自 PHP 的段错误。这些段错误是由版本低于 2.1.0 的 XDebug 引起的,该版本在某些情况下处理反射存在问题。要检查 XDebug 的当前版本,您可以运行 php -v。要解决这个问题,您必须将 XDebug 更新到最新 稳定版本。如果您无法在您的系统上更新 XDebug,您仍然可以禁用该扩展以避免出现段错误。要确保 XDebug 已成功更新或禁用,您可以运行 php -v。当您完成更新或禁用 XDebug 后,运行 php atoum.phar --test-it 以确保所有段错误都已消失,并且 atoum 正在正常工作。

路线图

正在寻找路线图?

  • 这里 是正在进行的工作,
  • 而那里 是下一个版本中将出现的功能。

致谢

atoum 是由 Frédéric Hardy 创建的。它现在由一个强大的贡献者社区领导。您可以在 提交者列表 或在 贡献者团队 中找到他们。

许可

atoum 在 BSD-3-Clause 许可下发布。有关详细信息,请参阅捆绑的 LICENSE 文件。