2023-12-18|閱讀時間 ‧ 約 33 分鐘

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

這一篇讓我們看看幾個重要的 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 這三個特殊函數!

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

參考資料

本系列文章目錄

分享至
成為作者繼續創作的動力吧!
© 2024 vocus All rights reserved.