Có nhiều cách khác nhau để kiểm tra ứng dụng phần mềm của bạn và kiểm tra đơn vị là một cách quan trọng.
Vì vậy, kiểm tra đơn vị là gì và làm thế nào bạn có thể làm điều đó? Bạn sẽ học được điều đó và nhiều hơn nữa trong bài viết này.
Kiểm tra đơn vị là gì?
Kiểm thử đơn vị là một quy trình phát triển phần mềm trong đó các phần nhỏ nhất có thể kiểm tra được của một ứng dụng, được gọi là các đơn vị, được xem xét kỹ lưỡng và độc lập để vận hành quy trình. – SearchSoftwareQuality
Về cơ bản, kiểm thử đơn vị có nghĩa là bạn chia nhỏ ứng dụng của mình thành các phần đơn giản nhất và kiểm tra các phần nhỏ này để đảm bảo rằng mỗi phần không có lỗi (và an toàn).
Thử nghiệm này được tự động hóa và viết bởi các kỹ sư phần mềm như một phần của quá trình phát triển của họ. Đây là một bước rất quan trọng trong quá trình phát triển vì nó giúp các nhà phát triển xây dựng các ứng dụng tốt hơn với ít lỗi hơn.
PHPUnit là gì?
Bạn có thể thực hiện kiểm tra đơn vị trong PHP với PHPUnit, một khung kiểm tra định hướng lập trình viên cho PHP. PHPUnit là một phiên bản của kiến trúc xUnit dành cho các khung kiểm tra đơn vị. Nó rất dễ cài đặt và bắt đầu sử dụng.
Cài đặt PHPUnit
Bạn có thể cài đặt PHPUnit trên toàn cầu trên máy chủ của mình. Bạn cũng có thể cài đặt nó cục bộ, trên cơ sở từng dự án, thời gian phát triển dưới dạng phụ thuộc vào dự án của bạn bằng cách sử dụng trình soạn thảo. Bài viết này sẽ giải thích cách sử dụng nó trên cơ sở từng dự án.
Để bắt đầu, hãy tạo và bắt đầu một dự án mới với trình soạn thảo bằng các lệnh sau:
$ mkdir test-project
$ cd test-project
$ composer init
Lệnh đầu tiên tạo một thư mục trong thư mục hiện tại của bạn, test-project
và lệnh thứ hai di chuyển vào đó. Lệnh cuối cùng bắt đầu một shell tương tác.

