All notable changes of the PHPUnit 12.5 release series are documented in this file using the Keep a CHANGELOG principles.
12.5.22 - 2026-04-17
- #6590: Silent failure when configuration file is invalid
- #6592: INI metacharacters
;and"are not preserved when forwarding settings to child processes
12.5.21 - 2026-04-16
- #5860: PHP CLI
-dsettings are not forwarded to child processes for process isolation - #6451: Incomplete version in
RequiresPhp(e.g.<=8.5) is compared against full PHP version, causing unexpected skips
12.5.20 - 2026-04-15
- #5993:
DefaultJobRunnerdeadlocks on child processes that write large amounts of stderr output - #6465: SAPI-populated
$_SERVERentries leak from parent into child process - #6587:
failOnEmptyTestSuite="false"inphpunit.xmlis ignored when--group/--filter/--testsuitematches no tests - #6588: Order of issue baseline entries is not canonicalized
12.5.19 - 2026-04-13
- Regression in XML configuration migration introduced in PHPUnit 12.5.8
12.5.18 - 2026-04-13
- #4571: No warning when
--random-order-seedis used when test execution order is not random - #4975:
--filterdoes not work when filter string starts with# - #5354: JUnit XML logger does not handle
TestSuiteSkippedevent - #6276: Exit with non-zero exit code when explicit test selection (
--filter,--group,--testsuite) yields no tests - #6583: Failing output expectation skips
tearDown()and handler restoration, causing subsequent tests to be marked as risky
12.5.17 - 2026-04-08
- #4793: Exit with non-zero exit code when
exitwas called from some test
- #5881:
colors="true"in XML configuration file does not unconditionally enable colored output - #6019:
--migrate-configurationdoes not update schema location when XML content already validates against current schema - #6372: Assertion failure inside
willReturnCallback()is silently swallowed when code under test catches exceptions - #6464: Process isolation template unconditionally calls
set_include_path() - #6571: Static analysis errors for
TestDoubleBuildermethod chaining
12.5.16 - 2026-04-03
- #6547: Support for
%r...%rinEXPECTFsection
- #6025:
FILE_EXTERNALbreaks__DIR__ - #6351: No warning when the same test runner extension is configured more than once
- #6433: Logic in
TestSuiteLoaderis brittle and causes "Class FooTest not found" even for valid tests in valid filenames - #6463: Process Isolation fails on non-serializable globals and quietly ignore closures
12.5.15 - 2026-03-31
- #4440: Improve error when configured code coverage file list is empty
- #6549: Allow to stub both hooks of non-virtual properties
- #6529: Git "detached HEAD state" in Open Test Reporting (OTR) XML logger not handled properly
- #6545: Stubbing a class with set property hook leaves property uninitialized by default
- The
RegularExpressionandStringMatchesFormatDescriptiondid not handlepreg_match()errors such asCompilation failed: regular expression is too large
12.5.14 - 2026-02-18
- #6521: Performance regression in PHPUnit 11.5.54, PHPUnit 12.5.13, and PHPUnit 13.0.4
12.5.13 - 2026-02-18
- #6489: Classification of self/direct/indirect deprecation triggers is not aligned with Symfony's bridge for PHPUnit
12.5.12 - 2026-02-16
12.5.11 - 2026-02-10
- #6510: Deprecate using
with*()on test stubs
- #6503: Temporary file used by
SourceMappermay be deleted prematurely when multiple PHPUnit processes run in parallel - #6509: "No expectations were configured for the mock object ..." notice is emitted when
with()is used withoutexpects()
12.5.10 - 2026-02-08
- #6495: Source map for issue trigger identification is regenerated in process isolation child processes
12.5.9 - 2026-02-05
- #6488: Allow disabling issue trigger identification for improved performance
- #6486: Incorrect file name reported for errors for test methods declared in traits
- #6490: Incorrect test count when tests are skipped in before-class method
12.5.8 - 2026-01-27
- To prevent Poisoned Pipeline Execution (PPE) attacks using prepared
.coveragefiles in pull requests, a PHPT test will no longer be run if the temporary file for writing code coverage information already exists before the test runs
12.5.7 - 2026-01-24
- #6362: Manually instantiated test doubles are broken since PHPUnit 11.2
- #6470: Infinite recursion in
Count::getCountOf()for unusal implementations ofIteratororIteratorAggregate
12.5.6 - 2026-01-16
- Reverted a change that caused a build failure for the PHP project's nightly community job
12.5.5 - 2026-01-15
PHPUnit\Framework\MockObjectexceptions are now subtypes ofPHPUnit\Exception
- #6461:
any()matcher (soft deprecation)
- #6470: Mocking a class with a property hook setter accepting more types than the property results in a fatal error
12.5.4 - 2025-12-15
- The
#[AllowMockObjectsWithoutExpectations]attribute can now be used on the method level
- #6446: Test runner crashes with
Timer::start() has to be called before Timer::stop()
12.5.3 - 2025-12-11
- The message emitted when a test method creates a mock object but does not configure any expectations for it has been improved
12.5.2 - 2025-12-08
- Attribute
#[AllowMockObjectsWithoutExpectations]for excluding tests from the check that emits the notice for test methods that create a mock object but do not configure an expectation for it
12.5.1 - 2025-12-06
TestCase::getStubBuilder()(analogous toTestCase::getMockBuilder()) for creating (partial) test stubs using a fluent API
12.5.0 - 2025-12-05
- #6376:
--allCLI option to ignore test selection configured in XML configuration file - #6422: Make
<source>element in XML code coverage report optional
- #6380: Allow
ThrowableinexpectExceptionObject() - A PHPUnit notice is now emitted for test methods that create a mock object but do not configure an expectation for it