Hướng dẫn run phpunit

Chuỗi bài viết chuyên sâu về PHPUnit hy vọng mang đến cho không chỉ các PHP Developer mới mà cả những người có nhiều năm kinh nghiệm cái nhìn thân thiện và tổng quan hơn với PHPUnit, đồng thời,  giúp cho các Quản lý dự án có những sample tham khảo khi dự án có sử dụng Unit Testing hoặc dự án phát triển theo TDD.

Bài viết sẽ giới thiệu những khái niệm cốt lõi của testing, cho bạn biết tại sao “dependency injection is king” và sự khác biệt giữa mock và stub là gì? Quan trọng hơn, bạn sẽ dễ chấp nhận các thống kê tồi về phần mềm để nâng cao chất lượng của sản phẩm, cho các developer thói quen sử dụng command và làm cách nào để có màu đỏ hay màu xánh lá.

I. PHPUnit là gì?

PHPUnit là một khung kiểm thử đơn vị  (a unit testing framework) cho ngôn ngữ PHP. Nó cung cấp cho người dùng rất nhiều các class – phương thức giúp cho việc viết các đoạn mã kiểm thử trở nên nhanh chóng và thuận lợi. Từ đó, chúng ta có thể tiết kiệm được nhiều thời gian test.

II. Chuẩn bị

Để có môi trường phát triển, bạn nên sử dụng máy ảo (Ví dụ như Docker) để giả lập môi trường máy chủ, thay vì sử dụng ngay trên hệ điều hành của hiện tại, và dùng CMD để chạy các lệnh. Nếu bạn đã quen với việc làm mọi thứ trên giao diện GUI, thì đây là lúc bạn nghĩ đến việc dùng CMD rồi.

III. Sử dụng PHPUnit

1. Cài đặt PHPUnit

Cách đơn giản nhất là sử dụng composer, khi đó, bạn nên lưu ý đến PSR-4 Autoloading. 

Để cài PHPUnit, chúng ta chỉ cần một dòng trong file composer.json

{

    "require": {

        "php": "^7.2.5"

    },

    "require-dev": {

        "phpunit/phpunit": "^8.5"

    }

}

Bạn nên sử dụng XDebug – một trình gỡ lỗi giúp bạn không thành “người tối cổ” khi vẫn dùng echo, print_r, var_dump, và cũng là công cụ tuyệt vời khi làm việc với PHPUnit.

Để composer tải xuống thư viện mới, bạn chỉ cần chạy lệnh

composer update --dev

2. Chạy PHPUnit

Bạn chỉ cần gõ: ./vendor/bin/phpunit sẽ ra file mà bạn chủ yếu tương tác, còn việc load các file để testing thì composer tự tìm và load rồi.

Khi chạy PHPUnit ./vendor/bin/phpunit sẽ cho bạn biết tất cả các tùy chọn có sẵn của bạn.

Hướng dẫn run phpunit

3. Cấu trúc của dự án

Vì sử dụng composer nên sẽ mất một chút thời gian để thiết lập dự án và khiến mọi thứ hoạt động với autoloader. Đặt namespace có mã nguồn của mình là App và namespace cho mã nguồn của PHPUnit là Tests.

Cập nhật file composer.json

{

    "require": {

        "php": "^7.2.5"

    },

    "require-dev": {

        "phpunit/phpunit": "^8.5"

    },

    "autoload": {

        "psr-4": {

            "App\\":"app/"

        }

    },

    "autoload-dev": {

        "psr-4": {

            "Tests\\": "tests/"

        }

    }

}

Sau đó, chúng ta chạy lệnh để update composer bằng lệnh composer update. Toàn bộ mã nguồn dự án sẽ nằm trong thư mục app, mã nguồn testing nằm trong thư mục tests, cùng cấp với thư mục vendor.

app/

composer.json

tests/

vendor/

4. Thiết lập phpunit.xml

Khi chạy PHPUnit nó sẽ chạy với cấu hình mặc định. Bạn có thể ghi đè các giá trị mặc định thông qua dòng lệnh. Nhưng cách tốt hơn cả là cấu hình thông qua file phpunit.xml.

Trong thư mục gốc của dự án ta tạo một file phpunit.xml như sau:

<phpunit colors="true">

    <testsuites>

        <testsuite name="Application Test Suite">

            <directory suffix="Test.php">./testsdirectory>

        testsuite>

    testsuites>

    <filter>

        <whitelist processUncoveredFilesFromWhitelist="true">

            <directory suffix=".php">./appdirectory>

        whitelist>

    filter>

phpunit>

Đây là file cấu hình đơn giản nhưng cực kỳ quan trọng.

  • colors="true": đảm bảo kết quả kiểm thử có màu.
  • <directory suffix="Test.php">./testsdirectory> : Nơi mã nguồn kiểm thử của bạn được đặt và khi chạy nó chỉ chạy các file có kết thúc bằng Test.php
  • <directory suffix=".php">./appdirectory>: Nơi chứa mã nguồn cần kiểm thử và chỉ kiểm thử file có kết thúc bằng .php

Tất cả các unit testing của bạn phải đặt trong thư mục test/

5. Convention

Convention giúp cho việc teamwork, hoặc maintain,… dễ dàng hơn.

File structure và file name

Qui ước đầu tiên của chúng ta là về cấu trúc file và tên file.
Tên của file kiểm thử phải trùng với tên của file mã nguồn được kiểm thử và có Test gắn thêm vào.

Ví dụ:
Nếu ta có các files mã nguồn sau:

app/Foo.php

app/Bar.php

Thì ta có các files mã nguồn kiểm thử như sau:

tests/FooTest.php

tests/BarTest.php

Class names

Class name phải giống hệt tên file. Điều này áp dung cho tất cả các file .php trong thư mục app, và tests

Method names

Tên phương thức kiểm thử bắt đầu bằng test. Tên phương thức nên mô tả về những gì đang được kiểm thử, bao gồm tên của phương thức được kiểm thử, và không được viết tắt.

Ví dụ: nếu bạn đang kiểm thử một phương thức được gọi verifyAccount()và trong một kiểm thử đơn vị, bạn muốn kiểm tra xem mật khẩu có khớp hay không, bạn sẽ đặt tên cho phương thức kiểm thử của mình testVerifyAccountMatchesPasswordGiven().

Độ dài của tên phương thức kiểm thử ở đây là một lợi thế. Bởi khi có nhiều kiểm thử không thành công, ta sẽ dễ dàng biết chính xác những gì thất bại nhờ vào tên phương thức, từ đó có thể nhanh chóng tiến hành sửa lỗi.

Các Method kiểm thử phải là public

PHPUnit không thể chạy các phương thức protect hoặc private nên chúng phải là public. Tất cả các phương thức helpers cũng phải public. Chúng ta không xây dựng public API mà chỉ muốn viết unit test nên không cần lo lắng về khả năng truy cập của nó.

Kế thừa PHPUnit

Tất cả các class kiểm thử phải extends class \PHPUnit\Framework\TestCase hoặc một class có extends \PHPUnit\Framework\TestCase

IV. Chạy thử

Kiểm thử đầu tiên của chúng ta sẽ ngắn và có thể là “ngớ ngẩn”, nhưng nó sẽ ở mức tối thiểu cần thiết cho một kiểm thử.

Tạo mới một file: test/StupidTest.php

namespace Tests;

use PHPUnit\Framework\TestCase;

class StupidTest extends TestCase

{

     //

}

Nội dung này không có gì đặc biệt, cho thấy ta đã tuân thủ theo 3 quy tắc bên trên.
Tiếp theo ta sẽ thực hiện một kiểm thử với assertion là true. Hãy tạo một method testTrueIsTrue

// ...

    public function testTrueIsTrue()

    {

        //

    }

Sau đây là mã kiểm thử của nó.

// ...

    public function testTrueIsTrue()

    {

        $foo = true;

        $this->assertTrue($foo);

    }

Từ thư mục gốc dự án ta chạy lệnh: $ vendor/bin/phpunit

Bạn sẽ nhìn thấy thanh màu xanh (lá) hy vọng.

Hướng dẫn run phpunit

Bạn đã chạy một test và xác nhận duy nhất một assertion.

V. Kết luận

Vậy là ta đã hoàn thành cài đặt PHPUnit bằng composer, thiết lập cấu hình cho PHPUnit, và chạy một kiểm thử đầu tiên.
Có vẻ bạn sẽ thấy những bước đầu tiên này chưa đem lại tác dụng gì cụ thể, nhưng nó củng cố ý tưởng rằng: unit testing không phải là một khái niệm cao siêu, huyền bí, chỉ giáo sư mới hiểu được. Thực ra nó chỉ là một đoạn code được chúng ta tạo nên. Và đoạn code ấy cho chúng ta biết mình đã làm sai ở chỗ nào.

Phần tiếp theo ta sẽ tìm hiểu sâu hơn về các assertion, và dataProvider. Hẹn gặp lại các bạn ở những bài viết sau!

Trịnh Văn Thành – CO-WELL Asia