Skip to content

Instantly share code, notes, and snippets.

@ronssij
Last active February 19, 2026 10:02
Show Gist options
  • Select an option

  • Save ronssij/ec86ac6771a761663fed016bc854d8f3 to your computer and use it in GitHub Desktop.

Select an option

Save ronssij/ec86ac6771a761663fed016bc854d8f3 to your computer and use it in GitHub Desktop.

Test File Organization

When creating feature tests for controllers, organize test files by controller method, not by controller.

Convention

For a controller at app/Http/Controllers/{Path}/{ControllerName}.php with methods {methodOne}, {methodTwo}, etc., create separate test files:

tests/Feature/Controllers/{Path}/{ControllerName}/
├── {MethodOne}Test.php
├── {MethodTwo}Test.php
└── {MethodThree}Test.php

Examples

Controller: app/Http/Controllers/Stripe/StripeConnectController.php

  • Methods: handleReturn, handleRefresh

Test files:

tests/Feature/Controllers/Stripe/StripeConnectController/
├── HandleReturnTest.php
└── HandleRefreshTest.php

Controller: app/Http/Controllers/UserController.php

  • Methods: index, store, update, destroy

Test files:

tests/Feature/Controllers/UserController/
├── IndexTest.php
├── StoreTest.php
├── UpdateTest.php
└── DestroyTest.php

Test File Naming

  • Use the method name in StudlyCase (PascalCase)
  • Append Test.php suffix
  • Each file should contain all test cases for that specific method only

Single Action Controllers

For single action controllers using __invoke, create a single test file named InvokeTest.php:

Controller: app/Http/Controllers/Stripe/AccountLinkController.php

  • Method: __invoke

Test file:

tests/Feature/Controllers/Stripe/AccountLinkController/
└── InvokeTest.php

Why This Pattern

  • Focused tests: Each file contains tests for a single method
  • Easier navigation: Quickly find tests for specific controller actions
  • Better organization: Matches the mental model of "one method = one responsibility"
  • Clearer scope: When reading a test file, you know exactly which method is being tested
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment