Laravel sử dụng phpunit giúp test ứng dụng dễ dàng, framework đã tích hợp sẵn chúng ta có thể config mở rộng hoặc sử dụng luôn. Thêm các config cho phpunit test trong file phpunit.xml
. Các file test được tạo trong thư mục tests
, có 2 loại test: feature test và unit test
Tạo 1 feature test, các file test được tạo trong folder tests/Feature
php artisan make:test UserTest
// Create UserController in tests/Feature/Controllers/Api/V1
php artisan make:test Controllers/Api/V1/UserControllerTest
Tạo 1 unit test, cái file test được tạo trong folder tests/Unit
php artisan make:test UserTest --unit
// Create UserController in tests/Unit/Controllers/Api/V1
php artisan make:test Controllers/Api/V1/UserControllerTest --unit
Tạo testTrait viết các function dùng chung
<?php
namespace Tests\Traits;
use App\Models\User;
trait TestTrait
{
/**
* Create user
*
* @return User
*/
protected function createUser(): User
{
return User::factory()->create();
}
/**
* Generate Token
*
* @param User|null $user User
* @return string
*/
protected function generateToken(User $user = null): string
{
if (!$user) {
$user = $this->createUser();
}
return $user->createToken('token')->plainTextToken;
}
/**
* Handle headers with bearer token
*
* @param User|null $user User
* @return array
*/
protected function headersWithToken(User $user = null): array
{
return [
'Authorization' => 'Bearer ' . $this->generateToken($user),
];
}
}
Tạo test cho userController
<?php
namespace Tests\Feature\Controllers\Api\V1;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Symfony\Component\HttpFoundation\Response;
use Tests\TestCase;
use Tests\Traits\TestTrait;
class UserControllerTest extends TestCase
{
use RefreshDatabase;
use TestTrait;
/**
* Test get list users success.
*
* @return void
*/
public function testGetUsersSuccess()
{
$response = $this->get('api/v1/users', $this->headersWithToken());
$response->assertStatus(Response::HTTP_OK);
$response->assertJson([
'status' => true,
]);
$response->assertJsonStructure([
'status',
'message',
'data',
]);
}
/**
* Test get list users paginate success.
*
* @return void
*/
public function testGetUsersPaginateSuccess()
{
$response = $this->get('api/v1/users/paginate', $this->headersWithToken());
$response->assertStatus(Response::HTTP_OK);
$response->assertJson([
'status' => true,
]);
$response->assertJsonStructure([
'data',
'status',
'pagination',
'message',
]);
}
/**
* Test get list users paginate error.
*
* @return void
*/
public function testGetUsersPaginateInvalid()
{
$response = $this->get('api/v1/users/paginate?page=abc', $this->headersWithToken());
$response->assertStatus(Response::HTTP_UNPROCESSABLE_ENTITY);
}
/**
* Test get detail user.
*
* @return void
*/
public function testGetUserSuccess()
{
$user = $this->createUser();
$response = $this->get('api/v1/users/' . $user->id, $this->headersWithToken());
$response->assertStatus(Response::HTTP_OK);
$response->assertJson([
'status' => true,
]);
$response->assertJsonStructure([
'status',
'message',
'data',
]);
}
/**
* Test update user.
*
* @return void
*/
public function testUpdateUserSuccess()
{
$user = $this->createUser();
$params = [
'name' => 'test',
];
$response = $this->put('api/v1/users/' . $user->id, $params, $this->headersWithToken());
$response->assertStatus(Response::HTTP_OK);
$response->assertJson([
'status' => true,
]);
$response->assertJsonStructure([
'status',
'message',
'data',
]);
$this->assertDatabaseHas('users', [
'name' => 'test',
]);
}
/**
* Test update user.
*
* @return void
*/
public function testDeleteUserSuccess()
{
$user = $this->createUser();
$response = $this->delete('api/v1/users/' . $user->id, [], $this->headersWithToken());
$response->assertStatus(Response::HTTP_OK);
$response->assertJson([
'status' => true,
]);
$response->assertJsonStructure([
'status',
'message',
'data',
]);
}
}
Chú ý sử dụng các trait DatabaseTransactions
RefreshDatabase
để clear dữ liệu trong database
// Truncate database
// Xoá tất cả dữ liệu trong database khi run test
use Illuminate\Foundation\Testing\RefreshDatabase;
// Database transactions
// Chỉ xoá dữ liệu do chạy test tạo ra
use Illuminate\Foundation\Testing\DatabaseTransactions;
Command chạy unitest trong laravel
// Test all
php artisan test
// Test use config in env.testing
php artisan test --env=testing
// Test for special file
php artisan test --filter=UserControllerTest
// Test for special function
php artisan test --filter=testGetUsersSuccess
Sử dụng test coverage để check độ bao phủ của test, giúp chúng ta có thể check được mình đã viết đủ cảc case test chưa. Để test được coverage cần config Xdebug
// Install Xdebug in dockerFile
RUN pecl install xdebug && \
docker-php-ext-enable xdebug
// Config php trong file php.ini
[XDebug]
zend_extension=xdebug.so
xdebug.mode=coverage
xdebug.start_with_request=no
Config test coverage trong file phpunit.xml
Chạy command check độ bao phủ của test
php artisan test --coverage
// Test chỉ pass khi các file test có độ bao phủ test lớn hơn 80%
php artisan test --coverage --min=80
Như vậy chúng ta đã đã config, viết xong unitest, check được độ bao phủ của test. Giờ đến lượt bạn thử viết test với laravel cho ứng dụng của mình.Thanks for reading...