Làm theo lời nhắc, điền thông tin chi tiết theo yêu cầu (giá trị mặc định là được). Bạn có thể đặt mô tả dự án, tên tác giả (hoặc tên của người đóng góp), độ ổn định tối thiểu cho các phần phụ thuộc, loại dự án, giấy phép và xác định các phần phụ thuộc của bạn.
Bạn có thể bỏ qua phần phụ thuộc vì chúng tôi không cài đặt bất kỳ phụ thuộc nào. PHPUnit được cho là một dev-dependency
bởi vì thử nghiệm nói chung chỉ nên xảy ra trong quá trình phát triển.
Bây giờ, khi lời nhắc hỏi Would you like to define your dev dependencies (require-dev) interactively [yes]?
, nhấn enter để chấp nhận. Sau đó gõ vào phpunit/phpunit
để cài đặt PHPUnit như một dev-dependency
.
Chấp nhận các giá trị mặc định khác và tiến hành tạo composer.json
tập tin. Tệp được tạo sẽ trông như thế này hiện tại:
{
"name": "zubair/test-project",
"require-dev": {
"phpunit/phpunit": "^9.5"
},
"autoload": {
"psr-4": {
"Zubair\\TestProject\\": "src/"
}
},
"authors": [
{
"name": "Idris Aweda Zubair",
"email": "[email protected]"
}
],
"require": {}
}
Để tìm hiểu cách cài đặt PHPUnit trên toàn cầu trên máy chủ của bạn, hãy đọc tại đây.
Cách viết bài kiểm tra trong PHPUnit
Viết test trong PHPUnit khá đơn giản. Dưới đây là một vài quy ước để giúp bạn bắt đầu:
- Để kiểm tra một lớp trong PHP, bạn sẽ tạo một lớp kiểm tra được đặt tên theo lớp đó. Ví dụ, nếu tôi có một số loại
User
lớp, lớp kiểm tra sẽ được đặt tênUserTest
. - Lớp kiểm tra,
UserTest
thường sẽ kế thừaPHPUnit\Framework\TestCase
lớp. - Các bài kiểm tra riêng lẻ trên lớp là các phương thức công khai được đặt tên bằng
test
như một tiền tố. Ví dụ, để kiểm tra mộtsayHello
phương pháp trênUser
lớp, phương thức sẽ được đặt têntestSayHello
. - Bên trong phương pháp kiểm tra, nói
testSayHello
bạn sử dụng phương thức của PHPUnit nhưassertSame
để thấy rằng một số phương thức trả về một số giá trị mong đợi.
Một quy ước phổ biến là có tất cả các bài kiểm tra trong một tests
thư mục và tất cả mã nguồn trong src
danh mục.
Ví dụ kiểm thử PHPUnit
Để giúp hiểu bài viết này, đây là một mẫu User
class với các phương thức đơn giản sẽ được kiểm tra:
<?php
namespace Zubair\TestProject;
use InvalidArgumentException;
class User
{
public int $age;
public array $favorite_movies = [];
public string $name;
/**
* @param int $age
* @param string $name
*/
public function __construct(int $age, string $name)
{
$this->age = $age;
$this->name = $name;
}
public function tellName(): string
{
return "My name is " . $this->name . ".";
}
public function tellAge(): string
{
return "I am " . $this->age . " years old.";
}
public function addFavoriteMovie(string $movie): bool
{
$this->favorite_movies[] = $movie;
return true;
}
public function removeFavoriteMovie(string $movie): bool
{
if (!in_array($movie, $this->favorite_movies)) throw new InvalidArgumentException("Unknown movie: " . $movie);
unset($this->favorite_movies[array_search($movie, $this->favorite_movies)]);
return true;
}
}
Lớp người dùng này có thể là User
class trong ứng dụng phát trực tuyến phim của bạn. Người dùng có tên, tuổi và danh sách phim yêu thích có thể cập nhật. Đối với phần còn lại của bài viết, chúng tôi sẽ kiểm tra xem tất cả các tính năng này có hoạt động như mong đợi hay không.
Tạo một UserTest
lớp học trong tests
thư mục. Dán cái này vào để bắt đầu:
<?php
namespace Zubair\TestProject;
use PHPUnit\Framework\TestCase;
final class UserTest extends TestCase
{
// Tests will go here
}
Trình xây dựng thử nghiệm
Thông thường, bạn sẽ không kiểm tra __construct
phương pháp. Tuy nhiên, vì chúng tôi đang đặt các giá trị trong đó, nên việc đảm bảo rằng các giá trị đang được đặt chính xác là điều hợp lý.
Điều này có vẻ như là một điều rất nhỏ để kiểm tra, nhưng đó là toàn bộ điểm của kiểm tra đơn vị – để đảm bảo rằng các phần nhỏ nhất trong ứng dụng của bạn hoạt động như mong đợi.
Tạo một testClassConstructor
phương pháp để kiểm tra hàm tạo:
public function testClassConstructor()
{
$user = new User(18, 'John');
$this->assertSame('John', $user->name);
$this->assertSame(18, $user->age);
$this->assertEmpty($user->favorite_movies);
}
Bây giờ chúng ta hãy nghỉ ngơi nhanh chóng để xem cách chạy thử nghiệm.
Cách chạy thử nghiệm trong PHPUnit
Bạn có thể chạy tất cả các bài kiểm tra trong một thư mục bằng cách sử dụng tệp nhị phân PHPUnit được cài đặt trong thư mục nhà cung cấp của bạn.
$ ./vendor/bin/phpunit --verbose tests
Bạn cũng có thể chạy thử nghiệm đơn lẻ bằng cách cung cấp đường dẫn đến tệp thử nghiệm.
$ ./vendor/bin/phpunit --verbose tests/UserTest.php
Bạn sử dụng --verbose
cờ để có thêm thông tin về trạng thái thử nghiệm.
Bây giờ, chúng ta có thể chạy thử nghiệm và xem đầu ra:

Đầu ra cho thấy rằng chúng tôi đã chạy 1 bài kiểm tra và đưa ra 3 xác nhận trong đó. Chúng tôi cũng xem mất bao lâu để chạy thử nghiệm cũng như lượng bộ nhớ đã được sử dụng để chạy thử nghiệm.
Các xác nhận này là những gì PHPUnit sử dụng để so sánh các giá trị được trả về từ các phương thức với giá trị mong đợi của chúng.
Ví dụ này sử dụng assertSame
để kiểm tra xem name
và age
các thuộc tính trên đối tượng người dùng khớp với các giá trị đã nhập. Nó cũng sử dụng assertEmpty
để kiểm tra xem favorite_movies
mảng trống.
Để xem danh sách tất cả các xác nhận này, bạn có thể xem tài liệu của PHPUnit tại đây.
Chỉnh sửa mã để kiểm tra xem tuổi người dùng có giống với 21.
public function testClassConstructor()
{
$user = new User(18, 'John');
$this->assertSame('John', $user->name);
$this->assertSame(21, $user->age);
$this->assertEmpty($user->favorite_movies);
}
Chạy lại bài kiểm tra lần này sẽ cho kết quả như sau:

