PHPUnit 自動化測試大作戰【CH13】

更新於 2024/12/17閱讀時間約 11 分鐘

這一篇讓我們看看幾個重要的 PHPUnit @ Annotation 吧!

所謂的 PHPUnit @ Annotation,是指在測試案例函數前的 PHP Doc 區塊,PHPUnit 提供開發者引用的 @Annotation。PHPUnit 提供的 @ Annotation 大約有 20+ 個,今天會和大家介紹最常用的幾個。

測試目標函數

首先,大家請先閱讀以下程式碼,後續的@ Annotation 範例皆是以此為測試目標:

  • app/Services/TestService.php
<?php

namespace App\Services;

use Exception;

class TestService{

/** * @throws Exception */

public function calculateBmi(float $height, float $weight): float {

if ($weight <= 0 || $height <= 0) {

throw new Exception('Invalid input!', 1);

} return $weight / ($height * $height);

}}

Annotation 介紹

@test

  • 介紹:當測試程式碼中的函數之 PHP Doc 區塊有引用此 Annotation 時,PHPUnit方會將此函數當成測試案例函數執行。
  • 範例
<?php

namespace Tests\Feature;

use App\Services\TestService;

use Exception;

use Tests\TestCase;

class ExceptionTest extends TestCase{

/** * @test */

public function canCalcuateBmi() {

$service = app(TestService::class);

$this->expectException(Exception::class);

$bmiActual = $service->calculateBmi(64.0, 1.6);

$bmiExpected = 64.0/(1.6^2);

$this->assertEquals($bmiExpected, $bmiActual);

} public function testCanCalcuateBmi() {

$service = app(TestService::class);

$this->expectException(Exception::class);

$bmiActual = $service->calculateBmi(64.0, 1.6);

$bmiExpected = 64.0/(1.6^2);

$this->assertEquals($bmiExpected, $bmiActual);

} public function canCalcuateBmi2() {

$service = app(TestService::class);

$this->expectException(Exception::class);

$bmiActual = $service->calculateBmi(64.0, 1.6);

$bmiExpected = 64.0/(1.6^2);

$this->assertEquals($bmiExpected, $bmiActual);

}}

以上程式碼中,canCalcuateBmi()、 testCanCalcuateBmi() 兩函數都會被執行,canCalcuateBmi2() 則不會。

@depends

  • 介紹:當測試程式碼中的函數之 PHP Doc 區塊有引用此 Annotation ,則 PHPUnit 會確認其依賴的測試案例函數有驗證通過,方會執行當前的測試案例涵數。
  • 範例
<?php

namespace Tests\Feature;

use App\Services\TestService;

use Exception;

use Tests\TestCase;

class ExceptionTest extends TestCase{

public function testCanCalcuateBmi() {

$service = app(TestService::class);

$this->expectException(Exception::class);

$bmiActual = $service->calculateBmi(64.0, 1.6);

$bmiExpected = 64.0/(1.6^2);

$this->assertEquals($bmiExpected, $bmiActual);

} /** * @depends testCanCalcuateBmi */

public function testCanThrowExceptionWhenInvaliHeight() {

$service = app(TestService::class);

$this->expectException(Exception::class);

$service->calculateBmi(0.0, 1.0);

}}

以上程式碼中,當 testCanCalcuateBmi() 驗證通過時,testCanThrowExceptionWhenInvaliHeight() 才會被執行;當testCanCalcuateBmi() 測試失敗時,testCanThrowExceptionWhenInvaliHeight()不會被執行。

@group

  • 介紹:顧名思義,此 Annotation 可以將多個測試案例函數分組。
  • 範例
<?php

namespace Tests\Feature;

use App\Services\TestService;

use Exception;

use Tests\TestCase;

class ExceptionTest extends TestCase{

/** * @group BMI */

public function testCanCalcuateBmi() {

$service = app(TestService::class);

$this->expectException(Exception::class);

$bmiActual = $service->calculateBmi(64.0, 1.6);

$bmiExpected = 64.0/(1.6^2);

$this->assertEquals($bmiExpected, $bmiActual);

} /** * @group BMI */

public function testCanThrowExceptionWhenInvaliHeight() {

$service = app(TestService::class);

$this->expectException(Exception::class);

$service->calculateBmi(0.0, 1.0);

}}

