為我們的類建立第一個 PHPUnit 測試

想象一下,我們有一個類 Math.php,具有計算 fiobanacci 和階乘數的邏輯。像這樣的東西:

<?php    
class Math {
    public function fibonacci($n) {
        if (is_int($n) && $n > 0) {
            $elements = array();
            $elements[1] = 1;
            $elements[2] = 1;
            for ($i = 3; $i <= $n; $i++) {
                $elements[$i] = bcadd($elements[$i-1], $elements[$i-2]);
            }
            return $elements[$n];
        } else {
            throw new 
                InvalidArgumentException('You should pass integer greater than 0');
        }
    }

    public function factorial($n) {
        if (is_int($n) && $n >= 0) {
            $factorial = 1;
            for ($i = 2; $i <= $n; $i++) {
                $factorial *= $i;
            }
            return $factorial;
        } else {
            throw new 
                InvalidArgumentException('You should pass non-negative integer');
        }
    }
}

最簡單的測試

我們想測試方法 fibonaccifactorial 的邏輯。讓我們用 Math.php 將檔案 MathTest.php 建立到同一目錄中。在我們的程式碼中,我們可以使用不同的斷言 。最簡單的程式碼將是這樣的(我們只使用 assertEqualsassertTrue):

<?php
require 'Math.php';

use PHPUNIT_Framework_TestCase as TestCase;
// sometimes it can be
// use PHPUnit\Framework\TestCase as TestCase;

class MathTest extends TestCase{
    public function testFibonacci() {
        $math = new Math();
        $this->assertEquals(34, $math->fibonacci(9));
    }

    public function testFactorial() {
        $math = new Math();
        $this->assertEquals(120, $math->factorial(5));
    }

    public function testFactorialGreaterThanFibonacci() {
        $math = new Math();
        $this->assertTrue($math->factorial(6) > $math->fibonacci(6));
    }
}

我們可以使用命令 phpunit MathTest 從控制檯執行此測試,輸出將是:

    PHPUnit 5.3.2 by Sebastian Bergmann and contributors.

...                                                                 3 / 3 (100%)

Time: 88 ms, Memory: 10.50Mb

OK (3 tests, 3 assertions)

使用 dataProviders

測試方法可以接受任意引數。這些引數由資料提供者方法提供 。要使用的資料提供程式方法是使用 @dataProvider 註釋指定的。 :

<?php
require 'Math.php';

use PHPUNIT_Framework_TestCase as TestCase;
// sometimes it can be
// use PHPUnit\Framework\TestCase as TestCase;

class MathTest extends TestCase {
    /**
     * test with data from dataProvider
     * @dataProvider providerFibonacci
     */
    public function testFibonacciWithDataProvider($n, $result) {
        $math = new Math();
        $this->assertEquals($result, $math->fibonacci($n));
    }

    public function providerFibonacci() {
        return array(
            array(1, 1),
            array(2, 1),
            array(3, 2),
            array(4, 3),
            array(5, 5),
            array(6, 8),
        );
    }
}

我們可以使用命令 phpunit MathTest 從控制檯執行此測試,輸出將是:

    PHPUnit 5.3.2 by Sebastian Bergmann and contributors.

......                                                              6 / 6 (100%)

Time: 97 ms, Memory: 10.50Mb

OK (6 tests, 6 assertions)

<?php
require 'Math.php';
use PHPUNIT_Framework_TestCase as TestCase;
// sometimes it can be
// use PHPUnit\Framework\TestCase as TestCase;

測試異常

我們可以使用方法 expectException() 測試被測程式碼是否丟擲異常。同樣在這個例子中,我們新增了一個失敗的測試來顯示失敗測試的控制檯輸出

<?php
require 'Math.php';
use PHPUNIT_Framework_TestCase as TestCase;
// sometimes it can be
// use PHPUnit\Framework\TestCase as TestCase;

class MathTest extends TestCase {
    public function testExceptionsForNegativeNumbers() {
        $this->expectException(InvalidArgumentException::class);
        $math = new Math();
            $math->fibonacci(-1);
    }

    public function testFailedForZero() {
        $this->expectException(InvalidArgumentException::class);
        $math = new Math();
        $math->factorial(0);
    }
}

我們可以使用命令 phpunit MathTest 從控制檯執行此測試,輸出將是:

        PHPUnit 5.3.2 by Sebastian Bergmann and contributors.

.F                                                                  2 / 2 (100%)

Time: 114 ms, Memory: 10.50Mb

There was 1 failure:

1) MathTest::testFailedForZero
Failed asserting that exception of type "InvalidArgumentException" is thrown.

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

SetUp 和 TearDown

此外,PHPUnit 還支援共享設定程式碼。在執行測試方法之前,將呼叫名為 setUp() 的模板方法。setUp() 是你建立要測試的物件的位置。一旦測試方法執行完畢,無論是成功還是失敗,都會呼叫另一個名為 tearDown() 的模板方法。tearDown() 是你清理測試物件的地方。

<?php
require 'Math.php';

use PHPUNIT_Framework_TestCase as TestCase;
// sometimes it can be
// use PHPUnit\Framework\TestCase as TestCase;

class MathTest extends TestCase {
    public $fixtures;
    protected function setUp() {
        $this->fixtures = [];
    }

    protected function tearDown() {
        $this->fixtures = NULL;
    }

    public function testEmpty() {
        $this->assertTrue($this->fixtures == []);
    }
}

更多資訊

你可以在測試中使用 PHPUnit 的更多機會。有關詳細資訊,請參閱官方手冊