1

我是 PHPUnit 的新手,事实上我是从今天开始的。而且,就我一直在阅读的内容而言,我开始了解这个脚本的作用。

class UserTest extends PHPUnit_Framework_TestCase
{
     protected $user;

    // test the talk method
    protected function setUp() {
        $this->user = new User();
        $this->user->setName("Tom");
    }

    protected function tearDown() {
        unset($this->user);
    }

 public function testTalk() {
        $expected = "Hello world!";
        $actual = $this->user->talk();
        $this->assertEquals($expected, $actual);
    }

}

对于这个类:

<?php
class User {
    protected $name;

    public function getName() {
        return $this->name;
    }

    public function setName($name) {
        $this->name = $name;
    }

    public function talk() {
        return "Hello world!";
    }
} 

好的,所以我已经确定测试基于测试的相等性返回一个 Ok/Fail 语句,但我正在寻找更多。我需要一种实际的方法来测试一个更复杂的类,它的结果与这个例子不同,不能轻易猜到。

比如说,我编写了一个执行轮询的脚本。我将如何或以什么方式测试方法/类是否可以工作?上面的代码只显示了一个方法的结果是否只有'Hello World'但是,这太容易测试了,因为我需要测试复杂的东西,而且没有太多的教程。

4

2 回答 2

7

在单元测试中测试一个类应该不复杂。

之所以如此,是因为在一个设计良好的系统中,您可以单独测试该类,而不要在该类后面增加系统的复杂性——因为该系统在测试期间不存在,它被模拟了.

典型的例子是 User 类通常向数据库询问信息,但在测试用例中,该数据库真的很难设置、准备数据以及事后销毁。使用真正的数据库也会减慢速度。因此,您将 User 类设计为从外部接受一个数据库对象,并在测试用例中为它提供一个数据库的模拟对象。

这样,模拟数据库的各种返回值真的很简单,而且您可以检查数据库对象是否获得正确的参数,而无需处理真实数据库的复杂性。

如果您的类被设计为允许依赖注入,则只能进行适当的模拟对象注入。这是一个原则,不要在其他对象内部创建对象,而是需要外部世界提供它们。只需快速查看一些视频以进行解释:

请记住,创建好的测试需要一些经验。很适合你开始尝试。

于 2013-08-10T18:59:29.523 回答
4

但是,这太容易测试了,因为我需要测试复杂的东西,而且没有太多的教程。

越复杂,测试就越复杂。这有点像蛇咬自己的一端。您通常希望防止这种情况发生,因此要使其成为黄金:编写简单的测试以确保测试和运行复杂的软件。

这并不总是 100% 有效,但它比没有测试时效果更好。PHPUnit 是为单元测试(Xunit 测试模式)而设计的,但您也可以使用它来运行不同的测试。为此,您将测试分组。根据不同的事情,不同的人会采取不同的做法。例如:

  1. 小测试
  2. 中等测试
  3. 大型测试

或(不等效):

  1. 单元测试
  2. 集成测试
  3. 验收测试

或(也许等效的 TestPyramid):

  1. 单元测试
  2. 服务测试
  3. 用户界面测试

什么不是。当您开始测试时,最好从单元测试开始,正如Sven 已经回答的那样,保持它们简单。熟悉 TDD,阅读一些幻灯片和书籍。欢迎来到自动化测试的世界。

PS 是的,简单的 getter setter 太容易测试了。如果 setter 所做的只是存储到私有成员并且 getter 将其取回,那么您可以相信 PHP 正在工作,为此编写测试是浪费时间并且只会导致麻烦。它清楚地表明有人在编写代码后编写了测试。而是先编写测试并看到它失败(红色),然后尽快将代码组合在一起以使测试通过(绿色)。您可以稍后改进代码,因为测试已经表明它正在工作。

于 2013-08-12T05:39:56.277 回答