以上程式碼中,當我們在命令列執行 ./vendor/bin/phpunit --group=BMI 時, testCanCalcuateBmi() 及 testCanThrowExceptionWhenInvaliHeight() 都會被執行。除此之外,一個測試案例函數可以被歸類在多個 @group 喔!

@testWith

  • 介紹:此 Annotation 可以讓我們對同一個測試案例函數,執行一組以上資料組的測試驗證。
  • 範例
<?php

namespace Tests\Feature;

use App\Services\TestService;

use Exception;

use Tests\TestCase;

class ExceptionTest extends TestCase{

/** * @testWith [0.0, 1.0] * [1.0, 0.0] * [0.0, 0.0] */

public function testCanThrowExceptionWhenInvalidData(float $height, float $weight) {

$service = app(TestService::class);

$this->expectException(Exception::class);

$service->calculateBmi($height, $weight);

}}

以上程式碼中, testCanThrowExceptionWhenInvalidData() 會被執行3次:

  • testCanThrowExceptionWhenInvalidData(0.0, 1.0)
  • testCanThrowExceptionWhenInvalidData(1.0, 0.0)
  • testCanThrowExceptionWhenInvalidData(0.0, 0.0)

@dataProvider

  • 介紹:此 Annotation 與 @testWith 類似,但使用方式比較特別,姑且讓我們保留到下一篇文章再做介紹。 😆

以上就是今天的介紹,大家可以多演練一下唷!

下一篇來為大家介紹 setUp()、tearDown()、Data Provider 這三個特殊函數!

如果您喜歡這篇文章,歡迎加入追蹤以接收新文章通知 😄

參考資料

本系列文章目錄

