laravelunit-testingtestinglaravel-11

What is the difference in feature test and unit test in laravel?


I'm new to testing in Laravel and I used to think that unit tests and feature tests were the same thing.

But now I realize there's a big difference between them.

Can someone please explain—preferably with examples—what exactly is the difference between unit tests and feature tests in Laravel? When should I use one over the other?

I tried writing some tests in Laravel 11 using both

php artisan make:test with the --unit flag and without it.

I expected both types of tests to work the same way since they looked similar at first. But when I ran them, I noticed they behave differently, especially when interacting with the database or HTTP routes.

I’m confused about which type to use for what purpose.


Solution

  • When Should You Use What?

    Use unit tests when you want fast, isolated tests for internal logic.

    Use feature tests when testing real-world flows through your app that may depend on routing, middleware, or the database.

    Unit Tests

    Example:

    // tests/Unit/PriceCalculatorTest.php
    
    use Tests\TestCase;
    
    class PriceCalculatorTest extends TestCase
    {
        public function test_discount_is_applied_correctly()
        {
            $calculator = new \App\Services\PriceCalculator();
            $result = $calculator->applyDiscount(100, 10); // 10%
    
            $this->assertEquals(90, $result);
        }
    }
    

    Feature Tests

    Example

    // tests/Feature/UserRegistrationTest.php
    
    use Illuminate\Foundation\Testing\RefreshDatabase;
    use Tests\TestCase;
    
    class UserRegistrationTest extends TestCase
    {
        use RefreshDatabase;
    
        public function test_user_can_register()
        {
            $response = $this->post('/register', [
                'name' => 'John Doe',
                'email' => 'john@example.com',
                'password' => 'password',
                'password_confirmation' => 'password',
            ]);
    
            $response->assertRedirect('/home');
            $this->assertDatabaseHas('users', ['email' => 'john@example.com']);
        }
    }