跳到主要内容

เนื้อหาภาษาไทย / 泰语内容

系统指南 内容已审核

การทำ Unit Testing ด้วย PHPUnit

บทความนี้แนะนำการทำ Unit Testing ใน PHP โดยใช้ PHPUnit ซึ่งเป็น Framework ที่นิยมใช้กันอย่างแพร่หลาย เนื้อหาครอบคลุมตั้งแต่การติดตั้ง PHPUnit, การสร้าง Test Cas...

การทำ Unit Testing ด้วย PHPUnit

ในบทที่แล้ว เราได้เรียนรู้เกี่ยวกับการใช้ Debugging Tools เพื่อตรวจสอบและแก้ไขข้อผิดพลาดในโค้ด PHP ของเรา ในบทนี้ เราจะมาเรียนรู้วิธีการเขียน Unit Test โดยใช้ PHPUnit ซึ่งเป็น Framework ที่ได้รับความนิยมอย่างมากสำหรับการทำ Unit Testing ใน PHP การทำ Unit Testing จะช่วยให้เรามั่นใจได้ว่า Code ที่เราเขียนทำงานได้อย่างถูกต้องตามที่คาดหวัง และยังช่วยลดข้อผิดพลาดที่อาจเกิดขึ้นใน Production ได้อีกด้วย

Unit Testing คืออะไร?

Unit Testing คือการทดสอบส่วนย่อยที่สุดของโปรแกรม (Unit) โดยทั่วไปคือฟังก์ชันหรือเมธอด เพื่อให้แน่ใจว่า Unit นั้นทำงานได้อย่างถูกต้องตาม Specification ที่กำหนดไว้ การทำ Unit Testing จะช่วยให้เราสามารถตรวจจับข้อผิดพลาดได้ตั้งแต่เนิ่นๆ ทำให้ง่ายต่อการแก้ไข และยังช่วยให้เรามั่นใจได้ว่าเมื่อมีการเปลี่ยนแปลง Code จะไม่ส่งผลกระทบต่อส่วนอื่นๆ ของโปรแกรม

PHPUnit คืออะไร?

PHPUnit เป็น Framework สำหรับการทำ Unit Testing ใน PHP ที่ได้รับความนิยมอย่างมาก มีเครื่องมือและฟังก์ชันต่างๆ ที่ช่วยให้เราเขียน Test Cases ได้ง่ายและมีประสิทธิภาพ เช่น Assertions ต่างๆ ที่ใช้ตรวจสอบผลลัพธ์ของการทดสอบ

PHPUnit Installation

ก่อนที่เราจะเริ่มเขียน Unit Test ได้ เราต้องติดตั้ง PHPUnit ก่อน ซึ่งสามารถทำได้ง่ายๆ ผ่าน Composer:

composer require --dev phpunit/phpunit

คำสั่งนี้จะติดตั้ง PHPUnit เป็น Dependency สำหรับการพัฒนา (--dev) ซึ่งหมายความว่า PHPUnit จะไม่ถูกติดตั้งเมื่อเรา Deploy โปรแกรมไปยัง Production

หลังจากติดตั้งเสร็จเรียบร้อยแล้ว เราสามารถตรวจสอบได้ว่า PHPUnit ถูกติดตั้งสำเร็จหรือไม่โดยการรันคำสั่ง:

./vendor/bin/phpunit --version

ถ้าทุกอย่างเรียบร้อยดี จะแสดง Version ของ PHPUnit ที่ติดตั้งไว้

Test Cases

Test Case คือ Class ที่ประกอบไปด้วย Test Methods ซึ่งแต่ละ Test Method จะทดสอบการทำงานของ Unit หนึ่งๆ ในโปรแกรมของเรา โดยทั่วไปแล้ว Test Case จะอยู่ใน Directory ที่แยกจาก Code หลัก เพื่อความเป็นระเบียบ

สมมติว่าเรามี Class ชื่อ `Calculator` ที่มี Method ชื่อ `add` ซึ่งทำหน้าที่บวกเลขสองจำนวน:

// src/Calculator.php
class Calculator
{
    public function add(int $a, int $b): int
    {
        return $a + $b;
    }
}

เราสามารถสร้าง Test Case สำหรับ Class `Calculator` ได้ดังนี้:

// tests/CalculatorTest.php
use PHPUnit\Framework\TestCase;

class CalculatorTest extends TestCase
{
    public function testAdd()
    {
        $calculator = new Calculator();
        $result = $calculator->add(2, 3);
        $this->assertEquals(5, $result);
    }
}

อธิบาย Code:

  • use PHPUnit\Framework\TestCase;: Import Class `TestCase` จาก PHPUnit ซึ่งเป็น Class แม่ของ Test Case ทั้งหมด
  • class CalculatorTest extends TestCase: สร้าง Class `CalculatorTest` ซึ่ง extends จาก `TestCase`
  • public function testAdd(): สร้าง Test Method ชื่อ `testAdd` โดยชื่อ Method ต้องขึ้นต้นด้วย `test` เสมอ
  • $calculator = new Calculator();: สร้าง Instance ของ Class `Calculator`
  • $result = $calculator->add(2, 3);: เรียกใช้ Method `add` ของ Class `Calculator`
  • $this->assertEquals(5, $result);: ใช้ Assertion `assertEquals` เพื่อตรวจสอบว่าผลลัพธ์ที่ได้ ($result) เท่ากับ 5 หรือไม่

เพื่อให้ PHPUnit รู้ว่าจะรัน Test Case นี้ได้อย่างไร เราต้อง Configure Autoloading ในไฟล์ `composer.json` โดยเพิ่มส่วน `autoload-dev` ดังนี้:

