iT邦幫忙

2022 iThome 鐵人賽

DAY 12
0

Medium 清新閱讀版連結

過去兩週,我們演練了許多測試方式,不過不知道大家有沒有發現,我們測試的大多是「正向」情況,「反向」的情況反而沒有測試到,也就是例外情況。

例外情況也可以測試嗎?當然可以!

本篇文章會為大家介紹如何「成功地測試失敗」。

例外測試函數

  • $this->expectException()
    • 函數簽名: expectException(string $exception):
    • 函數說明:此函數可驗證是否有參數1所指涉的例外類別被拋出。
  • $this->expectExceptionMessage()
    • 函數簽名:expectExceptionMessage(string $message)
    • 函數說明:此函數可驗證是否有例外類別被拋出,且例外訊息包含參數1之字串。
  • $this->expectExceptionMessageMatches()
    • 函數簽名:expectExceptionMessageMatches(string $regularExpression)
    • 函數說明:這個函數和前一個差不多,差別在於會以Regex的方式做判定。
  • $this->expectExceptionCode()
    • 函數簽名:expectExceptionCode($code)
    • 函數說明:此函數可驗證是否有例外類別被拋出,且例外代碼是否與參數1相等

範例

  • 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);
        }
    }
    

    這邊借用了前幾天的計算BMI程式碼當範例,並加入了「當輸入不符預期時,將拋出例外」的這個行為。

  • tests/Feature/ExceptionTest.php

    <?php
    
    namespace Tests\Feature;
    
    use App\Services\TestService;
    use Exception;
    use Tests\TestCase;
    
    class ExceptionTest extends TestCase
    {
        /**
         * @return void
         */
        public function testCanThrowExceptionWhenInvaliHeight()
        {
            $service = app(TestService::class);
    
            $this->expectException(Exception::class);
    
            $service->calculateBmi(0.0, 1.0);
        }
    
        /**
         * @return void
         */
        public function testCanThrowExceptionWhenInvaliWeight()
        {
            $service = app(TestService::class);
    
            $this->expectException(Exception::class);
    
            $service->calculateBmi(1.0, 0.0);
        }
    
        /**
         * @return void
         */
        public function testCanThrowExceptionWithMessageWhenInvaliData()
        {
            $service = app(TestService::class);
    
            $this->expectExceptionMessage('Invalid');
    
            $service->calculateBmi(0.0, 1.0);
        }
    
        /**
         * @return void
         */
        public function testCanThrowExceptionWithMessageRegexMatcchWhenInvaliData()
        {
            $service = app(TestService::class);
    
            $this->expectExceptionMessageMatches('/Invalid/');
    
            $service->calculateBmi(0.0, 1.0);
        }
    
        /**
         * @return void
         */
        public function testCanThrowExceptionWithCodeWhenInvaliData()
        {
            $service = app(TestService::class);
    
            $this->expectExceptionCode(1);
    
            $service->calculateBmi(0.0, 1.0);
        }
    }
    

    以上我們共撰寫了5個測試案例。

    第1個測試案例 testCanThrowExceptionWhenInvaliHeight(),驗證了當輸入不合理的身高值時,目標函數是否會拋出例外。

    第2個測試案例 testCanThrowExceptionWhenInvaliWeight(),驗證了當輸入不合理的體重值時,目標函數是否會拋出例外。

    第3個測試案例 testCanThrowExceptionWithMessageWhenInvaliData(),驗證了當輸入不合理的身高值時,目標函數是否會拋出例外,且包含指定的例外訊息。

    第4個測試案例 testCanThrowExceptionWithMessageRegexMatcchWhenInvaliData(),驗證了當輸入不合理的體重值時,目標函數是否會拋出例外,且其例外訊息符合指定的Regex形式。

    第5個測試案例 testCanThrowExceptionWithCodeWhenInvaliData(),驗證了當輸入不合理的體重值時,目標函數是否會拋出例外,且例外代碼與預期相符。

    以上就是今天的演練,希望對大家了解例外測試有所幫助。

    明天來看看 PHPUnit 的 Annotation 吧!

    參考資料


上一篇
指令測試
下一篇
PHPUnit @ Annotation
系列文
自動化測試大作戰31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言