Skip to content

Breaking change in Laravel 12.42.0: Commands named *Test.php no longer discovered #58106

@krzysztofgwiazda

Description

@krzysztofgwiazda

Laravel Version

12.42.0

PHP Version

8.2.27

Database Driver & Version

No response

Description

After upgrading to Laravel 12.42.0, some of our Artisan commands stopped being registered.
The root cause is the change introduced in commit:

d03f650

This change silently excludes files named *Test.php from command discovery.

Why this is a problem

Until 12.42.0, naming a command file *Test.php was a valid and supported use case.
There was no documented restriction or deprecation warning suggesting that such filenames were reserved or invalid.

As a result:

  • Existing production applications broke after a minor version upgrade
  • There was no prior deprecation notice
  • No opt-in mechanism or configuration to control this behavior

This effectively introduces a breaking change in a minor release.
Laravel explicitly documents that minor releases should not introduce breaking changes to application code, which violates the expectations set by Laravel’s versioning policy and Semantic Versioning principles.

Inconsistent framework behavior

The framework itself still allows creating such commands.

For example, running:

php artisan make:command Test

generates a command class in Test.php, even though commands with this filename are no longer discovered at runtime.

This creates an internal inconsistency:

  • The framework allows generating command classes named *Test.php
  • The same framework silently ignores them during command discovery
    From a developer experience perspective, this is confusing and misleading.

Design concern

The change assumes that files ending with Test.php must always be PHPUnit test files.

This assumption does not hold universally.
In our case, *Test.php commands were used intentionally (e.g. test runners, diagnostics, QA tooling, sandbox commands).

Laravel previously allowed this, so excluding these files retroactively is a behavioral regression.

Suggested approaches

One of the following would avoid breaking existing applications:

  1. Defer this change to the next major release
  2. Add a configuration option to control exclusion rules
  3. Introduce a deprecation cycle with warnings before enforcing the behavior
  4. Narrow the exclusion logic to test directories only (e.g. /tests)

Summary

This change breaks existing, valid applications without warning and introduces inconsistent framework behavior.
Please consider reverting or softening this change to preserve backward compatibility.

Thank you for considering this feedback.

Steps To Reproduce

  1. Upgrade an application from Laravel 12.41.x to 12.42.0
  2. Create a command named FooTest located in app/Console/Commands/FooTest.php
  3. Run php artisan list

Expected: command is listed
Actual: command is silently missing

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions