大多数人都知道测试您的网站是个好主意,但一段时间后测试可能会变得乏味。如果很多测试过程可以自动化,这样你就不必一次又一次地手动检查每个函数,以确保它在更新代码后仍然有效,那会怎么样?这就是单元测试的用武之地,以自动化测试过程。

单元测试使修改代码变得更容易,最重要的是更安全,因为它可以捕获新代码中可能引入的行为中的任何异常(即错误)。在本文中,您将学习使用 PHPUnit 进行单元测试的绝对基础知识,以及开始使用它是多么容易,因为我将指导您完成编写第一个测试的过程。

在开始编写第一个单元测试之前,您需要安装 PHPUnit。它可以使用PEAR安装程序轻松安装

编写您的第一个测试

现在是时候亲自动手编写您的第一个测试了!首先,你需要测试一些东西,所以在第一个例子中,我写了一个非常简单的PHP类来表示一个用户:

解释
<?php class User { protected $name; public function getName() { return $this->name; } public function setName($name) { $this->name = $name; } public function talk() { return "Hello world!"; } }

假设您希望确保用户始终打招呼;例如,如果她突然开始像猫一样喵喵叫,那将是毁灭性的!

为此,您需要创建一个新的测试类,我将其任意命名为 .你怎么称呼你的测试类并不重要,但通常以你正在测试的类命名它们是一个好主意。UserTest

要创建测试类,您需要包含要测试的类以及 PHPUnit 的自动加载功能。然后定义扩展的测试类。PHPUnit_Framework_TestCase

解释
<?php require_once "PHPUnit/Autoload.php"; require_once "User.php"; class UserTest extends PHPUnit_Framework_TestCase { }

这是您将在其中编写测试的类,每个测试都有自己的方法。

中定义的方法正是您假设的,它断言某物是否相等。由于 是 的子类,因此可以将其与 一起使用。assertEquals()PHPUnit_Framework_TestCaseUserTestPHPUnit_Framework_TestCase$this

若要确保用户说出适当的问候语,请编写以下方法:

解释
<?php ... class UserTest extends PHPUnit_Framework_TestCase { // test the talk method public function testTalk() { // make an instance of the user $user = new User(); // use assertEquals to ensure the greeting is what you $expected = "Hello world!"; $actual = $user->talk(); $this->assertEquals($expected, $actual); } }

设置和拆卸

需要在每种测试方法中设置新用户可能会变得非常乏味。这就是 PHPUnit 的灯具可以提供帮助的地方。夹具是指设置特定状态,每次测试后状态都会重置回原样。这是如何工作的?

假设你有你的对象,并且你重写了继承的方法:$usersetUp()

解释
<?php ... class UserTest extends PHPUnit_Framework_TestCase { protected $user; ... protected function setUp() { $this->user = new User(); $this->user->setName("Tom"); } }

在这里,你已实例化了用户并将其名称设置为 Tom。

完成所有测试后,您可能希望取消设置用户;为此,您可以重写该方法:tearDown()

解释
<?php ... class UserTest extends PHPUnit_Framework_TestCase { ... protected function tearDown() { unset($this->user); } ... }

PHPUnit 在每次测试之前和之后都会调用 and 方法,因此您可以跳过在测试方法中实例化用户。 现在变为:setUp()tearDown()testTalk()

解释
<?php ... class UserTest extends PHPUnit_Framework_TestCase { ... public function testTalk() { $expected = "Hello world!"; $actual = $this->user->talk(); $this->assertEquals($expected, $actual); } }

运行测试

现在你已经有一个定义所有测试的测试类,运行它们不是很好吗?如果您已成功安装所有内容,则应该能够简单地从终端运行测试。

michelle@testbed:~$ phpunit UnitTest UserTest.php
PHPUnit 3.6.3 by Sebastian Bergmann.

.

Time: 0 seconds, Memory: 5.75Mb

OK (1 test, 1 assertion)

祝贺!您现在已经使用 PHPUnit 编写并运行了您的第一个单元测试!

你看到那里的小点了吗?对于每次测试运行,都会有一个字符指示结果。字符如下:

  • .– 测试成功时打印。
  • F – 断言失败时打印。
  • E – 在运行测试时发生错误时打印。
  • S – 跳过测试时打印。
  • I – 当测试标记为不完整时打印。

现在,您需要担心的两个最重要的问题是点和 F,因为它们表明您的测试是成功还是失败。

当测试失败时

那么,当测试失败时会发生什么?让我们改变一下,这样他们实际上会说一些完全出乎意料的话,比如“blubb”。User

解释
<?php class User { ... public function talk() { return "blubb"; } }

现在像以前一样运行测试。

michelle@testbed:~$ phpunit UnitTest UserTest.php
PHPUnit 3.6.3 by Sebastian Bergmann.

F

Time: 0 seconds, Memory: 5.75Mb

There was 1 failure:

1) UserTest::testTalk
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-Hello World!
+blubb

/PHPUnit introduction/tests/UserTest.php:23

FAILURES!
Tests: 1, Assertions: 1, Failures: 1.

如您所见,F 符号表示失败。还有关于失败的更多信息,你可以看到它失败了,断言两个字符串相等;它期待“Hello World!”,但得到了“blubb”。

总结

在本文中,你发现开始进行单元测试并不难。基础知识非常简单。然而,单元测试远比我们看到的要多得多。这个简单的测试情况应该足以让你开始编写自己的测试,但请尝试扩展它,出现错误并未通过测试。尝试扩展类并为其编写其他测试。添加 、 或 属性怎么样?Userheighthair_colorbirthday

我可以提供一些有用的提示,这些提示将在此过程中为您提供帮助:

  • 尝试在终端中调用,看看你可以用 PHPUnit 做什么。phpunit --help
  • 如果你想知道如何测试一些特定的东西,PHPUnit手册实际上非常好。我简要提到了夹具,手册中有完整的描述
  • 当您刚开始时,涵盖断言的手册部分真的很震撼。请务必检查一下。

如果要从本文中下载测试代码进行试验,可以在 GitHub 上随心所欲地使用它。

我希望本教程能帮助您开始使用 PHPUnit。尝试一下,从错误中吸取教训,不要害怕提出任何问题,最重要的是玩得开心!

编者注 2012 年 10 月 19 日:GitHub 上提供的随附代码已更新为使用 Composer 下载 PHPUnit 依赖项。require 语句已更改为调用 vendor/autoload.php 来采购自动加载程序。可以通过导航到 tests 目录并调用 .. 来运行测试。/vendor/bin/phpunit 单元测试UserTest.php。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
小程序二维码

微信小程序

微信扫一扫体验

立即
投稿
公众号二维码

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部