sebastianbergmann/phpunit
72.9
Strong · 26 September 2026
89.4k
lines of production code
PHP
primary language
3
measurements over time
What this system is
This system is the PHPUnit testing framework, a tool for executing and validating PHP code through unit and integration tests. It provides a comprehensive event-driven architecture that captures granular telemetry, manages test execution order, and handles process isolation for reliable test runs. The framework supports extensive output formatting via multiple logging backends and offers advanced capabilities for mocking, code coverage analysis, and deprecation tracking.
How it got here
2010–2021 — PHPUnit 13.4 modernization and event system
102 changes.
This period focused on the comprehensive modernization of PHPUnit 13.4, migrating the codebase to modern PHP features such as readonly properties, strict typing, and native PHP 8 attributes for metadata. A major architectural shift introduced a new event-driven subsystem with telemetry and immutable value objects, replacing legacy monolithic components in the test runner, CLI, and configuration handling. The work also included extensive refactoring of constraints, mock objects, and exception hierarchies to improve type safety and internal consistency.
2022–2023 — Event-driven architecture and test double enhancements
89 changes.
PHPUnit underwent a major architectural shift to an event-driven system, introducing new event classes, subscribers, and a centralized output facade to replace legacy result objects. This period also saw significant refactoring of the mock object generator to support invocation ordering and parameter-set matching, alongside the introduction of a baseline system for suppressing known deprecations and warnings.
2024–2026 — Test execution engine and reliability overhaul
109 changes.
This period focused on a comprehensive refactoring of the test execution engine, introducing a modular job runner for improved process isolation, security, and non-blocking worker management. It also implemented significant reliability features such as test run history for detecting flaky tests, a configurable execution order pipeline, and a cached test index to optimize startup performance. These core changes were accompanied by the addition of new output formats, logging standards, and extensive end-to-end test coverage to validate the new behaviors.
Features
Add IsTrue, IsFalse, IsFinite, IsInfinite, and IsNan constraints
New assertion constraints have been added to the framework, allowing tests to verify boolean values (IsTrue, IsFalse) and numeric properties (IsFinite, IsInfinite, IsNan). These constraints provide specific failure messages for both positive and negative assertions, improving the clarity of test output when validating these specific data types.
src/Framework/Constraint/Math · high confidence
Add Open Test Reporting (OTR) XML logger
Introduces a new OtrXmlLogger that writes test execution results to an XML file conforming to the Open Test Reporting schema (version 0.2.0). The output includes infrastructure details such as the host name, operating system, PHP version, and thread model, along with comprehensive test lifecycle events. It supports nested test suites via parentId attributes, reports reasons for assertion failures and exceptions, includes CPU time telemetry, and optionally embeds Git repository information. Unexpected output is attached under the \<reported\> element, and TestDox information is included in the report.
src/Logging/OpenTestReporting · high confidence
Added XML configuration schemas for PHPUnit 10.0 through 11.3
New XSD schema files have been added to the schema directory to define the structure of PHPUnit XML configuration files for versions 10.0, 10.5, 11.0, 11.1, 11.2, and 11.3. These schemas validate configuration files, supporting features such as source code filtering, code coverage reporting, test execution ordering, and deprecation handling specific to each PHPUnit version.
schema · high confidence
Added test data value objects and collection for PHPUnit events
This change introduces a new set of immutable, readonly value objects within the \PHPUnit\\Event\\TestData\ namespace to represent test data sources. It adds a base \TestData\ abstract class with concrete implementations for data originating from data providers (\DataFromDataProvider\) and test dependencies (\DataFromTestDependency\). A \TestDataCollection\ class is also provided to manage these items, offering iteration, counting, and specific access to data-provider entries, supported by a dedicated \TestDataCollectionIterator\. These classes are marked as internal and not covered by the backward compatibility promise, serving as the structural foundation for event payloads related to test data.
src/Event/Value/Test/TestData · high confidence
Automatic PHP garbage collection during test runs
PHPUnit now automatically triggers PHP's garbage collector (gc\_collect\_cycles) at the start and end of a test run, and periodically after every N tests (configurable via a threshold). This helps manage memory usage during long-running test suites by clearing circular references. The feature is implemented via new internal subscriber classes that hook into the test runner's lifecycle events.
src/Runner/GarbageCollection · high confidence
Initial project configuration and documentation scaffolding
This change introduces the foundational configuration files and documentation for the PHPUnit project. It adds an .editorconfig to enforce consistent coding styles (LF line endings, 4-space indentation for PHP, 2-space for YAML), a .gitattributes file to manage export-ignores for build and tool directories, and a .gitignore to exclude build artifacts, caches, and IDE files. It also establishes the initial .php-cs-fixer.dist.php configuration with a comprehensive set of formatting rules, along with standard project files including LICENSE, README.md, SECURITY.md, and the initial ChangeLog and DEPRECATIONS documentation for version 13.4.
(repo-wide) · high confidence
Introduce IssueTriggerResolver interface and default implementation
Added the \IssueTriggerResolver\ component, consisting of the \Resolver\ interface, the \Resolution\ data class, and the \DefaultResolver\ implementation. This new structure allows the runner to resolve issue triggers from stack traces in a modular way, with the default resolver extracting callee and caller file information from the trace array.
src/Runner/IssueTriggerResolver · high confidence
Introduce baseline generation for deprecations, notices, and warnings
Adds a new baseline system in \src/Runner/Baseline\ that allows PHPUnit to record and suppress known deprecations, notices, and warnings. The \Generator\ class registers event subscribers to capture these issues during test runs, while \Reader\ and \Writer\ handle loading and saving the baseline as an XML file. The \Issue\ class computes a content hash for each file/line to ensure baselines remain valid even if file contents change, and \RelativePathCalculator\ ensures paths in the baseline are relative to the baseline file for portability.
src/Runner/Baseline · high confidence
Introduce compact output mode with detailed issue reporting and safety controls
A new compact text output mode is added to PHPUnit, providing a concise progress view during test execution and a detailed summary report upon completion. The compact progress printer immediately displays errors and failures as they occur, while the result printer aggregates counts of tests, assertions, errors, failures, and various warnings (deprecations, notices, warnings) into a single summary line. This mode supports displaying PHPUnit-specific deprecations and notices via dedicated flags, allows showing unexpected test output when enabled, and ensures user-supplied strings are sanitized to prevent formatting issues in the output.
src/TextUI/Output/Compact · high confidence
Introduce dedicated TestDox HTML and Plain Text renderers
The TestDox logging subsystem now includes new \HtmlRenderer\ and \PlainTextRenderer\ components to generate human-readable documentation of test outcomes. The HTML renderer produces a styled report featuring a summary of passed and failed tests, with individual test classes and methods displayed in cards that visually indicate success or failure using checkmarks and crosses, while also supporting light and dark color schemes. The plain text renderer provides a concise, terminal-friendly output that lists test classes followed by their prettified method names and status indicators (pass/fail). These renderers work in conjunction with the refactored \NamePrettifier\ to format test names and handle data provider values, ensuring that special characters like dollar signs are preserved and control characters are made visible in the output.
src/Logging/TestDox · high confidence
Introduce dedicated deprecation collection subsystem
PHPUnit now includes a new \DeprecationCollector\ component (located in \src/Runner/DeprecationCollector\) that manages the gathering and filtering of deprecation warnings during test execution. This subsystem introduces a \Collector\ class to aggregate deprecation messages, an \InIsolationCollector\ variant for isolated test runs, and a \Facade\ to initialize and access these collectors. The implementation leverages the event system to capture \DeprecationTriggered\ events and applies an \IssueFilter\ to determine which deprecations should be processed and reported, separating them into general and filtered lists for more granular control over deprecation output.
src/Runner/DeprecationCollector · high confidence
Introduce test run history to persist test results across executions
PHPUnit now maintains a test run history (persisted by default in .phpunit.result.cache) that remembers the status and duration of tests between runs. This allows the test runner to detect flaky tests and optimize execution order by re-running previously failing tests first. The history is updated when a test's status changes (e.g., from failing to passing) and pruned when tests are removed from the codebase. Skipped tests do not overwrite recorded durations, and the history is persisted only after the entire test suite has finished executing.
src/Runner/TestRunHistory · high confidence
Introduces a new telemetry system with CPU time and garbage collector metrics
PHPUnit now provides a comprehensive telemetry system for tracking test execution performance. This change adds new immutable value objects and interfaces in the \PHPUnit\\Event\\Telemetry\ namespace, including \CpuTime\, \Duration\, \HRTime\, \MemoryUsage\, and \GarbageCollectorStatus\. The system introduces \Info\ and \Snapshot\ classes that aggregate these metrics, allowing users to observe CPU time (user and system), memory usage, and garbage collector status during test runs. Implementations like \SystemCpuTimeMeter\ and \SystemGarbageCollectorStatusProvider\ leverage PHP's \getrusage()\ and \gc\_status()\ functions to provide accurate, low-level performance data.
src/Event/Value/Telemetry · high confidence
Introduces immutable metadata value objects for PHPUnit annotations and attributes
The \src/Metadata\ directory now contains a comprehensive set of immutable, readonly value objects (such as \Before\, \After\, \DataProvider\, \CoversClass\, \DependsOnMethod\, and \RequiresEnvironmentVariable\) that represent test metadata. These classes replace the previous annotation/attribute parsing logic with a structured, type-safe model, enabling PHPUnit to handle lifecycle hooks, coverage requirements, data providers, and environment dependencies through a unified, immutable API.
src/Metadata · high confidence
Introduction of HTTP downloader abstraction
A new internal interface \PHPUnit\\Util\\Http\\Downloader\ and its concrete implementation \PhpDownloader\ have been added to the \src/Util/Http\ directory. The \PhpDownloader\ class provides a basic HTTP download capability using PHP's \file\_get\_contents\ function. This change introduces a new internal component for handling HTTP downloads within the PHPUnit utility layer.
src/Util/Http · high confidence
Introduction of the new Event subsystem facade and core infrastructure
This change introduces the foundational components of PHPUnit's new event system within the src/Event directory. It adds the Event\\Facade class, which manages the lifecycle of event registration and dispatching, including methods to register subscribers and tracers, seal the facade to prevent further modifications, and handle deferred dispatching. The update also includes the core interfaces Subscriber and Tracer, along with the TypeMap class responsible for mapping subscriber interfaces to their corresponding event classes and validating event types. This infrastructure enables the emission of various test lifecycle and telemetry events, marking a significant architectural shift in how PHPUnit handles internal state and external observability.
src/Event · high confidence
Mock objects now record invocation order and support parameter-set matching rules
The mock object runtime now records the order in which methods are invoked, enabling assertions on call sequences. Additionally, new methods like withParameterSetsInOrder, withParameterSetsInAnyOrder, and withParameterSetsInPartialOrder allow matching method calls based on specific parameter sets, improving the precision of mock expectations.
src/Framework/MockObject/Runtime · high confidence
New EventLogger class for structured test event logging
A new EventLogger class has been added to the PHPUnit logging subsystem to handle the output of test events. This logger writes event data to a specified file path (or stdout), optionally including telemetry information. It normalizes line endings to ensure consistent formatting across different operating systems and applies exclusive file locking (LOCK\_EX) on Linux/Unix systems while omitting it on Windows and macOS to prevent file access errors.
src/Logging · high confidence
New JUnit XML logger implementation
A new JUnit XML logger has been introduced in src/Logging/JUnit/JunitXmlLogger.php. This component subscribes to the event system to capture test suite and test case lifecycle events, constructing a DOM-based XML report that includes suite metadata (name, file, test/assertion/error/failure/skipped counts, and time) and individual test case details. It handles various test outcomes such as passed, failed, errored, skipped, and incomplete states, ensuring proper XML structure including testcase elements for skipped tests.
src/Logging/JUnit · high confidence
New PHAR bootstrap templates with PHP version and extension checks
Added two new build templates for PHAR distribution: \binary-phar-autoload.php.in\ and \library-phar-autoload.php.in\. The binary template now includes runtime validation to ensure the PHP version is at least 8.4.1 and that required extensions (ctype, dom, filter, json, libxml, mbstring, tokenizer, xmlwriter) are available, exiting with a clear error message if not. It also supports new command-line flags (\--composer-lock\, \--manifest\, \--sbom\) to dump specific metadata files from the PHAR archive. The library template provides a simpler autoload mechanism without these checks or flags.
build/templates · high confidence
New PHP 8 attributes for test configuration and metadata
This change introduces a comprehensive set of new PHP 8 attributes in the \src/Framework/Attributes\ directory, providing a modern, type-safe alternative to annotations for configuring PHPUnit tests. These include lifecycle hooks (\Before\, \After\, \BeforeClass\, \AfterClass\, \PreCondition\, \PostCondition\) with priority support, dependency management (\Depends\, \DependsExternal\, \DependsOnClass\ with deep/shallow clone options), and coverage tracking (\CoversClass\, \CoversMethod\, \CoversFile\, etc.). It also adds attributes for test data providers (\DataProvider\, \DataProviderClosure\, \DataProviderExternal\), environment and requirement checks (\RequiresPhp\, \RequiresEnvironmentVariable\, \RequiresOperatingSystem\), and test behavior control (\Group\, \Repeat\, \IgnoreDeprecations\, \DisableReturnValueGenerationForTestDoubles\). All attribute classes are declared as \final readonly\ to ensure immutability and strict type safety.
src/Framework/Attributes · high confidence
New TestRunner and Application lifecycle events
The event system now exposes granular lifecycle events for the TestRunner and the Application. New events include Application\\Started and Application\\Finished to track the overall process, alongside TestRunner events for configuration (Configured), execution phases (ExecutionStarted, ExecutionFinished, ExecutionAborted), and bootstrap completion (BootstrapFinished). The diff also introduces events for child process management (ChildProcessStarted, ChildProcessFinished, ChildProcessErrored), extension loading (ExtensionBootstrapped, ExtensionLoadedFromPhar), and internal runtime behaviors like garbage collection (GarbageCollectionEnabled, GarbageCollectionDisabled, GarbageCollectionTriggered) and deprecation handling (DeprecationTriggered). Each event is paired with a corresponding Subscriber interface, allowing users to hook into these specific lifecycle moments.
src/Event/Events/TestRunner · high confidence
New XML configuration model for code coverage and logging reports
The XML configuration system now uses dedicated immutable value objects to represent code coverage and logging report settings, allowing users to configure these outputs via XML. Code coverage reports can now be configured for Clover, Cobertura, Crap4j, HTML, JSONL, OpenClover, PHP, Text, and XML formats, with the HTML report supporting granular control over class/file views, color thresholds, and custom CSS. Logging outputs are similarly structured for JUnit, Open Test Reporting (OTR), TeamCity, and TestDox (HTML/Text). These configuration classes are consumed by the new XML Loader, which parses the XML file and maps it to the internal configuration model.
src/TextUI/Configuration/Xml · high confidence
New XML configuration validation classes
Added two new internal classes, Validator and ValidationResult, to the TextUI XML configuration subsystem. The Validator class now handles schema validation of XML configuration documents against XSD files using libxml, returning structured error details via the new ValidationResult class, which aggregates and formats validation errors by line number for user reporting.
src/TextUI/Configuration/Xml/Validator · high confidence
New build automation scripts for release management and PHAR integrity
The build process now includes several new PHP scripts to streamline release workflows and ensure PHAR integrity. \check-scoped-phar.php\ verifies that PHAR archives are correctly scoped, while \phar-version.php\ and \version.php\ handle version string extraction and injection for PHAR builds. \phar-manifest.php\ generates software bill of materials (SBOM) and manifest files from composer data. Additionally, \extract-release-notes.php\ automates the extraction of release notes from changelogs, and \prepare-patch-release.php\ automates the version bumping and changelog updates required for patch releases.
build/scripts · high confidence
New event collection and iteration infrastructure
The event system now includes a new \Event\ interface defining telemetry and string representation capabilities, alongside an \EventCollection\ class that aggregates events and supports counting, emptiness checks, and array conversion. A corresponding \EventCollectionIterator\ enables standard PHP iteration over these events, utilizing \isset()\ for validity checks to ensure safe access during traversal. These components form the foundational data structures for collecting and iterating over test events.
src/Event/Events · high confidence
New event value objects for test metadata and execution context
This change introduces a new set of immutable value objects in the \PHPUnit\\Event\\Code\ namespace to represent test information in event data. The \Test\ abstract base class and its \TestMethod\ and \Phpt\ subclasses now encapsulate details such as class/method names, file locations, line numbers, and metadata. Additionally, support for test repetitions and retries is added via \repetition\, \totalRepetitions\, \attempt\, and \maxAttempts\ properties, allowing event consumers to distinguish between repeated runs and retry attempts. The \TestDox\ and \TestDoxBuilder\ classes provide prettified class and method names for human-readable output, while \TestDataCollection\ and related builders capture data provider and dependency information. These objects form the core data structure for PHPUnit's event system, replacing previous ad-hoc data passing with a structured, typed API.
src/Event/Value/Test · high confidence
New extension bootstrapping and child-process support
PHPUnit now provides a structured extension bootstrapping system that allows extensions to register event subscribers, replace output, and require code coverage collection via the new \Facade\ interface and \ExtensionBootstrapper\. The system also introduces \ChildProcessExtension\ support, enabling extensions to run inside isolated test processes (e.g., when using \--process-isolation\) through \ChildProcessExtensionBootstrapper\ and \ChildProcessExtensionFacade\. Additionally, \PharLoader\ has been updated to explicitly warn when PHAR extensions cannot be loaded due to missing PHP extensions or manifest issues, rather than silently skipping them.
src/Runner/Extension · high confidence
New filesystem and string assertion constraints
PHPUnit now provides dedicated constraint classes for common assertions, improving clarity and error reporting. Filesystem checks are now handled by DirectoryExists, FileExists, IsReadable, and IsWritable, which validate paths and provide descriptive failure messages. String assertions have been expanded with StringContains (supporting case-insensitive and line-ending-ignoring modes with encoding details), StringStartsWith, StringEndsWith, StringEqualsStringIgnoringLineEndings, StringEqualsStringIgnoringWhitespace, StringMatchesFormatDescription (with improved diff handling for placeholders), RegularExpression, and IsJson (leveraging json\_validate() for validation and providing specific JSON error details).
src/Framework/Constraint/String · high confidence
New immutable configuration model for code coverage settings
The code coverage configuration is now handled by a new, immutable \CodeCoverage\ class that consolidates settings for drivers, path/branch coverage, and report formats (Clover, Cobertura, Crap4j, HTML, JSONL, OpenClover, PHP, Text, XML). This change introduces a structured, type-safe way to configure code coverage options in PHPUnit's XML configuration, replacing the previous ad-hoc handling with a dedicated, read-only configuration object.
src/TextUI/Configuration/Xml/CodeCoverage · high confidence
New mock object stub implementations for varied return behaviors
The \src/Framework/MockObject/Runtime/Stub\ directory now contains a suite of new stub classes that allow more granular control over mock return values. Users can configure mocks to return consecutive values from a stack (\ConsecutiveCalls\), throw a specific exception (\Exception\), return a specific argument by index (\ReturnArgument\), invoke a callback (\ReturnCallback\), return a reference to a variable (\ReturnReference\), return the mocked object itself (\ReturnSelf\), return a fixed value (\ReturnStub\), or match parameters against a map to determine the return value (\ReturnValueMap\). These classes implement the new \Stub\ interface and are marked as internal, meaning they are not covered by the backward compatibility promise.
src/Framework/MockObject/Runtime/Stub · high confidence
New object comparison and property-checking constraints
Two new constraint classes have been added to the framework: ObjectEquals, which allows comparing two objects using a custom method (defaulting to 'equals') with strict reflection-based validation of the method's signature, and ObjectHasProperty, which asserts that an object contains a specific property. These additions provide more granular and type-safe ways to verify object state and equality in tests.
src/Framework/Constraint/Object · high confidence
New runtime environment value objects for test events
PHPUnit now exposes detailed runtime context in its event system through new immutable value objects in the \PHPUnit\\Event\\Runtime\ namespace. The \Runtime\ class aggregates \OperatingSystem\, \PHP\, and \PHPUnit\ specific data, allowing users of the event API to access precise information such as the PHP version, SAPI, loaded extensions, OS family, and PHPUnit release series. These classes are marked as \readonly\ and immutable to ensure safe, consistent access to the environment state at the time the test run started.
src/Event/Value/Runtime · high confidence
New test result event subscribers for lifecycle and triggered issues
The test runner now includes a comprehensive set of new subscriber classes in the \src/Runner/TestResult/Subscriber\ directory to capture a wider range of test execution events. These subscribers handle lifecycle events such as test suite start/finish, test preparation, and before/after class method failures or errors, as well as detailed issue tracking for deprecations, errors, notices, and warnings triggered by PHP, PHPUnit, or the test code itself. By implementing these specific event interfaces, the framework ensures that all these previously unhandled or broadly handled scenarios are now explicitly collected and reported in the test result.
src/Runner/TestResult/Subscriber · high confidence
New version requirement metadata classes
The \src/Metadata/Version\ directory now contains a new set of immutable value objects (\Requirement\, \ComparisonRequirement\, \ConstraintRequirement\, and \InvalidVersionRequirement\) that handle version constraint parsing and evaluation. These classes replace previous inline logic, providing a structured way to represent version requirements using either PharIo version constraints or simple comparison operators, and are marked as part of PHPUnit's public API.
src/Metadata/Version · high confidence
Open Test Reporting subscriber infrastructure for test lifecycle events
This change adds the event-subscriber classes in src/Logging/OpenTestReporting/Subscriber that bridge PHPUnit's internal event system to the Open Test Reporting (OTR) XML logger. The new files cover the full test lifecycle—including test runner start/finish, test suite start/finish, individual test preparation, execution, and completion—as well as specific outcomes such as errors, failures, skips, risky tests, and deprecations/notices/warnings. Each subscriber delegates to the OtrXmlLogger so that these events are recorded in the OTR XML output.
src/Logging/OpenTestReporting/Subscriber · high confidence
Architecture
Refactored CLI commands into dedicated command classes
The PHPUnit CLI has been restructured by extracting specific operations into individual command classes within the \src/TextUI/Command/Commands\ directory. This change introduces dedicated implementations for configuration management (\GenerateConfigurationCommand\, \MigrateConfigurationCommand\, \ValidateConfigurationCommand\), test discovery and listing (\ListGroupsCommand\, \ListTestFilesCommand\, \ListTestIdsCommand\, \ListTestSuitesCommand\, \ListTestsAsTextCommand\, \ListTestsAsXmlCommand\), and utility functions (\AtLeastVersionCommand\, \CheckPhpConfigurationCommand\, \VersionCheckCommand\, \WarmCodeCoverageCacheCommand\). This modularization replaces the previous monolithic command handling, making the CLI logic more maintainable and explicit.
src/TextUI/Command/Commands · high confidence
Refactored TestCase internals into dedicated sub-classes
The PHPUnit test execution engine has been restructured by extracting specific responsibilities from the main TestCase class into a new set of dedicated classes within the \src/Framework/TestCase\ directory. This refactoring introduces specialized components for managing test lifecycle and state, including \BackedUpEnvironmentVariable\ and \EnvironmentVariables\ for handling environment variable backups, \ErrorLogCapture\ for selectively capturing error logs, \CustomRegistrations\ for tracking comparators and exporters, \DependencyResolver\ for handling test dependencies, and \HookMethodInvoker\ for executing lifecycle hooks. Additional classes such as \DataSet\, \ExceptionExpectation\, \DeprecationExpectation\, \GlobalStateCapture\, \MockObjectRegistry\, \OutputBuffer\, and \TestDoubleFactory\ isolate their respective logic, improving code organization and maintainability.
src/Framework/TestCase · high confidence
Behavioural changes
Add version requirement exception classes with named-argument annotations
New exception classes, InvalidVersionRequirementException and NoVersionRequirementException, have been added to the PHPUnit Metadata namespace to handle specific version requirement errors. These classes, along with the base Exception interface, include the @no-named-arguments annotation to clarify that parameter names are not covered by the backward compatibility promise.
src/Metadata/Exception · medium confidence
Automated PHPUnit XML configuration migration system
PHPUnit now automatically detects and migrates legacy XML configuration files to the current schema. The new \Migrator\ and \MigrationBuilder\ classes in \src/TextUI/Configuration/Xml/Migration\ orchestrate a series of version-specific transformations (e.g., moving coverage elements, renaming attributes like \restrictDeprecations\ to \ignoreIndirectDeprecations\, removing obsolete options like \--no-interaction\ and \\<testdoxXml\>\) based on the detected source version. This ensures that older configuration files are seamlessly updated to work with the current PHPUnit release without manual intervention.
src/TextUI/Configuration/Xml/Migration · high confidence
Automated migration of legacy PHPUnit XML configuration formats
PHPUnit now automatically rewrites deprecated XML configuration files to the new schema when they are loaded. This covers several structural changes: coverage settings previously defined under \<coverage\> or \<whitelist\> are moved to the new \<source\> and \<coverage\> elements; old \<logging\> log types (such as 'junit', 'teamcity', 'plain', and coverage formats like 'clover', 'html', 'xml') are converted to the new \<report\> structure; and obsolete attributes (like 'cacheResultFile', 'cacheTokens', 'verbose', 'noInteraction', 'printerClass', and various 'convert...ToExceptions' flags) are removed. Additionally, the 'executionOrder' attribute is refined to correctly position 'defects' and move dependency resolution to a dedicated 'resolveDependencies' attribute, while elements like \<testdoxGroups\> and \<listeners\> are stripped out.
src/TextUI/Configuration/Xml/Migration/Migrations · high confidence
Configure PHP-Scoper prefix and namespace exclusions
The build configuration for PHP-Scoper has been updated to use 'PHPUnitPHAR' as the symbol prefix instead of 'PHPUnit', allowing internal symbols starting with 'PHPUnit' to be prefixed if needed in the future. Additionally, the 'PHPUnit' namespace is now explicitly excluded from prefixing, and constants matching the pattern '\_\PHPUNIT\\*' are exposed.
build/config · high confidence
Constraint classes migrated to modern PHP types and readonly properties
The constraint classes in src/Framework/Constraint (including Constraint, Callback, IsAnything, IsIdentical, and JsonMatches) now use modern PHP features: strict types, readonly properties, and explicit type declarations. This ensures stricter type safety and clearer intent in constraint evaluation. The Callback constraint now handles variadic callbacks correctly by checking isVariadic() and using spread operator when needed. IsIdentical now generates proper diff output for arrays and enums. JsonMatches now canonicalizes JSON before comparison for consistent results.
src/Framework/Constraint · high confidence
Exception constraint classes marked as internal and refactored with readonly properties
The exception constraint classes in src/Framework/Constraint/Exception (Exception, ExceptionCode, ExceptionMessageIs, ExceptionMessageIsOrContains, and ExceptionMessageMatchesRegularExpression) are now marked as internal and are no longer covered by the backward compatibility promise. Additionally, these classes have been refactored to use readonly properties and the mixed type for parameters, aligning with internal implementation standards.
src/Framework/Constraint/Exception · high confidence
Extracted PHP configuration validation into dedicated classes
The PHP configuration checking logic has been refactored from the command class into two new internal components: \PhpConfigurationChecker\ and \PhpConfigurationCheckResult\. The checker now explicitly validates specific PHP settings (such as \display\_errors\, \error\_reporting\, and \xdebug.show\_exception\_trace\) against expected values, returning structured results that indicate whether each setting is correctly configured. This change isolates the validation logic, making the configuration check process more modular and testable.
src/Runner/PhpConfiguration · high confidence
Global assertion functions are now namespaced under PHPUnit\\Framework
The \src/Framework/Assert/Functions.php\ file introduces a comprehensive set of global assertion functions (such as \assertArrayHasKey\, \assertIsList\, \assertJson\, etc.) that are now explicitly defined within the \PHPUnit\\Framework\ namespace. Previously, these functions were likely defined in the global namespace or handled differently; this change ensures they are namespaced, which prevents naming collisions with other libraries and aligns with modern PHP practices. Users can now call these assertions directly (e.g., \assertArrayHasKey(...)\) without importing the \Assert\ class, while the underlying implementation delegates to the \PHPUnit\\Framework\\Assert\ class methods.
src/Framework/Assert · high confidence
Granular control over test runner issue output and deprecation stack traces
The default text UI output now provides finer control over how test runner issues (deprecations, notices, warnings, and errors) are displayed. Users can configure whether to show details for issues triggered outside of tests (e.g., by code under test) versus those triggered within test code. Deprecations, notices, and warnings are now grouped by issue type rather than by test, and control characters in user-supplied strings are made visible. Additionally, when execution is stopped at a specific deprecation, a stack trace is printed to aid debugging.
src/TextUI/Output/Default · high confidence
Incomplete test exceptions marked as internal and excluded from backward compatibility
The IncompleteTest interface and IncompleteTestError class are now explicitly marked as internal and excluded from PHPUnit's backward compatibility promise. This means that parameter names and internal implementation details of these exception types may change in future versions without adhering to semantic versioning guarantees, allowing the framework to modify these components more freely.
src/Framework/Exception/Incomplete · high confidence
Internal property hook classes added to MockObject runtime
The MockObject runtime now includes internal \PropertyHook\, \PropertyGetHook\, and \PropertySetHook\ classes to manage property access hooks. These classes provide a structured way to represent and stringify property get/set operations within the mock object framework, supporting internal implementation details for property mocking.
src/Framework/MockObject/Runtime/PropertyHook · high confidence
Introduce TeamCity logger with comprehensive event-based output
The TeamCity logger has been rewritten to subscribe directly to the PHPUnit event system, replacing the previous implementation. This change enables detailed, structured logging for CI/CD integration, including accurate test suite and test method start/finish messages, location hints for IDE navigation, and specific handling for edge cases such as skipped tests, risky tests, and preparation failures. The new logger also ensures control characters in user-supplied strings are visible and prefixes non-assertion throwables with their class names for better debugging.
src/Logging/TeamCity · high confidence
Introduce dedicated Printer interface and implementations for test output
The TextUI output layer now uses a dedicated \Printer\ interface with two implementations: \DefaultPrinter\ handles writing to standard output, standard error, files, or network sockets (with proper error handling for socket connections), and \NullPrinter\ provides a no-op implementation for suppressing output. This refactoring extracts output logic from the test runner into a dedicated component, improving separation of concerns and allowing output behavior to be controlled independently of the test execution engine.
src/TextUI/Output/Printer · high confidence
Introduce dedicated TestResult data structures for TestDox logging
The TestDox logging subsystem now uses new, immutable value objects—TestResult, TestResultCollection, and TestResultCollectionIterator—to represent test outcomes. This change refactors how test results are collected and grouped by class, ensuring that tests are sorted by their source code location and that class groups are not collapsed when their prettified names match. It also ensures that skipped or incomplete tests are displayed in the TestDox output even if they never started, and that test methods are correctly ordered by line number within their declaring class.
src/Logging/TestDox/TestResult · high confidence
Introduce immutable value objects for TextUI configuration
The TextUI configuration layer now uses a set of new, immutable value objects in src/TextUI/Configuration/Value to represent configuration data. This includes dedicated classes for constants, directories, files, filter paths, groups, INI settings, PHP environment settings, and test sources, along with their respective collections and iterators. These objects replace previous representations, providing a stricter, type-safe structure for configuration values such as include/exclude paths, deprecation triggers, and variable scopes.
src/TextUI/Configuration/Value · high confidence
Introduces test file caching to skip loading files that cannot contribute to the current run
PHPUnit now maintains a persistent index of test files to determine whether a file needs to be loaded before the test suite is built. By recording which test methods, groups, and data sets each file contains, the runner can skip loading files that do not match the selected groups or name filters, significantly reducing startup time for large suites. The index is versioned and invalidated if the PHPUnit version, PHP version, or file contents change, ensuring correctness while avoiding unnecessary file I/O.
src/Runner/TestIndex · high confidence
Introduction of PHPUnit\\Exception marker interface
A new \PHPUnit\\Exception\ interface has been added to the public API, extending \Throwable\ to serve as a marker for PHPUnit exceptions. This interface includes a \@no-named-arguments\ annotation, indicating that parameter names are not covered by the backward compatibility promise, and is intended to standardize exception handling within the framework.
src · high confidence
Introduction of TestSize value objects for test size classification
PHPUnit now uses a dedicated set of immutable value objects in the \PHPUnit\\Framework\\TestSize\ namespace to represent test sizes. The new classes \Small\, \Medium\, \Large\, \Unknown\, and the abstract base \TestSize\ replace previous mechanisms, providing a structured way to identify and compare test sizes via methods like \isSmall()\, \isMedium()\, \isLarge()\, and \isGreaterThan()\. These classes are marked as internal and immutable, ensuring that test size information is handled consistently and safely within the framework.
src/Framework/TestSize · high confidence
Introduction of internal Command and Result interfaces for TextUI execution
The TextUI subsystem now exposes an internal \Command\ interface and a \Result\ class to structure command-line execution outcomes. The \Command\ interface defines the \execute()\ method for running commands, while the \Result\ class provides an immutable container for capturing execution output and shell exit codes (success, failure, exception, or crash). Both components are marked as internal and excluded from the backward compatibility promise, indicating they are implementation details for the test runner's text output handling rather than public APIs.
src/TextUI/Command · high confidence
Introduction of the new DispatchingEmitter event system
The test runner now utilizes a new \DispatchingEmitter\ implementation to manage event dispatching, replacing the previous mechanism. This change introduces a comprehensive set of new lifecycle and test-phase events (such as \TestRunner\\Started\, \Test\\AssertionMade\, and \Test\\PreparationFailed\) and refactors existing ones to provide richer telemetry data, including memory usage snapshots, CPU time, and detailed assertion outcomes. For users, this means more granular visibility into test execution phases and improved support for extensions and tooling that rely on the event system, while internal method signatures and event structures have been updated to support these capabilities.
src/Event/Emitter · high confidence
Isolated PHPT test runner with prefixed global variables
The PHPT test execution template now uses globally prefixed variable names (e.g., $\_\_phpunit\_composerAutoload) to prevent pollution of the user's global state. It also explicitly registers the current test job in the isolation exclusion list and bootstraps code coverage (including branch and path coverage settings) before requiring the test file, ensuring that test execution is isolated and coverage data is correctly captured.
src/Runner/Phpt/templates · high confidence
JUnit logging refactored into event subscribers
The JUnit XML logger implementation has been restructured to use an event-subscriber pattern. A new abstract Subscriber base class and a set of specific subscribers (e.g., TestAttemptErroredSubscriber, TestFailedSubscriber, TestRunnerExecutionFinishedSubscriber) now handle individual test lifecycle events. This change ensures that the JUnit XML log file is written and flushed automatically upon test execution completion, removing the need for explicit flush calls by users or other components.
src/Logging/JUnit/Subscriber · high confidence
Mock object generation refactored into dedicated domain classes
The mock object generator has been restructured to use dedicated classes for handling doubled classes, methods, and properties. This change introduces \DoubledClass\, \DoubledMethod\, \DoubledMethodSet\, \HookedProperty\, and \HookedPropertyGenerator\ to manage the generation of mock and stub code more modularly. The \Generator\ class now coordinates these components, and a \TemplateLoader\ trait is used to load code generation templates. This refactoring improves the maintainability and clarity of the mock generation logic, particularly for handling property hooks and method configurations.
src/Framework/MockObject/Generator · high confidence
MockObject exceptions are now internal, final classes implementing a dedicated interface
The exception classes in \src/Framework/MockObject/Exception\ have been refactored to be \final\ and to implement the new \PHPUnit\\Framework\\MockObject\\Exception\ interface (which extends \PHPUnit\\Exception\). All classes are marked with \@internal\ and \@no-named-arguments\, meaning they are no longer part of the backward compatibility promise and their parameter names are not guaranteed to remain stable. This change isolates mock-object-specific error handling from the general framework exception hierarchy.
src/Framework/MockObject/Exception · high confidence
Namespace migration and API deprecations in the Framework component
The \src/Framework\ directory has been migrated from the legacy \PHPUnit\Framework\\*\ naming convention to the modern \PHPUnit\\Framework\\\ namespace, affecting core classes such as \TestCase\, \Assert\, and \TestResult\. This change is accompanied by the deprecation of several legacy methods and assertions (including \getMock\, \createMockObject\, \assertArraySubset\, and \assertInternalType\) to encourage the use of updated alternatives like \createMock\ and specialized type assertions. Additionally, internal implementation details have been refined, such as the removal of the \Test\\SetupFinished\ event and the consolidation of test result handling, to streamline the testing experience and improve type safety.
src/Framework · high confidence
New Metadata API layer for test execution logic
PHPUnit introduces a new \src/Metadata/Api\ namespace containing dedicated API classes that handle the resolution of test metadata at runtime. \DataProvider\ now manages data provider execution and emits specific events, \CodeCoverage\ resolves \\#\[Covers\]\ and \\#\[Uses\]\ targets, \Groups\ handles group and size resolution including virtual groups for coverage options, \HookMethods\ manages lifecycle hooks with priority support, \Dependencies\ resolves \\#\[Depends\]\ order, and \Requirements\ validates environment and version constraints. This refactors the test execution engine to rely on a structured metadata API rather than legacy utility methods.
src/Metadata/Api · high confidence
New PHPT test runner implementation with isolated coverage and section parsing
PHPUnit now includes a new PHPT test runner located in src/Runner/Phpt that replaces the previous approach. This implementation introduces a dedicated Parser to strictly validate and extract PHPT sections (supporting standard sections like FILE, EXPECT, SKIPIF, and ignoring others), a Renderer to prepare test jobs with correct \_\DIR\\/\\FILE\\_ paths and coverage configuration, and a CodeCoverageBootstrapper to initialize branch and path coverage granularity. A key behavioral change is that temporary files for code coverage are now created in an isolated directory under the system temp folder (phpunit-phpt) rather than alongside the PHPT source files, preventing pollution of the test directory and respecting open\_basedir restrictions.
src/Runner/Phpt · high confidence
New PHPT-specific exception classes for detailed error reporting
The PHPT test runner now introduces a set of specific exception classes (e.g., CannotLoadPhptFileException, ConflictingPhptSectionsException, DuplicatePhptSectionException, InvalidPhptFileException, PhptExternalFileCannotBeLoadedException, UnknownPhptSectionException, UnsupportedPhptSectionException) to provide clearer, more descriptive error messages when PHPT files are malformed, contain invalid sections, or fail to load external dependencies.
src/Runner/Phpt/Exception · high confidence
New TestDox ResultPrinter with summary and error details
The TestDox output now includes a dedicated ResultPrinter that displays prettified class and method names, colorizes test status symbols, and prints detailed error information for failed or errored tests. When the summary option is enabled, it prints a dedicated section listing only tests with errors, failures, or issues, along with their associated throwables and stacktraces.
src/TextUI/Output/TestDox · high confidence
New array constraint classes for PHPUnit assertions
The \src/Framework/Constraint/Array\ directory now contains dedicated constraint classes (\ArrayComparison\, \ArrayHasKey\, \ArraysAreEqual\, \ArraysAreIdentical\, \IsList\) that implement the underlying logic for array-related assertions. \ArrayComparison\ provides a base for comparing arrays with configurable key and order sensitivity, while \ArraysAreEqual\ and \ArraysAreIdentical\ offer specific equality and identity checks. \ArrayHasKey\ validates the presence of specific keys in arrays or \ArrayAccess\ objects, and \IsList\ checks if an array is a sequential list using \array\_is\_list\. These changes refactor the internal constraint structure to support more precise and maintainable array assertion behavior.
src/Framework/Constraint/Array · high confidence
New attribute-based metadata parsing infrastructure
PHPUnit introduces a new internal metadata parsing system located in src/Metadata/Parser that replaces the previous annotation-based approach. This change adds the AttributeParser class to read PHPUnit attributes (such as \#\[Group\], \#\[Test\], \#\[DataProvider\], and \#\[DependsOnClass\]) from test code, a CachingParser to optimize performance by storing parsed results, and a Registry to manage the parser instance. This shift enables the use of native PHP attributes for configuring test behavior, providing a more modern and type-safe way to define test metadata compared to the legacy docblock annotations.
src/Metadata/Parser · high confidence
New configuration-specific exception classes
The TextUI configuration layer now includes a dedicated set of exception classes (e.g., BootstrapScriptDoesNotExistException, NoDefaultTestSuiteException, TimeoutNotConfiguredException) under PHPUnit\\TextUI\\Configuration\\Exception. These exceptions implement the new internal Exception interface and extend RuntimeException, providing specific error handling for configuration-related issues such as missing bootstrap scripts, unconfigured code coverage drivers, or missing test suite definitions.
src/TextUI/Configuration/Exception · high confidence
New deprecation collection event subscribers
The test runner now includes new subscriber classes within the \DeprecationCollector\ namespace that listen for specific test lifecycle events. \TestPreparedSubscriber\ triggers collection when a test is prepared, and \TestTriggeredDeprecationSubscriber\ captures deprecations as they occur during test execution, passing these events to the underlying collector instances.
src/Runner/DeprecationCollector/Subscriber · high confidence
New event-based test result collection and wall-clock time limit enforcement
The test runner now uses a new event-driven architecture in the \TestRunner/TestResult\ namespace to collect and report test outcomes, replacing the legacy \TestResult\ object. This change introduces new classes (\Collector\, \Facade\, \TestResult\, \Issue\, \PassedTests\) that aggregate events for errors, failures, deprecations, notices, and warnings, allowing for more granular reporting and grouping of issues. Additionally, a new \TimeLimit\ subsystem has been added to enforce a wall-clock time limit for the entire test run using \pcntl\_alarm\ when available, ensuring that hanging tests do not prevent the runner from exiting.
src/Runner/TestResult · high confidence
New exception classes for mock object generation errors
The mock object generator now throws specific, distinct exceptions for various failure scenarios, replacing generic errors with clearer diagnostics. New exception classes include ClassIsAnonymousException, ClassIsEnumerationException, and ClassIsFinalException to explicitly identify when a class cannot be doubled due to its nature; InvalidClassNameException and InvalidMethodNameException for validation errors; DuplicateMethodException to report duplicate entries in method lists; NameAlreadyInUseException for naming conflicts; and MethodNamedMethodException and MethodNamedRecordInvocationsInException to prevent doubling interfaces or classes with reserved method names. These changes improve error clarity for users attempting to create test doubles under invalid conditions.
src/Framework/MockObject/Generator/Exception · high confidence
New exception classes for object comparison method validation
The framework now introduces several new exception classes within the \ObjectEquals\ namespace to provide more specific error reporting when validating comparison methods. These include \ActualValueIsNotAnObjectException\, \ComparisonMethodDoesNotExistException\, \ComparisonMethodDoesNotDeclareBoolReturnTypeException\, \ComparisonMethodDoesNotDeclareExactlyOneParameterException\, \ComparisonMethodDoesNotDeclareParameterTypeException\, and \ComparisonMethodDoesNotAcceptParameterTypeException\. These exceptions are marked as internal and are not covered by the backward compatibility promise, meaning their signatures or existence may change in future versions without notice.
src/Framework/Exception/ObjectEquals · high confidence
New exception classes for the event system
The \src/Event/Exception\ directory now contains a dedicated set of exception classes (such as \EventAlreadyAssignedException\, \EventFacadeIsSealedException\, and \UnknownEventException\) that implement the new \PHPUnit\\Event\\Exception\ interface. These classes replace the previous reliance on generic \RuntimeException\ or \\\InvalidArgumentException\ for event-related errors, providing more specific error types for the event dispatcher and facade. All new exceptions are marked with \@no-named-arguments\ to clarify that parameter names are not part of the backward compatibility promise.
src/Event/Exception · high confidence
New immutable value objects for test event data
The src/Event/Value directory now introduces a set of immutable, readonly value objects (ChildProcessReason, ClassMethod, ComparisonFailure, Throwable) and their corresponding builders (ComparisonFailureBuilder, ThrowableBuilder) to represent structured data in test events. These classes replace previous ad-hoc structures, ensuring that event payloads such as comparison failures and exception details are strictly typed, immutable, and include support for nested exceptions and scalar-to-string mapping, thereby improving the reliability and clarity of event data consumed by subscribers.
src/Event/Value · high confidence
New internal exception classes for runner errors
The PHPUnit runner now introduces a set of new, internal exception classes in the \PHPUnit\\Runner\ namespace to handle specific runtime errors more precisely. These include \ClassCannotBeFoundException\, \ClassDoesNotExtendTestCaseException\, \ClassIsAbstractException\, \DirectoryDoesNotExistException\, \FileDoesNotExistException\, and \ParameterDoesNotExistException\ for descriptive error reporting, alongside \CodeCoverageDriverException\, \InvalidOrderException\, and \ErrorException\ for structural or system-level issues. All classes implement the new \PHPUnit\\Runner\\Exception\ interface and are marked as internal, meaning they are not covered by the backward compatibility promise and are intended for internal use only.
src/Runner/Exception · high confidence
New output facade and summary printer with granular issue control
The TextUI output layer has been refactored to introduce a central Output Facade that manages printer initialization and dispatch, replacing the previous scattered logic. This change brings several user-visible improvements: the summary output now explicitly counts and displays PHPUnit-specific deprecations and notices alongside standard PHP warnings and errors, and it reports the number of issues ignored by the baseline. Additionally, the compact output mode now respects configuration options to display details on specific issue types (incomplete, skipped, deprecations, errors, notices, warnings, PHPUnit deprecations/notices) and honors the new granular control flags for restricting or displaying these details. The summary printer also no longer treats skipped tests alone as a failure condition (yellow background) if there are no other issues, and it correctly counts skipped tests in the summary line.
src/TextUI/Output · high confidence
New subscribers for deprecations, notices, and warnings in the default progress printer
The default text UI progress printer now includes a comprehensive set of new subscriber classes that listen for and display deprecation, notice, and warning events (including PHP and PHPUnit-specific variants) alongside standard test lifecycle events. This ensures that these runtime signals are consistently printed to the console output during test execution.
src/TextUI/Output/Default/ProgressPrinter/Subscriber · high confidence
OpenTest Reporting XML schema updated to version 0.2.0 with extended test metadata
The OpenTest Reporting XML logging format has been upgraded to version 0.2.0, introducing a new schema structure that captures richer test execution details. The updated schema now includes source file and directory information for tests, allows attaching test descriptions and TestDox output, and records specific reasons for test failures or skips. Additionally, it supports reporting PHP environment specifics (version and thread model), Git repository context (branch, commit, status), and detailed resource usage metrics including CPU time. This enables more comprehensive debugging and analysis of test runs by providing deeper insight into the test environment and execution context.
src/Logging/OpenTestReporting/schema · high confidence
PHAR builds now use reproducible timestamps
The PHAR build process now sets file timestamps to a deterministic value to ensure reproducible builds. It prioritizes the SOURCE\_DATE\_EPOCH environment variable, falls back to the timestamp of the most recent git tag, and only uses the current time if neither is available. This change ensures that PHAR archives are identical across builds when the same source and environment are used, aiding in verification and caching.
build/scripts/phar-set-timestamps · high confidence
PHPUnit 13.4 release
This update introduces PHPUnit 13.4, bringing the framework to its new version identifier. The release includes a refactored test runner architecture with a new CodeCoverage singleton, a dedicated DeprecationFilter interface, and a new IssueFilter class to manage the processing of deprecations, errors, and notices. Test execution order is now handled by a TestSuiteSorter that applies a ReorderPipeline, supporting sorting by duration, size, and modification time. The TestSuiteLoader has been updated to map declared classes to their declaring files for more efficient loading, and the ShutdownHandler now ensures its output is only printed in the main process.
src/Runner · high confidence
Refactor TestDox subscribers into readonly classes with internal status
The TestDox result subscribers in src/Logging/TestDox/TestResult/Subscriber have been reorganized into a new abstract readonly base class and specific readonly implementations for each test event (e.g., errored, failed, skipped). These classes are marked @internal and use the @no-named-arguments annotation, indicating that parameter names are not covered by the backward compatibility promise. This change affects how test outcome details are collected and displayed in the TestDox format, specifically ensuring that skipped test classes are shown in the output.
src/Logging/TestDox/TestResult/Subscriber · high confidence
Refactor TextUI exceptions into internal, named-argument-free classes
The TextUI exception hierarchy has been reorganized: a new internal \Exception\ interface and a \RuntimeException\ base class were introduced, and specific exceptions (such as \CannotOpenSocketException\, \InvalidSocketException\, \TestDirectoryNotFoundException\, and \TestFileNotFoundException\) now implement this interface and extend the new base. All these classes are marked \@internal\ and carry the \@no-named-arguments\ annotation, meaning their parameter names are not covered by the backward compatibility promise and may change without notice.
src/TextUI/Exception · high confidence
Refactored CLI argument parsing into a new Builder and Configuration model
The CLI argument parsing logic in src/TextUI/Configuration/Cli has been restructured into a new Builder class and a readonly Configuration data model. This change introduces a dedicated XmlConfigurationFileFinder to handle configuration file discovery and replaces the previous monolithic parsing approach with a more modular, immutable configuration object that holds all parsed CLI options.
src/TextUI/Configuration/Cli · high confidence
Refactored MockObject runtime interfaces and added invocation recording
The MockObject runtime interfaces have been restructured to separate the API for test stubs from that for mock objects. New interfaces include InvocationJournal and InvocationJournalInternal, which allow recording the order in which methods of test doubles are invoked, and InvocationMocker, which adds parameter-matching rules like withParameterSetsInOrder, withParameterSetsInAnyOrder, and withParameterSetsInPartialOrder. The InvocationStubber interface now includes a seal() method, and the MockObject interface exposes recordInvocationsIn() for enabling invocation tracking. Internal interfaces (MockObjectInternal, StubInternal) expose additional state and verification methods, while the id() and after() methods on InvocationMocker are deprecated.
src/Framework/MockObject/Runtime/Interface · high confidence
Refactored PHP child-process execution with dedicated Job and JobRunner classes
The internal mechanism for spawning and managing PHP worker processes has been restructured. A new immutable \Job\ value object now encapsulates test execution parameters (code, settings, environment variables, arguments, and Xdebug requirements), replacing the previous ad-hoc parameter passing. The \JobRunner\ class manages the lifecycle of these jobs, introducing a separation between process spawning (\start\) and reaping (\wait\) via the \RunningJob\ handle, which enables non-blocking, multiplexed execution of multiple workers. Additionally, the \JobRunnerRegistry\ centralizes runner instantiation, and the system now emits specific events for child process completion and errors, improving observability and reliability during test runs.
src/Util/PHP · high confidence
Refactored PHPUnit exception hierarchy with serialization-safe base class
The PHPUnit exception framework has been restructured to improve memory management during process isolation. A new base \Exception\ class now sanitizes stack traces by stripping function arguments, preventing memory leaks caused by stray object references when test results are serialized between child and parent processes. This change introduces several new internal exception classes (such as \AssertionFailedError\, \EmptyStringException\, and \ErrorLogNotWritableException\) and marks the entire exception hierarchy as internal, meaning parameter names and class structures are no longer covered by the backward compatibility promise.
src/Framework/Exception · high confidence
Refactored Test Suite lifecycle events and added filtering support
The Test Suite event system has been restructured to provide more granular lifecycle notifications and improved type safety. A new \Filtered\ event and its corresponding subscriber have been introduced to notify listeners when a test suite is filtered. The existing lifecycle events (\Started\, \Finished\, \Sorted\, \Loaded\, \Skipped\) have been rewritten as immutable, readonly value objects that carry a \Telemetry/info\ payload. The \Finished\ and \Started\ events now include specific logic to distinguish between standard test runs, data provider iterations, repeated executions, and PHPT retries, resulting in more precise status messages. Additionally, the \Sorted\ event now exposes the execution pipeline stages applied to the test suite, replacing the previous ambiguous ordering configuration.
src/Event/Events/TestSuite · high confidence
Refactored TextUI into a modular, event-driven architecture
The TextUI component has been restructured from a monolithic runner into a modular, event-driven system. The main entry point is now the \Application\ class, which orchestrates configuration loading, extension bootstrapping, and command execution. The legacy \TestRunner\ has been replaced by a new \TestRunner\ class that focuses solely on test execution and ordering, while a new \ShellExitCodeCalculator\ handles exit codes based on the test result and configuration. Additionally, a dedicated \TestSuiteFilterProcessor\ manages test selection logic, and a new \Help\ class generates formatted CLI help output.
src/TextUI · high confidence
Refactored XML schema detection into a dedicated, immutable class hierarchy
The XML configuration schema detection logic has been reorganized into a new \SchemaDetector\ class and a set of dedicated result classes (\SchemaDetectionResult\, \SuccessfulSchemaDetectionResult\, \FailedSchemaDetectionResult\). These classes are marked as \@internal\ and \readonly\ (immutable), meaning they are not covered by PHPUnit's backward compatibility promise. This change isolates the schema validation workflow, making the detection mechanism more explicit and robust, though it may affect internal consumers relying on the previous implementation structure.
src/TextUI/Configuration/Xml/SchemaDetector · high confidence
Refactored XML utilities into dedicated Loader and Xml classes
The XML handling logic in src/Util/Xml has been reorganized into two new internal classes: Loader and Xml. The Loader class now centralizes XML file and string loading, explicitly passing the LIBXML\_NONET flag to ensure no network I/O occurs during parsing and validating, and includes improved error handling for empty files and load failures. The Xml class provides a static prepareString method that safely escapes strings for XML documents by converting them to UTF-8 and removing invalid characters. These changes improve code maintainability and security by isolating XML parsing concerns and preventing external entity resolution.
src/Util/Xml · high confidence
Refactored cardinality constraints with readonly properties and dedicated negation methods
The cardinality constraint classes (Count, GreaterThan, IsEmpty, LessThan, SameSize) have been rewritten to use readonly properties and dedicated negatedToString/negatedFailureDescription methods for generating inverse assertion messages, replacing previous string-rewriting approaches. This change also introduces support for the mixed type in method signatures and improves handling of Traversable objects by preventing infinite recursion in Count::getCountOf() via SebastianBergmann\\RecursionContext, while explicitly throwing GeneratorNotSupportedException for generators.
src/Framework/Constraint/Cardinality · high confidence
Refactored equality constraints to use dedicated negation methods
The equality constraint classes (IsEqual, IsEqualCanonicalizing, IsEqualIgnoringCase, IsEqualWithDelta) now implement a dedicated negatedToString() method to generate failure messages for inverse assertions. This change ensures that negated messages are authored as proper negations rather than by rewriting strings, keeping the exported value out of the negation entirely for clearer output. The implementation also adopts readonly properties and uses modern string functions like str\_contains.
src/Framework/Constraint/Equality · high confidence
Refactored event dispatcher architecture with new dispatcher implementations
The event dispatching system in src/Event/Dispatcher has been restructured to introduce three new concrete dispatcher classes: CollectingDispatcher, which buffers events and registers a deprecation collector subscriber; DeferringDispatcher, which supports start/stop event collection and defers dispatching until flush is called; and DirectDispatcher, which handles immediate dispatching to subscribers and tracers while reporting exceptions from third-party subscribers as test runner warnings instead of swallowing them. These changes are accompanied by the introduction of Dispatcher and SubscribableDispatcher interfaces to define the contract for event dispatching and subscriber registration.
src/Event/Dispatcher · high confidence
Refactored isolated test execution to use a new method template with improved isolation and security
The test runner's process isolation mechanism has been updated to use a new \method.tpl\ template for executing individual tests in child processes. This change introduces several improvements: global variables in the generated code are now prefixed with \\_\phpunit\\ to prevent polluting the user's global state, and child process result files are verified using a random nonce to ensure integrity. Additionally, the template ensures that the event emitter is injected directly into the \PhpHandler\ rather than retrieved from a static facade, and source maps are shared with child processes to support better debugging. The template also handles output buffering carefully to avoid breaking the unserialization of results by writing to \php://temp\ instead of relying on standard output.
src/Framework/TestRunner/templates · high confidence
Refactored mock object builder into dedicated TestDoubleBuilder hierarchy
The mock object creation API has been restructured to use a new \TestDoubleBuilder\ abstract base class, with specialized \MockBuilder\ and \TestStubBuilder\ subclasses. This change introduces distinct fluent interfaces for creating mocks (which verify expectations) and stubs (which provide return values), allowing users to explicitly choose the test double type. The refactoring also adds new methods such as \onlyMethods()\ for specifying methods to mock, \doubleProperties()\ for mocking public non-static properties, and \setConstructorArgs()\ for passing constructor arguments, while maintaining backward compatibility through the existing builder pattern.
src/Framework/MockObject · high confidence
Refactored mock object generation templates for improved variable handling and structure
The mock object generator templates have been reorganized and renamed to improve code clarity and fix specific behavioral issues. The new \doubled\method.tpl\ template ensures that local variables in generated test doubles are prefixed with \\\phpunit\\ to prevent naming collisions, and correctly handles variadic associative elements by registering them properly. A new \deprecation.tpl\ template allows for the generation of deprecation triggers, while \doubled\_static\_method.tpl\ now explicitly throws a \BadMethodCallException\ for static methods on mocks. Additionally, \intersection.tpl\ and \test\_double\_class.tpl\ provide updated structures for interface intersections and class declarations respectively.
src/Framework/MockObject/Generator/templates · high confidence
Refactored mock object internal API into dedicated traits and state management
The internal implementation of mock objects and stubs has been reorganized to separate concerns more clearly. New internal traits (DoubledCloneMethod, ProxiedCloneMethod, Method, MockObjectApi, StubApi) and a dedicated TestDoubleState class now manage the lifecycle, cloning behavior, invocation handling, and configuration of test doubles. This change isolates the API for mock objects from that of test stubs and introduces a centralized state object to handle invocation handlers and configuration, improving the internal structure without altering the public testing interface.
src/Framework/MockObject/Runtime/Api · high confidence
Refactored mock object invocation and parameter-matching rules
The mock object rule system in src/Framework/MockObject/Runtime/Rule has been restructured to improve invocation counting and parameter matching. New classes (AnyInvokedCount, InvokedAtLeastCount, InvokedAtMostCount, InvokedCount) now handle invocation count expectations, while OrderedParameterSets, UnorderedParameterSets, and PartiallyOrderedParameterSets provide granular control over how method arguments are matched against configured sets. This change also introduces the ParametersRule interface and dedicated classes (AnyParameters, IndexedParameters, Parameters) to standardize parameter validation, resulting in clearer failure messages and more flexible mock expectations.
src/Framework/MockObject/Runtime/Rule · high confidence
Refactored progress printer to use event facade and support deprecation filtering
The default progress printer has been refactored to subscribe to the new event facade instead of direct test runner hooks, allowing it to react to specific test lifecycle events like deprecations, notices, and warnings. This change introduces support for filtering these events based on configuration options such as ignoring self, direct, or indirect deprecations, and respecting suppression flags, which affects how test progress and status indicators are displayed in the console output.
src/TextUI/Output/Default/ProgressPrinter · high confidence
Refactored test execution engine with improved process isolation and security
The test runner has been restructured into dedicated components to enhance reliability and security. Process isolation now uses a random nonce to verify child process results, preventing tampering, and shares a source map to improve code coverage accuracy. The runner also introduces a configurable wall-clock timeout for entire test runs, better handling of unexpected child process exits, and stricter validation of code coverage targets to ensure only first-party code is analyzed.
src/Framework/TestRunner · high confidence
Refactored test filtering with compiled parsers and new filter iterators
The test filtering logic in src/Runner/Filter has been restructured to improve performance and maintainability. The parsing of the --filter and --group/--exclude-group CLI options is now centralized in new compiled classes (CompiledNameFilter and CompiledGroupFilter), which handle syntax like data-set ranges (\#4-8) and group conjunctions (foo+bar) before the iterators run. The filtering itself is now driven by a new Factory class that wires together a set of dedicated iterator classes (TestIdFilterIterator, GroupFilterIterator, NameFilterIterator, and their Include/Exclude variants). This change also introduces the ability to filter tests by their unique ID via the new TestIdFilterIterator.
src/Runner/Filter · high confidence
Refactored test runner configuration into a new immutable value object and builder
The test runner's configuration handling has been restructured around a new, immutable \Configuration\ value object in \src/TextUI/Configuration\. This change introduces a dedicated \Builder\ to orchestrate the merging of CLI arguments and XML configuration, and a \Merger\ to combine them into the final state. The previous static access patterns have been replaced with explicit dependency injection, including the event emitter, into components like \BootstrapLoader\, \PhpHandler\, and \ExecutionOrderParser\. This refactoring also adds support for new configuration capabilities such as per-test-suite bootstrapping, granular source filtering via \SourceMapper\, and the ability to save and load the configuration state for use in separate processes.
src/TextUI/Configuration · high confidence
Refactored test suite event value objects into immutable, readonly classes
The test suite event value objects in \src/Event/Value/TestSuite\ have been refactored into a hierarchy of immutable, readonly classes (e.g., \TestSuite\, \TestSuiteForTestClass\, \TestSuiteForTestMethodWithDataProvider\). This change introduces specific subclasses for different test suite types (such as repeated or retried PHPT and method tests) and adds a \TestSuiteBuilder\ to convert framework test suites into these event value objects. The refactoring ensures these internal value objects are immutable and includes type-safe discriminators (like \isForTestClass()\) to distinguish between suite types, while explicitly noting that parameter names are not covered by the backward compatibility promise.
src/Event/Value/TestSuite · high confidence
Refactored traversable constraint classes with modern PHP types
The traversable constraint classes (TraversableContains, TraversableContainsEqual, TraversableContainsIdentical, and TraversableContainsOnly) have been rewritten to use modern PHP features, including readonly properties, mixed type declarations, and strict typing. This refactoring improves code clarity and maintainability while preserving the existing assertion behavior for checking if traversables contain specific values or types.
src/Framework/Constraint/Traversable · high confidence
Refactored type constraints to use readonly properties and explicit negation methods
The type constraint classes in src/Framework/Constraint/Type (IsInstanceOf, IsNull, IsType) have been rewritten to use readonly properties and strict typing. A key behavioral change is that failure messages for inverse assertions are now generated by authoring explicit negations (e.g., 'is not an instance of', 'is not null') via dedicated negatedToString() and negatedFailureDescription() methods, rather than rewriting positive strings. Additionally, IsType now explicitly supports 'resource (closed)' as a distinct type check.
src/Framework/Constraint/Type · high confidence
Refactored utility classes to readonly value objects with strict typing
The \src/Util\ directory has been rewritten to use modern PHP practices: classes are now \final readonly\ value objects with strict type declarations. This includes new implementations for \Color\ (ANSI formatting), \DifferBuilder\ (diff configuration), \ExcludeList\ (dependency exclusion), \Exporter\ (object serialization), \Filesystem\ (path handling), \Filter\ (stacktrace filtering), \GlobalState\ (environment snapshotting), \Json\ (canonicalization), \Reflection\ (method discovery), \Sanitizer\ (control character escaping), \Test\ (test detection), and \ThrowableToStringMapper\. Exception classes in \src/Util/Exception\ are also refactored as readonly value objects. These changes improve performance, type safety, and immutability in PHPUnit's internal utility layer.
src/Util · high confidence
Reimplemented test execution order into a configurable pipeline of stages
The test execution order logic in the runner has been refactored from a monolithic sorter into a modular pipeline of distinct stages (Context, ReorderPipeline, and individual Stage implementations). This change introduces new sorting capabilities, including ordering tests by the modification time of their source files (ascending or descending) and by test duration (ascending or descending), in addition to existing options like size, randomization, and reversing. The pipeline also supports a 'defects first' overlay that hoists previously failing tests to the front based on a configurable weight policy, and ensures dependency resolution is always applied as the final stage to maintain execution integrity.
src/Runner/ExecutionOrder · high confidence
Reorganized constraint operators into a dedicated namespace
The logical constraint operators (And, Or, Xor, Not) and their base classes have been moved from the root PHPUnit\\Framework\\Constraint namespace into a new PHPUnit\\Framework\\Constraint\\Operator namespace. This structural change improves code organization and modularity without altering the public API or the behavior of existing constraint assertions.
src/Framework/Constraint/Operator · high confidence
Support for prioritized test hook methods
The test runner now supports assigning priorities to hook methods (such as setUp, tearDown, etc.), allowing users to control the execution order when multiple hooks are defined. This is implemented via new internal classes that manage a collection of hooks, sorting them by priority before execution.
src/Runner/HookMethod · medium confidence
TeamCity logging now uses event subscribers
The TeamCity logger has been refactored to use a subscriber pattern, introducing a set of new classes in \src/Logging/TeamCity/Subscriber\ that listen to specific PHPUnit test events (such as test started, finished, failed, or skipped) and forward them to the logger. This change replaces the previous explicit method calls with an event-driven architecture, ensuring that logging output is synchronized with the test execution lifecycle without requiring manual flush calls from the core runner.
src/Logging/TeamCity/Subscriber · high confidence
Test status values are now represented by immutable objects instead of integers
The integer constants previously used to represent test outcomes (such as success, failure, error, skipped, etc.) have been replaced by a hierarchy of immutable, readonly value objects in the \PHPUnit\\Framework\\TestStatus\ namespace. Each status is now a distinct class (e.g., \Success\, \Failure\, \Error\, \Warning\, \Deprecation\) that implements \isMoreImportantThan()\ to define precedence based on integer values. This change affects how test statuses are created and compared internally, moving away from raw integer comparisons to object-oriented status checks, while maintaining backward compatibility for integer-based lookups via \TestStatus::from()\.
src/Framework/TestStatus · high confidence
Test coverage
Add internal test extension for validating PHPUnit 13.0 extension APIs; Added PHPT test files for invalid and unsupported sections; Added PHPUnit configuration and test fixtures for Phar end-to-end tests; Added PHPUnit test suite for test result status reporting; Added TestDox expectation fixtures for HTML and plain-text reports; Added TestDox test fixtures for data providers, metadata, and formatters; Added basic PHPUnit test fixture and configuration; Added end-to-end test fixture for TeamCity warning scenarios; Added end-to-end test fixture for baseline generation; Added end-to-end test fixture for text log event export; Added end-to-end test fixtures for PHP test scenarios; Added end-to-end test fixtures for PHPUnit extension CLI and XML configurations; Added end-to-end test fixtures for PHPUnit extension bootstrapping; Added end-to-end test fixtures for data-provider edge cases; Added end-to-end test fixtures for error handling and deprecation management; Added end-to-end test fixtures for stop-on-fail-on behavior; Added end-to-end test fixtures for test execution ordering strategies; Added end-to-end test for --exclude-filter CLI option; Added end-to-end test for baseline with all issue types; Added end-to-end test for exception hook transformation; Added end-to-end test for invalid coverage metadata; Added end-to-end tests for CLI column width and help output; Added end-to-end tests for CLI conflicting option pairs; Added end-to-end tests for CLI diff-context output; Added end-to-end tests for CLI filter behavior; Added end-to-end tests for CLI filter error handler event display; Added end-to-end tests for CLI group filtering and conjunctions; Added end-to-end tests for CLI list-suites and configuration-based test selection; Added end-to-end tests for CLI stop-on flags; Added end-to-end tests for CLI test ID filtering; Added end-to-end tests for JUnit XML logging; Added end-to-end tests for PHP configuration checking; Added end-to-end tests for PHPUnit XML configuration migration; Added end-to-end tests for RequiresEnvironmentVariable attribute; Added end-to-end tests for TestCase::registerObjectExporter(); Added end-to-end tests for TestDox output formatting and edge cases; Added end-to-end tests for abstract test class handling; Added end-to-end tests for baseline functionality; Added end-to-end tests for baseline suppression handling; Added end-to-end tests for coverage driver and xdebug mode validation; Added end-to-end tests for coverage driver validation; Added end-to-end tests for fail-on CLI options and deprecation triggers; Added end-to-end tests for fail-on-all-issues precedence; Added end-to-end tests for filtering tests by group from configuration; Added end-to-end tests for generic test runner behaviors; Added end-to-end tests for mock object generation and partial function application; Added end-to-end tests for risky code coverage metadata; Added end-to-end tests for size-based coverage metadata requirements; Added end-to-end tests for test run history management; Added end-to-end tests for test suite execution ordering; Added end-to-end tests for the \#\[Repeat\] attribute and test repetition logic; Added end-to-end tests for the --timeout CLI option; Added end-to-end tests for the PHPUnit event system; Added end-to-end tests for the WithEnvironmentVariable attribute; Added end-to-end tests for the cached test index feature; Added end-to-end tests for the compact output mode; Added end-to-end tests for the test retry mechanism; Added placeholder for regression test 5822; Added regression tests for PHPUnit 12.0 development; Added self-test to validate end-to-end test suite configuration; Added test fixture classes for namespaced class resolution; Added test fixture for HTML escaping in TestDox reports; Added test fixture for baseline generation with relative paths; Added test fixture for baseline in a separate directory; Added test fixture for external directory file handling; Added test fixture for force-covers-annotation; Added test fixture for group-based test filtering; Added test fixture for overlapping test suite configuration; Added test fixture for verifying no-log and no-CC override behavior; Added test fixture for verifying warnings on \#\[Test\] attributes in hook methods; Added test fixtures and unit tests for source mapping, test suite selection, and test dox output; Added test fixtures for BeforeClass skip behavior; Added test fixtures for DataProviderIssue2833; Added test fixtures for OneClassPerFile validation scenarios; Added test fixtures for PHAR loader and error handler scope resolution; Added test fixtures for PHPUnit metadata attributes; Added test fixtures for abstract test classes with and without test suffix; Added test fixtures for annotation-based filtering and migration detection; Added test fixtures for child-process extension scenarios; Added test fixtures for class and method level size groups; Added test fixtures for class inheritance scenarios; Added test fixtures for code coverage parse error handling; Added test fixtures for code-coverage and time-limit scenarios; Added test fixtures for coverage metadata attributes; Added test fixtures for custom code-coverage drivers; Added test fixtures for dependency resolver size attributes and providers; Added test fixtures for deprecation filter validation; Added test fixtures for enum equality; Added test fixtures for error-handler deprecation scenarios; Added test fixtures for extension bootstrap and execution finished subscriber; Added test fixtures for extension output replacement capabilities; Added test fixtures for extension subscriber and tracer registration; Added test fixtures for group attributes on parent classes; Added test fixtures for inherited TestDox behavior; Added test fixtures for lifecycle method errors and test status reporting; Added test fixtures for logging end-to-end verification; Added test fixtures for metadata attribute parsing; Added test fixtures for multiple PHPUnit test suite configurations; Added test fixtures for multiple size attribute combinations; Added test fixtures for object comparison scenarios; Added test fixtures for object equality edge cases; Added test fixtures for risky dependency on larger test; Added test fixtures for same-class-name resolution; Added test fixtures for source-filter prefix/suffix matching; Added test fixtures for undefined variable issues; Added test for empty source filter warning; Added tests for IssueTriggerResolver resolution logic; Added tests for PHPUnit test suite bootstrapping; Added tests for code coverage targeting warnings; Added tests for disabling the error handler; Added tests for failOnDeprecation precedence with trigger-specific overrides; Added tests for issue trigger classification logic; Added tests for new PHPUnit event issue classes; Added tests for new Test/HookMethod event classes; Added tests for the test execution reorder pipeline; Added unit tests for CLI configuration parsing and XML file discovery; Added unit tests for EventLogger; Added unit tests for Exception serialization; Added unit tests for HookMethodCollection; Added unit tests for MockObject invocation rules; Added unit tests for MockObject runtime internals; Added unit tests for MockObject, Stub, and ReturnValueGenerator; Added unit tests for ObjectEquals and ObjectHasProperty constraints; Added unit tests for PHP child-process job execution components; Added unit tests for PHPUnit TestCase internal components; Added unit tests for PHPUnit Util classes; Added unit tests for PHPUnit assertion methods; Added unit tests for PHPUnit extension runner components; Added unit tests for PHPUnit framework core components; Added unit tests for PHPUnit metadata collection and metadata objects; Added unit tests for PhpConfigurationChecker and PhpConfigurationCheckResult; Added unit tests for ReturnValueMap stub behavior; Added unit tests for Test Issue event value objects; Added unit tests for TestData and TestDataCollection value objects; Added unit tests for TestDouble event creation; Added unit tests for TestDox rendering and name prettification; Added unit tests for TestDox result collection and subscriber logic; Added unit tests for TestRunner event classes; Added unit tests for TestSuite lifecycle events; Added unit tests for TestSuite value objects and builder; Added unit tests for TextUI command implementations; Added unit tests for TextUI configuration and execution order parsing; Added unit tests for TextUI configuration and output components; Added unit tests for default TextUI output printers; Added unit tests for deprecation collector components; Added unit tests for equality constraint variants; Added unit tests for event value objects and issue trigger classification; Added unit tests for hook method event classes; Added unit tests for logical constraint operators; Added unit tests for mock object creation and configuration; Added unit tests for new Test event classes; Added unit tests for runtime event value objects; Added unit tests for string and cardinality constraints; Added unit tests for telemetry value objects and system components; Added unit tests for test runner filter components; Added unit tests for the DispatchingEmitter; Added unit tests for the Test Run History feature; Added unit tests for the TestRunner framework components; Added unit tests for the XML Loader utility; Added unit tests for the compact output printer components; Added unit tests for the event system infrastructure; Added unit tests for the issue-baseline feature components; Added unit tests for the metadata attribute parser; Added unit tests for the test index and file skipper components; Added unit tests for the test result collector and related components; Added unit tests for type constraints; Added unit tests for version metadata requirements; Documentation and bootstrap updates for the test suite; End-to-end tests for Open Test Reporting (OTR) XML logging; End-to-end tests for PHPT runner validation and features; End-to-end tests for XML-configured PHPUnit extensions; End-to-end tests for code coverage driver configuration and edge cases; End-to-end tests for data provider validation and key handling; End-to-end tests for error-handler deprecation filtering and classification; End-to-end tests for listing tests and groups with filters; End-to-end tests for test metadata and configuration attributes; Expanded end-to-end CLI test coverage; Expanded end-to-end test fixtures for PHPUnit event system; Expanded end-to-end test fixtures for PHPUnit runner features; Expanded test fixtures for PHPUnit internals; Expanded test fixtures for mock-object scenarios; New event types and subscribers for test doubles; New test lifecycle event classes and subscriber interfaces; New test outcome event classes and subscribers.
Dependencies
PHPUnit 13.4 development dependencies and build tooling updated
The project has initialized the composer manifests and lock files for PHPUnit 13.4 (dev-main), establishing a PHP 8.4.1 minimum requirement and updating core dependencies such as phpunit/php-code-coverage to ^14.4, sebastian/diff to ^9.0.1, and sebastian/exporter to ^8.2.1. The main composer.json now includes a security audit policy that fails on security advisories and abandoned packages. Additionally, the PHPStan static analysis tooling in tools/.phpstan has been updated to use phpstan/phpstan ^2.2.16 along with its associated strict rules and extension installer.
(dependencies) · high confidence
Updated PHPStan static analysis tooling to version 2.2.16
The PHPStan static analysis tool installed in the \tools/.phpstan\ directory has been updated to version 2.2.16, along with its associated extensions \phpstan-strict-rules\ (2.0.12) and \ergebnis/phpstan-rules\ (2.14.0). This upgrade brings the latest rule sets and bug fixes to the project's local development environment, ensuring that static analysis checks run against the most recent version of the tooling.
tools · high confidence
Updated seld/phar-utils dependency to version 1.2.2
The build script located at build/scripts/phar-set-timestamps now uses seld/phar-utils version 1.2.2. This update ensures that the PHAR build process remains reproducible by correctly handling file timestamps within the archive, addressing the final source of non-determinism in the build output.
build/scripts/phar-set-timestamps/vendor · high confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
Score
- CAI 53 → 73 (+20.2)
- Rubric changed (rubric-2026.08.15 → rubric-2026.09.15) — scores are not directly comparable.
Lenses
- Code Health 85 → 83 (-1.3)
- Architecture 94 → 86 (-8.1)
- Maturity 59 → 65 (+6.1)
- Readiness 32 → 75 (+42.6)
- Security 79 → 88 (+9.1)
Resolved (30)
- Coverage not measured — test suite did not build
- Dimension evaluation failed
- Duplicated block (11 lines × 2) (src/Runner/CodeCoverage.php)
- Duplicated block (11 lines × 2) (src/TextUI/Configuration/Xml/Loader.php)
- Duplicated block (13 lines × 2) (src/Framework/TestRunner/ChildProcessResultProcessor.php)
- Duplicated block (13 lines × 2) (src/Logging/TestDox/NamePrettifier.php)
- Duplicated block (13 lines × 2) (src/TextUI/Configuration/Cli/Builder.php)
- Duplicated block (13 lines × 2) (src/TextUI/Configuration/Xml/Loader.php)
- Duplicated block (14 lines × 2) (src/TextUI/Configuration/Cli/Builder.php)
- Duplicated block (15 lines × 2) (src/TextUI/Configuration/Merger.php)
- Duplicated block (16 lines × 2) (src/TextUI/Configuration/Cli/Builder.php)
- Duplicated block (17 lines × 2) (src/TextUI/Configuration/Cli/Builder.php)
- Duplicated block (18 lines × 2) (src/Metadata/Api/DataProvider.php)
- Duplicated block (20 lines × 2) (src/TextUI/Configuration/Cli/Builder.php)
- Duplicated block (21 lines × 7) (src/TextUI/Configuration/Cli/Builder.php)
- Duplicated block (31 lines × 3) (src/TextUI/Configuration/Merger.php)
- Duplicated block (31 lines × 4) (src/TextUI/Configuration/Cli/Builder.php)
- Duplicated block (6 lines × 2) (src/TextUI/Configuration/Xml/Loader.php)
- Duplicated block (6 lines × 2) (src/TextUI/Output/Facade.php)
- Duplicated block (7 lines × 2) (src/Event/Value/TestSuite/TestSuiteBuilder.php)
- …and 10 more
New (636)
- Application.configureDeprecationTriggers (cognitive 17) (src/TextUI/Application.php)
- Application.executeCommandsThatOnlyRequireCliConfiguration (cognitive 16) (src/TextUI/Application.php)
- Application.registerLogfileWriters (cognitive 17) (src/TextUI/Application.php)
- Application.run (cognitive 38) (src/TextUI/Application.php)
- Application.run (cyclomatic 34) (src/TextUI/Application.php)
- Application.testRunHistoryMayBePruned (cyclomatic 16) (src/TextUI/Application.php)
- AttributeParser.deprecateGroupAttributesOnParentClassesOf (cognitive 21) (src/Metadata/Parser/AttributeParser.php)
- AttributeParser.forClass (cognitive 37) (src/Metadata/Parser/AttributeParser.php)
- AttributeParser.forClass (cyclomatic 65) (src/Metadata/Parser/AttributeParser.php)
- AttributeParser.forMethod (cognitive 31) (src/Metadata/Parser/AttributeParser.php)
- AttributeParser.forMethod (cyclomatic 65) (src/Metadata/Parser/AttributeParser.php)
- Boundary-crossing change coupling: PlainTextRenderer.php ↔ ResultPrinter.php (src/Logging/TestDox/PlainTextRenderer.php)
- Builder.fromParameters (cognitive 87) (src/TextUI/Configuration/Cli/Builder.php)
- Builder.fromParameters (cyclomatic 197) (src/TextUI/Configuration/Cli/Builder.php)
- Change coupling: HtmlRenderer.php ↔ PlainTextRenderer.php (src/Logging/TestDox/HtmlRenderer.php)
- Change coupling: PlainTextRenderer.php ↔ TestResultCollector.php (src/Logging/TestDox/PlainTextRenderer.php)
- ClassTooLong: Assert (src/Framework/Assert.php)
- ClassTooLong: AttributeParser (src/Metadata/Parser/AttributeParser.php)
- ClassTooLong: Builder (src/TextUI/Configuration/Cli/Builder.php)
- ClassTooLong: DispatchingEmitter (src/Event/Emitter/DispatchingEmitter.php)
- …and 616 more
Changes since last survey
- 300 commits — 294 feature/other, 6 fixes
By area
- (repo) — 68 commits
- (root) — 41 commits
- .github/workflows — 41 commits
- tests/end-to-end — 33 commits
- src/Framework — 29 commits
- tools/.phpstan — 23 commits
- src/TextUI — 21 commits
- src/Runner — 19 commits
- tests/unit — 17 commits
- tests/_files — 4 commits
- .phive/phars.xml — 2 commits
- src/Event — 1 commit
- src/Logging — 1 commit
Notable commits
- fix: Backport fix from 13.3
- fix: Backport the fix for bug #6904
- fix: Fix CS/WS issues
- fix: Fix documentation
- fix: Revert "Add --restrict-file-output to refuse writing files outside a directory"
- fix: Revert "Do not report deprecations triggered by myclabs/deep-copy"
- change: Add --restrict-file-output to refuse writing files outside a directory
- change: Add --timeout to limit the wall-clock time of the entire test run
- change: Add event emitter parameter to the factory methods of TestSuite instead of retrieving it from the event facade
- change: Add missing annotation
- change: Add option for caching which tests a test file contains
- change: Add tests
- change: Add tests
- change: Allow ordering tests by the time their source files were last modified
- change: Closes #6904
- change: Closes #6924
- change: Closes #6965
- change: Closes #6995
- change: Closes #6999
- change: Consult the test index when test files are named on the command line
- …and 280 more
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
sebastianbergmann/phpunit was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 26 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit 42bedd96c8b95755c360757a7f41ee16dd0f5dfa — the exact code this score is about.
- Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-a15879f6f801.