avatar-img
8會員
270內容數
歡迎來到 WilliamP 的沙龍天地,在這裡將與各位讀者探討各種主題,包刮高中數學題庫、PHP開發經驗、LINE聊天機器人開發經驗、書摘筆記等,歡迎交流!
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
WilliamP的沙龍 的其他內容
在之前的文章中,我們演練了許多測試方式,不過不知道大家有沒有發現,我們測試的大多是「正向」情況,「反向」的情況反而沒有測試到,也就是例外情況。 例外情況也可以測試嗎?當然可以! 本篇文章會為大家介紹如何「成功地測試失敗」。 例外測試函數 $this->expectException() 函
指令在現代 Laravel Web Applications 中,也是一個相當常見的應用,而 Laravel 也為此準備許多方便實現測試的函數,以下就來為大家介紹: artisan() 函數簽名: artisan($command, $parameters = []) 函數說明:這應該是指令測
前一篇我們介紹了在撰寫自動化測試時常使用的 Trait,今天則要來為大家介紹 Auth 相關測試可如何進行,同時為大家示範 RefreshDatabase 與 WithoutMiddleware 這兩個 Trait 的使用。 取得當前登入使用者資料 在以 Laravel 開發 Web 服務時,常
在之前的文章中,我們分別演練了 API 測試與資料庫測試,今天則讓我們停下腳步,來介紹一些 Laravel 提供的,與 自動化測試有關的 Trait 吧! DatabaseMigrations 當我們使用了這個 Trait 後,會在每個測試被執行前,先執行 migrate ,接著在測試被執行後,
前置: Factory & UserRepository 在開始實作資料庫測試之前,先與大家介紹 Factory 這個東西。 Factory 是個 Laravel 的 ORM:Eloquent 提供的功能,它可以讓我們用很簡單的方式,去準備測試資料,在 Laravel 初始化後,預設已經幫我們準
在前幾篇文章中,我們介紹了測試3A原則,也介紹了許多 Assertion 函數,今天就讓我們實際演練吧! 過去的經驗中,最常用自動化測試來測式的對象,大概就是API了,而前後端分離也是目前 Web 開發界常用的模式,因此我們就以 API 測試來演練吧! 驗證HTTP Status Code H
在之前的文章中,我們演練了許多測試方式,不過不知道大家有沒有發現,我們測試的大多是「正向」情況,「反向」的情況反而沒有測試到,也就是例外情況。 例外情況也可以測試嗎?當然可以! 本篇文章會為大家介紹如何「成功地測試失敗」。 例外測試函數 $this->expectException() 函
指令在現代 Laravel Web Applications 中,也是一個相當常見的應用,而 Laravel 也為此準備許多方便實現測試的函數,以下就來為大家介紹: artisan() 函數簽名: artisan($command, $parameters = []) 函數說明:這應該是指令測
前一篇我們介紹了在撰寫自動化測試時常使用的 Trait,今天則要來為大家介紹 Auth 相關測試可如何進行,同時為大家示範 RefreshDatabase 與 WithoutMiddleware 這兩個 Trait 的使用。 取得當前登入使用者資料 在以 Laravel 開發 Web 服務時,常
在之前的文章中,我們分別演練了 API 測試與資料庫測試,今天則讓我們停下腳步,來介紹一些 Laravel 提供的,與 自動化測試有關的 Trait 吧! DatabaseMigrations 當我們使用了這個 Trait 後,會在每個測試被執行前,先執行 migrate ,接著在測試被執行後,
前置: Factory & UserRepository 在開始實作資料庫測試之前,先與大家介紹 Factory 這個東西。 Factory 是個 Laravel 的 ORM:Eloquent 提供的功能,它可以讓我們用很簡單的方式,去準備測試資料,在 Laravel 初始化後,預設已經幫我們準
在前幾篇文章中,我們介紹了測試3A原則,也介紹了許多 Assertion 函數,今天就讓我們實際演練吧! 過去的經驗中,最常用自動化測試來測式的對象,大概就是API了,而前後端分離也是目前 Web 開發界常用的模式,因此我們就以 API 測試來演練吧! 驗證HTTP Status Code H
你可能也想看
Google News 追蹤
Thumbnail
*合作聲明與警語: 本文係由國泰世華銀行邀稿。 證券服務係由國泰世華銀行辦理共同行銷證券經紀開戶業務,定期定額(股)服務由國泰綜合證券提供。   剛出社會的時候,很常在各種 Podcast 或 YouTube 甚至是在朋友間聊天,都會聽到各種市場動態、理財話題,像是:聯準會降息或是近期哪些科
在前一篇文章中,我們探討了多重資料庫連線情境下,Model 及 Database Assertion 的應對方式,不過實際上筆者認為比較有難度的,其實是 Migration 應對方式。 今天就讓我們來探討這部分吧! Migration 應對方式 對於多重資料庫連線這種情境,筆者實務上做過的對應
今天讓我們探討「缺乏 Migration Files 與 Factory Files」的 Legacy 情境吧! 很多時候我們會遇到沒有 Migration Files 或 Factory Files 的 Legacy Codebase,原因大概有以下幾種: 該程式庫原本不是以 Laravel
在實務情境上,常會有在單一專案程式庫中,存取多個不同資料庫的使用情境,在這種情況下,我們通常會設置多個資料庫連線(Database Connection)設定。 在平常開發使用設很方便,但要做測試時就會發現一些問題: 在測試程式碼或 Seeder 中調用 factory() 時,都是在預設連線資
今天就讓我們依照前一天的情境題,來撰寫測試案例函數吧! 這次同樣地,先讓我們規畫擬訂測試案例: 測試案例 使用者註冊: 使用者可送出註冊資料,系統將建立使用者資料,並送出含有專屬驗證連結之驗證信,當此驗證連結被開啟後,將讓使用者轉為已驗證狀態 請求錯誤的驗證連結: 錯誤的驗證連結被開啟後
前兩天,我們探討了「網站文章」的情境題;今明兩天,就讓我們探討另一個情境題「會員註冊」吧! 這邊我們同樣假設網站是採前後端分離的設計,因此我們就專注在測試 API 的部分,不過會多一個「註冊驗證信」的部分要實作與做測試驗證。 使用案例 使用者可填寫註冊資料後送出資料。 使用者可收到註冊驗證信
Thumbnail
練習 PHPUnit 測試的撰寫,依序創建Controller、Service,並針對計算邏輯進行單元測試的練習。
Thumbnail
在 Laravel 中的測試中,PHPUnit 和 Mockery 都可以用來創建測試替身(test double),但它們有不同的方式和功能,以下簡單介紹兩種寫法方式。
前言 基本準備差不多了,也能跑自己的測試,再來就是關於測試腳本的核心:元素定位跟動作,本篇會著重介紹 XPATH 定位的部分
Thumbnail
前言 上篇我們成功執行第一個測試案例,從 Python 腳本透過 Appium 控制模擬器點選設定中的電池,下個問題就是怎麼找元件,這時候就要請出 Appium Inspector 了
前言 經過五個小單元的準備,終於可以開始跑第一個測試了,Appium 本身是個工具,可以搭配各種語言,這邊選擇 Python 作為測試腳本語言,以便之後跟 Robot Framework 串接。
Thumbnail
*合作聲明與警語: 本文係由國泰世華銀行邀稿。 證券服務係由國泰世華銀行辦理共同行銷證券經紀開戶業務,定期定額(股)服務由國泰綜合證券提供。   剛出社會的時候,很常在各種 Podcast 或 YouTube 甚至是在朋友間聊天,都會聽到各種市場動態、理財話題,像是:聯準會降息或是近期哪些科
在前一篇文章中,我們探討了多重資料庫連線情境下,Model 及 Database Assertion 的應對方式,不過實際上筆者認為比較有難度的,其實是 Migration 應對方式。 今天就讓我們來探討這部分吧! Migration 應對方式 對於多重資料庫連線這種情境,筆者實務上做過的對應
今天讓我們探討「缺乏 Migration Files 與 Factory Files」的 Legacy 情境吧! 很多時候我們會遇到沒有 Migration Files 或 Factory Files 的 Legacy Codebase,原因大概有以下幾種: 該程式庫原本不是以 Laravel
在實務情境上,常會有在單一專案程式庫中,存取多個不同資料庫的使用情境,在這種情況下,我們通常會設置多個資料庫連線(Database Connection)設定。 在平常開發使用設很方便,但要做測試時就會發現一些問題: 在測試程式碼或 Seeder 中調用 factory() 時,都是在預設連線資
今天就讓我們依照前一天的情境題,來撰寫測試案例函數吧! 這次同樣地,先讓我們規畫擬訂測試案例: 測試案例 使用者註冊: 使用者可送出註冊資料,系統將建立使用者資料,並送出含有專屬驗證連結之驗證信,當此驗證連結被開啟後,將讓使用者轉為已驗證狀態 請求錯誤的驗證連結: 錯誤的驗證連結被開啟後
前兩天,我們探討了「網站文章」的情境題;今明兩天,就讓我們探討另一個情境題「會員註冊」吧! 這邊我們同樣假設網站是採前後端分離的設計,因此我們就專注在測試 API 的部分,不過會多一個「註冊驗證信」的部分要實作與做測試驗證。 使用案例 使用者可填寫註冊資料後送出資料。 使用者可收到註冊驗證信
Thumbnail
練習 PHPUnit 測試的撰寫,依序創建Controller、Service,並針對計算邏輯進行單元測試的練習。
Thumbnail
在 Laravel 中的測試中,PHPUnit 和 Mockery 都可以用來創建測試替身(test double),但它們有不同的方式和功能,以下簡單介紹兩種寫法方式。
前言 基本準備差不多了,也能跑自己的測試,再來就是關於測試腳本的核心:元素定位跟動作,本篇會著重介紹 XPATH 定位的部分
Thumbnail
前言 上篇我們成功執行第一個測試案例,從 Python 腳本透過 Appium 控制模擬器點選設定中的電池,下個問題就是怎麼找元件,這時候就要請出 Appium Inspector 了
前言 經過五個小單元的準備,終於可以開始跑第一個測試了,Appium 本身是個工具,可以搭配各種語言,這邊選擇 Python 作為測試腳本語言,以便之後跟 Robot Framework 串接。