Đầu ra hiện cho thấy rằng chúng tôi đã chạy 1 thử nghiệm, với 2 lần xác nhận thành công và một lần xác nhận không thành công. Chúng ta có thể thấy một số lời giải thích về lỗi, hiển thị giá trị mong đợi, giá trị nhận được và dòng lỗi bắt nguồn từ đâu.
Kiểm tra testName và TellAge
Tiếp theo, chúng ta có thể kiểm tra testName
phương pháp. Phương thức này cho biết tên của người dùng dưới dạng một câu. Vì vậy, chúng ta có thể viết bài kiểm tra để kiểm tra:
- Nếu giá trị trả về là một chuỗi.
- Nếu chuỗi được trả về có tên người dùng trong đó (có hoặc không có phân biệt chữ hoa chữ thường).
public function testTellName()
{
$user = new User(18, 'John');
$this->assertIsString($user->tellName());
$this->assertStringContainsStringIgnoringCase('John', $user->tellName());
}
Bài kiểm tra sử dụng các khẳng định assertIsString
và assertStringContainsStringIgnoringCase
để kiểm tra xem giá trị trả về có phải là một chuỗi không và nó có chứa chuỗi đó không Johntương ứng.
Các testAge
phương pháp rất giống với testName
và sử dụng cùng một logic. Thử nghiệm của nó sẽ tương tự như thử nghiệm trước:
public function testTellAge()
{
$user = new User(18, 'John');
$this->assertIsString($user->tellAge());
$this->assertStringContainsStringIgnoringCase('18', $user->tellAge());
}
Kiểm tra addFavoriteMovie
Chúng ta cũng có thể thử nghiệm phương pháp này. Phương pháp này thêm một bộ phim vào danh sách các bộ phim. Để kiểm tra, chúng ta có thể kiểm tra xem phim mới được thêm vào có trong danh sách hay không và số lượng mục trong danh sách có thực sự tăng lên hay không.
Cái sau là để xác nhận rằng các mục không bị thay thế. Ngoài ra, vì hàm trả về một số giá trị ở cuối, nên chúng ta cũng có thể kiểm tra xem giá trị này có đúng không.
public function testAddFavoriteMovie()
{
$user = new User(18, 'John');
$this->assertTrue($user->addFavoriteMovie('Avengers'));
$this->assertContains('Avengers', $user->favorite_movies);
$this->assertCount(1, $user->favorite_movies);
}
Ở đây, chúng tôi sử dụng một vài khẳng định mới – assertTrue
, assertContains
và assertCount
– để kiểm tra xem giá trị được trả về có đúng không, giá trị đó có chứa chuỗi mới được thêm vào không và mảng hiện có một mục trong đó.
Kiểm tra loại bỏFavoriteMovie
Cuối cùng, chúng ta có thể kiểm tra xem phương pháp xóa phim có hoạt động hay không.
public function testRemoveFavoriteMovie()
{
$user = new User(18, 'John');
$this->assertTrue($user->addFavoriteMovie('Avengers'));
$this->assertTrue($user->addFavoriteMovie('Justice League'));
$this->assertTrue($user->removeFavoriteMovie('Avengers'));
$this->assertNotContains('Avengers', $user->favorite_movies);
$this->assertCount(1, $user->favorite_movies);
}
Ở đây, chúng tôi đang thêm một số phim vào danh sách. Sau đó, chúng tôi xóa một trong số chúng và xác nhận rằng hàm trả về true. Tiếp theo, chúng tôi xác nhận việc xóa bằng cách kiểm tra xem giá trị đó có còn trong danh sách không. Cuối cùng, chúng tôi xác nhận rằng chúng tôi chỉ có một phim trong danh sách, thay vì hai.
Phần kết luận
Bây giờ bạn đã biết cách thiết lập PHPUnit trong các dự án của mình cũng như cách kiểm tra và đảm bảo rằng bạn đang xây dựng phần mềm đẳng cấp thế giới. Bạn có thể tìm thấy tất cả các mã cho bài viết này ở đây.
Nếu bạn có bất kỳ câu hỏi hoặc lời khuyên có liên quan, xin vui lòng liên hệ với tôi để chia sẻ chúng.
Để đọc thêm các bài viết của tôi hoặc theo dõi công việc của tôi, bạn có thể kết nối với tôi trên LinkedIn, Twittervà Github. Thật nhanh chóng, thật dễ dàng và hoàn toàn miễn phí!