首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHPUnit 單元測試入門:從手動驗證到自動化測試的思維轉變

     編輯:PHP 綜合知識

為什麼要自動化測試?

  • 越早發現 Bug,修復成本越低:需求階段 1×,編碼 10×,測試 100×,上線後 1000×。
  • 重構安全網:有測試覆蓋,敢於大膽重構、升級依賴、調整架構。
  • 文檔化行為:測試代碼即「可執行的規格書」,新成員閱讀測試即懂業務邊界。
  • CI/CD 門檻:合併請求必須通過測試才能合入主分支。

從 print 到 assert 的演進

階段 1:手動觀察輸出

$fixture = [];
echo sizeof($fixture) . "\n"; // 0
$fixture[] = 'element';
echo sizeof($fixture) . "\n"; // 1
// 人工看輸出是否為 0 和 1

階段 2:自動比對 + 字串輸出

$fixture = [];
echo (sizeof($fixture) === 0) ? "ok\n" : "not ok\n";
$fixture[] = 'element';
echo (sizeof($fixture) === 1) ? "ok\n" : "not ok\n";
// 輸出 ok/ok,但仍需人工掃描

階段 3:斷言函數 + 異常中斷

function assertTrue($condition, $message = '') {
    if (!$condition) {
        throw new Exception("Assertion failed: $message");
    }
}

$fixture = [];
assertTrue(sizeof($fixture) === 0, '空陣列尺寸應為 0');
$fixture[] = 'element';
assertTrue(sizeof($fixture) === 1, '單元素陣列尺寸應為 1');
// 任一失敗拋出異常,腳本非零退出,CI 可直接判定失敗

PHPUnit 核心概念速覽

概念說明
TestCase繼承 PHPUnit\Framework\TestCase,每個 public function test* 為一個測試方法。
FixturesetUp() / tearDown() 準備/清理測試環境(DB、檔案、Mock)。
AssertionsassertEquals、assertSame、assertTrue、assertCount、assertException 等豐富斷言。
Data Providers@dataProvider 參數化測試,一個方法跑多組輸入輸出。
Mock/StubcreateMock()、createStub() 隔離外部依賴(API、DB、時間)。
Code Coverage--coverage-html report 產生覆蓋率報告,找出未測試分支。

第一個 PHPUnit 測試類

<?php
// tests/ArrayTest.php
use PHPUnit\Framework\TestCase;

class ArrayTest extends TestCase {
    public function testEmptyArraySizeIsZero(): void {
        $fixture = [];
        $this->assertCount(0, $fixture);
        $this->assertSame(0, sizeof($fixture));
    }

    public function testAddingElementIncreasesSize(): void {
        $fixture = [];
        $fixture[] = 'element';
        $this->assertCount(1, $fixture);
    }

    /**
     * @dataProvider sizeProvider
     */
    public function testArraySizeWithDataProvider(array $input, int $expected): void {
        $this->assertCount($expected, $input);
    }

    public function sizeProvider(): array {
        return [
            'empty' => [[], 0],
            'one'   => [['a'], 1],
            'three' => [['a','b','c'], 3],
        ];
    }
}

執行與報告

# 安裝
composer require --dev phpunit/phpunit

# 執行單一測試
./vendor/bin/phpunit tests/ArrayTest.php

# 產生 HTML 覆蓋率報告
./vendor/bin/phpunit --coverage-html coverage tests/

測試組織最佳實踐

  • 目錄結構:tests/Unit、tests/Integration、tests/Feature(Laravel 風格)。
  • 命名:test[Method]_[Scenario]_[Expected],如 testWithdraw_InsufficientFunds_ThrowsException。
  • AAA 模式:Arrange(準備)、Act(執行)、Assert(斷言)三段式清晰可讀。
  • 快速、隔離、可重複:單元測試不連真 DB、不呼叫真 API,用 Mock/In-memory SQLite。
  • 測試金字塔:大量單元測試(底)、適量整合測試(中)、極少 E2E 測試(頂)。

常見反模式避雷

反模式症狀修正
測試相依執行順序影響結果每個測試獨立 Fixture,setUp 重建
測試內部實作改 private 方法導致測試大量失敗測試公開行為(輸入→輸出/副作用)
斷言過多一個測試 20 行 assert拆分為多個聚焦測試
忽略覆蓋率陷阱100% 覆蓋率但無實際斷言關注分支覆蓋與突變測試

原文《PHPUnit袖珍指南之自動測試》重構,補充現代 PHPUnit 9/10 語法、Data Provider、Mock、覆蓋率與測試組織最佳實踐。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved