Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

ame180's avatar

Laravel Feature Tests always return 404

DISCLAIMER: I had to add spaces around all . because it read them as links for some reason. Sorry for that.

I'm struggling to make my Feature Tests run with Laravel. I ran out of options. Multiple people tried to help me already, to no avail. No one has any clue what's going on. This is the error I get (with withoutExceptionHandling to show the URL):

 • Tests\Feature\ClientTest > example
   Symfony\Component\HttpKernel\Exception\NotFoundHttpException 

  GET http://localhost/sunny-camping/welcome

  at vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel . php:416
    412▕      * @return \Symfony\Component\HttpFoundation\Response
    413▕      */
    414▕     protected function renderException($request, Throwable $e)
    415▕     {
  ➜ 416▕         return $this->app[ExceptionHandler::class]->render($request, $e);
    417▕     }
    418▕ 
    419▕     /**
    420▕      * Get the application's route middleware groups.

      +1 vendor frames
  2   tests/Feature/ClientTest . php:19
      Illuminate\Foundation\Testing\TestCase::get()

Obviously if I click the URL everything works fine, but the test gives me 404... The page itself is default welcome page from Laravel. Now for the files:

ClientTest . php

<?php

namespace Tests\Feature;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Tests\TestCase;

class ClientTest extends TestCase
{
    /**
     * A basic feature test example.
     *
     * @return void
     */
    public function test_example()
    {
        $this->withoutExceptionHandling();
        $response = $this->get('/welcome');

        $response->assertStatus(200);
    }
}

web . php

<?php

use App\Http\Controllers\Admin\ClientController;
use App\Http\Controllers\AdminController;
use App\Http\Controllers\HomeController;
use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/{year?}', [HomeController::class, 'home'])->where('year', '[0-9]+')->name('home');

Route::prefix('/admin')->group(function () {
    Route::prefix('/clients')->group(function () {
        Route::get('/add-client', [ClientController::class, 'addClient']);
        Route::get('/edit/{id}', [ClientController::class, 'edit'])->name('admin . clients . edit');
        Route::put('/add', [ClientController::class, 'add']);
        Route::patch('/update/{id}', [ClientController::class, 'update']);
        Route::delete('/delete/{id}', [ClientController::class, 'delete']);
        Route::get('/paginated-json', [ClientController::class, 'paginatedJson']);
        Route::get('/find-json/{id}', [ClientController::class, 'findJson']);
    });
    Route::get('/dashboard', [AdminController::class, 'dashboard'])->name('admin . dashboard');
    Route::get('/clients', [AdminController::class, 'clients'])->name('admin . clients');
    Route::get('/bills', [AdminController::class, 'bills']);
    Route::redirect('/', 'admin/dashboard');
});

Route::get('/welcome', function () {
    return view('welcome');
});

I'm running everything from Windows Subsystem Linux, using Apache and MariaDB.

So far I tried multiple things:

  • php artisan serve (no clue why but it helped some people, not me though)
  • Different URIs
  • Making . env . testing file with APP_URL set to the same as . env file
  • Adding APP_URL to phpunit . xml file <server name="APP_URL" value="http://localhost/sunny-camping"/>
  • Pasting full URLs as the URI
  • Copying URIs from php artisan routes:list
  • Using `route('myroutename')' instead of URI

(just to make it clear, I tried those things separately, from "clean" setup)

All of this to no avail. I keep getting 404 and I have no clue how to fix this. I went through multiple queries and over 2 pages of Google and found no solution...

Any ideas are appreciated.

EDIT: my . env file

APP_NAME="Sunny Camping"
APP_ENV=local
APP_KEY=base64:VvmQ1A56XyRz8XAsq011cb8LRXqG6NNYCXBAaRvnPOI=
APP_DEBUG=true
APP_URL=http://localhost/sunny-camping

ASSET_URL=http://localhost/sunny-camping/public
MIX_ASSET_URL=http://localhost/sunny-camping/public

LOG_CHANNEL=stack
LOG_LEVEL=debug

DB_CONNECTION=mysql
DB_HOST=127 . 0 . 0 . 1
DB_PORT=3306
DB_DATABASE=sunny_camping
DB_USERNAME=root
DB_PASSWORD=

BROADCAST_DRIVER=log
CACHE_DRIVER=file
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120

REDIS_HOST=127 . 0 . 0 . 1
REDIS_PASSWORD=null
REDIS_PORT=6379

MAIL_MAILER=smtp
MAIL_HOST=smtp . mailtrap . io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS=null
MAIL_FROM_NAME="${APP_NAME}"

AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=

PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1

MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
0 likes
8 replies
Sergiu17's avatar

What is sunny-camping?

GET http://localhost/sunny-camping/welcome

it tries to load route specified above, and you don't have one

ame180's avatar

sunny-camping is the root of my project. I should probably include my .env now that I think about it...

ame180's avatar

Unfortunately, no.

Expected status code 200 but received 404.
Failed asserting that 200 is identical to 404.
Sergiu17's avatar
Sergiu17
Best Answer
Level 60

@jacynoadam

<server name="APP_URL" value="http://localhost"/>

This is how you url should look in phpunit.xml file

2 likes
ame180's avatar

YES EXACTLY!

I did the same thing making a new . env . testing and setting it to just localhost.

I have no idea why it works this way, but it's fixed, after all these hours, such a simple fix... thank you!

jamessoncardozo's avatar

@jacynoadam Sorry. I changed my last reply. It actually really worked. That's exactly what was hindering my testing. Regardless of my route, it always resulted in an error. Thanks a lot.

tykus's avatar

Put this route at the end of the Routes file, it is matching the welcome segment:

Route::get('/{year?}', [HomeController::class, 'home'])->where('year', '[0-9]+')->name('home');
ame180's avatar

I tried that too and it didn't change anything (I can access both /welcome and /{year} separately)

Please or to participate in this conversation.