开始使用 PHPUnit

下载

我们用一个 PHP Archive (PHAR) 来包含你需要使用的PHPUnit,可以从这里下载它,使其可执行,并把它放到你的 $PATH 里, 如:

➜ wget http://phar.phpunit.cn/phpunit.phar

➜ chmod +x phpunit.phar

➜ sudo mv phpunit.phar /usr/local/bin/phpunit

➜ phpunit --version
PHPUnit 6.3.0 by Sebastian Bergmann and contributors.

当然您也可以立即使用PHAR下载它,如:

➜ wget http://phar.phpunit.cn/phpunit.phar

➜ php phpunit.phar --version
PHPUnit 6.3.0 by Sebastian Bergmann and contributors.

详情请参阅文档如何 校验 PHPUnit PHAR 发行包 或 如何使用 Composer 来安装 PHPUnit

Code

src/Email.php

<?php
declare(strict_types=1);

final class Email
{
    private $email;

    private function __construct(string $email)
    {
        $this->ensureIsValidEmail($email);

        $this->email = $email;
    }

    public static function fromString(string $email): self
    {
        return new self($email);
    }

    public function __toString(): string
    {
        return $this->email;
    }

    private function ensureIsValidEmail(string $email): void
    {
        if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
            throw new InvalidArgumentException(
                sprintf(
                    '"%s" is not a valid email address',
                    $email
                )
            );
        }
    }
}

Test Code

tests/EmailTest.php

<?php
declare(strict_types=1);

use PHPUnit\Framework\TestCase;

/**
 * @covers Email
 */
final class EmailTest extends TestCase
{
    public function testCanBeCreatedFromValidEmailAddress(): void
    {
        $this->assertInstanceOf(
            Email::class,
            Email::fromString('user@example.com')
        );
    }

    public function testCannotBeCreatedFromInvalidEmailAddress(): void
    {
        $this->expectException(InvalidArgumentException::class);

        Email::fromString('invalid');
    }

    public function testCanBeUsedAsString(): void
    {
        $this->assertEquals(
            'user@example.com',
            Email::fromString('user@example.com')
        );
    }
}



Code

src/Email.php

<?php
declare(strict_types=1);

final class Email
{
    private $email;

    private function __construct(string $email)
    {
        $this->ensureIsValidEmail($email);

        $this->email = $email;
    }

    public static function fromString(string $email): self
    {
        return new self($email);
    }

    public function __toString(): string
    {
        return $this->email;
    }

    private function ensureIsValidEmail(string $email)
    {
        if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
            throw new InvalidArgumentException(
                sprintf(
                    '"%s" is not a valid email address',
                    $email
                )
            );
        }
    }
}

Test Code

tests/EmailTest.php

<?php
declare(strict_types=1);

use PHPUnit\Framework\TestCase;

/**
 * @covers Email
 */
final class EmailTest extends TestCase
{
    public function testCanBeCreatedFromValidEmailAddress()
    {
        $this->assertInstanceOf(
            Email::class,
            Email::fromString('user@example.com')
        );
    }

    public function testCannotBeCreatedFromInvalidEmailAddress()
    {
        $this->expectException(InvalidArgumentException::class);

        Email::fromString('invalid');
    }

    public function testCanBeUsedAsString()
    {
        $this->assertEquals(
            'user@example.com',
            Email::fromString('user@example.com')
        );
    }
}



Code

src/Email.php

<?php


final class Email
{
    private $email;

    private function __construct($email)
    {
        $this->ensureIsValidEmail($email);

        $this->email = $email;
    }

    public static function fromString($email)
    {
        return new self($email);
    }

    public function __toString()
    {
        return $this->email;
    }

    private function ensureIsValidEmail($email)
    {
        if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
            throw new InvalidArgumentException(
                sprintf(
                    '"%s" is not a valid email address',
                    $email
                )
            );
        }
    }
}

Test Code

tests/EmailTest.php

<?php


use PHPUnit\Framework\TestCase;

/**
 * @covers Email
 */
final class EmailTest extends TestCase
{
    public function testCanBeCreatedFromValidEmailAddress()
    {
        $this->assertInstanceOf(
            Email::class,
            Email::fromString('user@example.com')
        );
    }

    public function testCannotBeCreatedFromInvalidEmailAddress()
    {
        $this->expectException(InvalidArgumentException::class);

        Email::fromString('invalid');
    }

    public function testCanBeUsedAsString()
    {
        $this->assertEquals(
            'user@example.com',
            Email::fromString('user@example.com')
        );
    }
}



如果您想理解上面所示的示例之间的差异,那么 "PHP 7 Explained 电子书可能对你有帮助.

如果您想使用示例代码 (PHP 5.6版本) ,您需要下载 https://phar.phpunit.de/phpunit-5.6.phar 而不是 http://phar.phpunit.cn/phpunit.phar.

测试执行

➜ phpunit --bootstrap src/Email.php tests/EmailTest
PHPUnit 6.3.0 by Sebastian Bergmann and contributors.

...                                                                 3 / 3 (100%)

Time: 70 ms, Memory: 10.00MB

OK (3 tests, 3 assertions)

让我们看看上面的调用意味着的三个部分:

  • phpunit 调用命令行测试PHPUnit。我们假定您已下载 phpunit.phar (见上面)并已把phpunit放进你的 $PATH里.

  • --bootstrap src/Email.php 指示PHPUnit命令行测试在测试之前执行 include src/Email.php .

    通常,但是,你使用 --bootstrap 指导PHPUnit命令行测试前包括启动脚本设置 autoloading 对于要测试的类。这样的脚本通常是使用工具来生成的,例如 Composerphpab.

  • tests/EmailTest 指示PHPUnit命令行测试要执行的测试 EmailTest 类声明在 tests/EmailTest.php.

    使用 tests 而不是 tests/EmailTest 将指示PHPUnit命令行执行所有已声明的测试 *Test.php 源代码文件在 tests 目录.

下面,您将看到测试结果的一个可选输出,它使用 --testdox 选项:

➜ phpunit --bootstrap src/Email.php --testdox tests
PHPUnit 6.3.0 by Sebastian Bergmann and contributors.

Email
 [x] 可以从有效的电子邮件地址创建
 [x] 无法从无效电子邮件地址创建
 [x] 可以用作字符串

此输出基于这样一个概念:测试的名称可以用来记录被测试验证的行为。

结论

您已经了解了如何编写简单的单元测试以及如何下载并运行PHPUnit. 更多细节请查看 文档.


推荐购买