{
    "autoload": {
        "psr-4": {
            "App\\": "src/"
        }
    },
    "autoload-dev": {
        "psr-4": {
            "Tests\\": "tests/"
        }
    },
    "require": {
        "php": "^7.4|^8.0"
    },
    "require-dev": {
        "phpunit/phpunit": "^9.0"
    }
}

จากนั้นรันคำสั่ง:

composer dump-autoload

เพื่อ Update Autoloader

ตอนนี้เราสามารถรัน Test Case ได้โดยใช้คำสั่ง:

./vendor/bin/phpunit tests/CalculatorTest.php

ถ้า Test Case ผ่าน จะแสดงข้อความ:

OK (1 test, 1 assertion)

ถ้า Test Case ไม่ผ่าน จะแสดงข้อความ Error พร้อมรายละเอียด

Assertions

Assertions คือ Method ที่ใช้ตรวจสอบว่าผลลัพธ์ของการทดสอบเป็นไปตามที่คาดหวังหรือไม่ PHPUnit มี Assertions ให้เลือกใช้มากมาย เช่น:

  • assertEquals($expected, $actual): ตรวจสอบว่า $actual เท่ากับ $expected
  • assertSame($expected, $actual): ตรวจสอบว่า $actual เหมือนกับ $expected (Type และ Value ต้องเหมือนกัน)
  • assertTrue($condition): ตรวจสอบว่า $condition เป็น true
  • assertFalse($condition): ตรวจสอบว่า $condition เป็น false
  • assertNull($variable): ตรวจสอบว่า $variable เป็น null
  • assertNotNull($variable): ตรวจสอบว่า $variable ไม่เป็น null
  • assertGreaterThan($expected, $actual): ตรวจสอบว่า $actual มากกว่า $expected
  • assertLessThan($expected, $actual): ตรวจสอบว่า $actual น้อยกว่า $expected
  • assertEmpty($variable): ตรวจสอบว่า $variable ว่างเปล่า (Empty)
  • assertNotEmpty($variable): ตรวจสอบว่า $variable ไม่ว่างเปล่า
  • assertArrayHasKey($key, $array): ตรวจสอบว่า $array มี Key $key
  • assertObjectHasAttribute($attribute, $object): ตรวจสอบว่า $object มี Attribute $attribute
  • assertStringContainsString($needle, $haystack): ตรวจสอบว่า $haystack มี String $needle

ตัวอย่างการใช้งาน Assertions อื่นๆ:

public function testAddNegativeNumbers()
{
    $calculator = new Calculator();
    $result = $calculator->add(-2, -3);
    $this->assertEquals(-5, $result);
}

public function testAddZero()
{
    $calculator = new Calculator();
    $result = $calculator->add(0, 5);
    $this->assertSame(5, $result); // ใช้ assertSame เพราะต้องการตรวจสอบ Type ด้วย
}

กรณีใช้งานจริงและข้อผิดพลาดที่พบบ่อย

  • การตั้งชื่อ Test Methods: ควรตั้งชื่อ Test Methods ให้สื่อความหมายถึงสิ่งที่กำลังทดสอบ เช่น `testAddTwoPositiveNumbers`, `testAddNegativeAndPositiveNumbers`, `testAddWithZero`
  • การทดสอบ Edge Cases: ควรทดสอบ Edge Cases หรือกรณีพิเศษต่างๆ เช่น การบวกเลขที่มีค่าเป็นศูนย์, การบวกเลขที่มีค่าเป็นลบ, การบวกเลขที่มีค่ามากเกินไป
  • การ Mocking Dependencies: ในบางครั้ง Unit ที่เราต้องการทดสอบอาจมี Dependencies กับ Units อื่นๆ ซึ่งอาจทำให้การทดสอบซับซ้อนขึ้น ในกรณีนี้ เราสามารถใช้ Mocking เพื่อจำลองการทำงานของ Dependencies เหล่านั้นได้ (จะกล่าวถึงในบทต่อๆไป)
  • ข้อผิดพลาดที่พบบ่อย:
    • ลืม Include ไฟล์ Test Case
    • ตั้งชื่อ Test Method ไม่ถูกต้อง (ไม่ได้ขึ้นต้นด้วย `test`)
    • ใช้ Assertion ไม่ถูกต้อง (เช่น ใช้ `assertEquals` แทน `assertSame` ในกรณีที่ต้องการตรวจสอบ Type ด้วย)
    • ไม่ได้ Update Autoloader หลังจากเพิ่ม Test Case ใหม่

การทำ Unit Testing เป็นส่วนสำคัญของการพัฒนา Software ที่มีคุณภาพ การเริ่มต้นเขียน Unit Test ตั้งแต่เนิ่นๆ จะช่วยให้เราสามารถตรวจจับข้อผิดพลาดได้ง่ายขึ้น และยังช่วยให้เรามั่นใจได้ว่า Code ที่เราเขียนทำงานได้อย่างถูกต้องตามที่คาดหวัง ในบทต่อไป เราจะมาเรียนรู้เกี่ยวกับการทำ Code Coverage ด้วย PHPUnit ซึ่งจะช่วยให้เราวัดได้ว่า Code ของเราได้รับการทดสอบครอบคลุมมากน้อยแค่ไหน

Office.in.th Custom Service

想基于此结构开发或定制系统?

Office.in.th 承接企业级 Web Application、API Integration 以及政府/企业管理系统的设计与开发,并提供长期支持。

查看软件开发服务