PHPUnit, Feature Tests trong Laravel
php artisan make:test PostControllerTest
<?php
// tests/Feature/PostControllerTest.php
namespace Tests\Feature;
use App\Models\Post;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class PostControllerTest extends TestCase
{
use RefreshDatabase;
public function test_can_list_posts(): void
{
Post::factory()->count(5)->create();
$response = $this->getJson('/api/posts');
$response->assertStatus(200)
->assertJsonCount(5, 'data')
->assertJsonStructure([
'data' => [
'*' => ['id', 'title', 'slug', 'created_at']
]
]);
}
public function test_can_create_post(): void
{
$user = User::factory()->create();
$response = $this->actingAs($user)
->postJson('/api/posts', [
'title' => 'Test Post',
'content' => 'Test content here',
]);
$response->assertStatus(201)
->assertJson([
'data' => [
'title' => 'Test Post',
]
]);
$this->assertDatabaseHas('posts', [
'title' => 'Test Post',
'user_id' => $user->id,
]);
}
public function test_guest_cannot_create_post(): void
{
$response = $this->postJson('/api/posts', [
'title' => 'Test Post',
'content' => 'Test content',
]);
$response->assertStatus(401);
}
public function test_validation_errors(): void
{
$user = User::factory()->create();
$response = $this->actingAs($user)
->postJson('/api/posts', [
'title' => '', // Empty - should fail
]);
$response->assertStatus(422)
->assertJsonValidationErrors(['title', 'content']);
}
}
php artisan make:test Services/OrderServiceTest --unit
<?php
// tests/Unit/Services/OrderServiceTest.php
namespace Tests\Unit\Services;
use App\Models\Order;
use App\Models\Product;
use App\Services\OrderService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class OrderServiceTest extends TestCase
{
use RefreshDatabase;
private OrderService $orderService;
protected function setUp(): void
{
parent::setUp();
$this->orderService = new OrderService();
}
public function test_calculate_total(): void
{
$items = [
['price' => 100, 'quantity' => 2],
['price' => 50, 'quantity' => 3],
];
$total = $this->orderService->calculateTotal($items);
$this->assertEquals(350, $total);
}
public function test_apply_discount(): void
{
$total = 1000;
$discountPercent = 10;
$result = $this->orderService->applyDiscount($total, $discountPercent);
$this->assertEquals(900, $result);
}
public function test_free_shipping_over_500(): void
{
$this->assertTrue($this->orderService->hasFreeShipping(600));
$this->assertFalse($this->orderService->hasFreeShipping(400));
}
}
# Chạy tất cả tests
php artisan test
# Chạy test cụ thể
php artisan test --filter=PostControllerTest
# Chạy với coverage
php artisan test --coverage
# Parallel testing (nhanh hơn)
php artisan test --parallel
php artisan test trong pipeline để đảm bảo
code quality.