Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Dec 1, 2025

Adds support for enabling Xdebug step debugging when running Behat tests, allowing developers to debug the actual WP-CLI + WordPress code executed during tests.

Changes:

  • Add running_with_xdebug() method in FeatureContext.php (mirrors existing running_with_code_coverage() pattern)
  • Set Xdebug environment variables (XDEBUG_MODE, XDEBUG_SESSION, XDEBUG_CONFIG) for spawned WP-CLI processes when enabled
  • Document usage in README.md

Usage:

WP_CLI_TEST_XDEBUG=true composer behat

Closes #257

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/0ca86845ce43291e8f5692c7356fccf3bcf02bf4
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/n1bEHN /usr/bin/composer install (http block)
  • https://api.github.com/repos/PHPCSStandards/composer-installer/zipball/845eb62303d2ca9b289ef216356568ccc075ffd1
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/n1bEHN /usr/bin/composer install (http block)
  • https://api.github.com/repos/phpstan/extension-installer/zipball/85e90b3942d06b2326fba0403ec24fe912372936
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/SUkeBE /usr/bin/composer install (http block)
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/n1bEHN /usr/bin/composer install (http block)
  • https://api.github.com/repos/phpstan/phpstan/zipball/2770dcdf5078d0b0d53f94317e06affe88419aa8
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/n1bEHN /usr/bin/composer install (http block)
  • https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/n1bEHN /usr/bin/composer install (http block)
  • https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/n1bEHN /usr/bin/composer install (http block)
  • https://api.github.com/repos/symfony/translation-contracts/zipball/65a8bc82080447fae78373aa10f8d13b38338977
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/SUkeBE /usr/bin/composer install (http block)
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/n1bEHN /usr/bin/composer install (http block)
  • https://api.github.com/repos/symfony/yaml/zipball/6c84a4b55aee4cd02034d1c528e83f69ddf63810
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/SUkeBE /usr/bin/composer install (http block)
    • Triggering command: /usr/bin/php8.3 /usr/bin/php8.3 -n -c /tmp/n1bEHN /usr/bin/composer install (http block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

This section details on the original issue you should resolve

<issue_title>Enable Xdebug in Behat tests</issue_title>
<issue_description>## Feature Request

Describe your use case and the problem you are facing

When working with the Behat tests, I'd like to be able to step debug the actual WP CLI + WordPress code which is being run.

Describe the solution you'd like

Add a WP CLI environmental variable to enable Xdebug, which would prepend any WP CLI commands run by Behat with Xdebug environmental variables to enable it.

WP_CLI_TEST_XDEBUG=true composer behat

In wp-cli/wp-cli/php/WP_CLI/Process.php:73 add:

if( getenv( 'WP_CLI_TEST_XDEBUG' ) ) {
  $this->command = "XDEBUG_CONFIG=\"idekey=WP_CLI_TEST_XDEBUG remote_connect_back=1 log_level=0\" XDEBUG_MODE=debug $this->command";
}

Drawbacks:

Definitely slower. And I seem to have to click play often, but maybe that's just a PhpStorm setting I've got wrong.

Alternatives:

Edit every Behat feature to add XDEBUG_CONFIG="idekey=WP_CLI_XDEBUG remote_connect_back=1 log_level=0" XDEBUG_MODE=debug as needed.

I seem to need XDEBUG_SESSION=1 sometimes – I certainly did not need it when I opened the issue.</issue_description>

Comments on the Issue (you are @copilot in this section)

@swissspidy We do something similar already when running tests with code coverage:

$with_code_coverage = (string) getenv( 'WP_CLI_TEST_COVERAGE' );
if ( \in_array( $with_code_coverage, [ 'true', '1' ], true ) ) {
$has_coverage_driver = ( new Runtime() )->hasXdebug() || ( new Runtime() )->hasPCOV();
if ( ! $has_coverage_driver ) {
throw new RuntimeException( 'No coverage driver available. Re-run script with `--xdebug` flag, i.e. `composer behat -- --xdebug`.' );
}
$coverage_require_file = self::$behat_run_dir . '/vendor/wp-cli/wp-cli-tests/utils/generate-coverage.php';
if ( ! file_exists( $coverage_require_file ) ) {
// This file is not vendored inside the wp-cli-tests project
$coverage_require_file = self::$behat_run_dir . '/utils/generate-coverage.php';
}
$current = getenv( 'WP_CLI_REQUIRE' );
$updated = $current ? "{$current},{$coverage_require_file}" : $coverage_require_file;
$env['WP_CLI_REQUIRE'] = $updated;
}

So this could be an easy addition.</comment_new>


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

…ugging in Behat tests

Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com>
Copilot AI changed the title [WIP] Enable Xdebug in Behat tests Add WP_CLI_TEST_XDEBUG environment variable for step debugging in Behat tests Dec 1, 2025
Copilot AI requested a review from swissspidy December 1, 2025 16:22
@codecov
Copy link

codecov bot commented Dec 1, 2025

Codecov Report

❌ Patch coverage is 0% with 7 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/Context/FeatureContext.php 0.00% 7 Missing ⚠️

📢 Thoughts on this report? Let us know!

@swissspidy
Copy link
Member

@BrianHenryIE wanna test this one?

@BrianHenryIE
Copy link
Member

BrianHenryIE commented Dec 2, 2025

I took a look at using xdebug_info() function, thinking of possibly always enabling Xdebug when it is enabled for the current process. Then rather than running WP_CLI_TEST_XDEBUG=true behat the existing XDEBUG_MODE=debug behat could be used. But I'm not sure that it's a good idea or not. Maybe it could default to using XDEBUG_MODE on the inner process and have WP_CLI_TEST_XDEBUG as a means to disable that.

For visual: php -r "xdebug_info();"

Full xdebug_info output (expand)
__   __   _      _                 
\ \ / /  | |    | |                
 \ V / __| | ___| |__  _   _  __ _ 
  > < / _` |/ _ \ '_ \| | | |/ _` |
 / . \ (_| |  __/ |_) | |_| | (_| |
/_/ \_\__,_|\___|_.__/ \__,_|\__, |
                              __/ |
                             |___/ 

Version => 3.4.0alpha2-dev
Support Xdebug on Patreon, GitHub, or as a business: https://xdebug.org/support

             Enabled Features (through 'xdebug.mode' setting)             
Feature => Enabled/Disabled
Development Helpers => ✔ enabled
Coverage => ✘ disabled
GC Stats => ✘ disabled
Profiler => ✘ disabled
Step Debugger => ✘ disabled
Tracing => ✘ disabled

                            Optional Features                            
Compressed File Support => yes (gzip)
Clock Source => clock_gettime_nsec_np
'xdebug://gateway' pseudo-host support => no
'xdebug://nameserver' pseudo-host support => no
Systemd Private Temp Directory => not enabled

                              Diagnostic Log                              
No messages

                                   PHP                                   
                           Build Configuration                           
Version (Run Time) => 8.4.14
Version (Compile Time) => 8.4.0-dev
Debug Build => no
Thread Safety => disabled
                                 Settings                                 
Configuration File (php.ini) Path => /opt/homebrew/etc/php/8.4
Loaded Configuration File => (none)
Scan this dir for additional .ini files => /Users/brian.henry/Library/Application Support/Herd/config/php/84/
Additional .ini files parsed => /Users/brian.henry/Library/Application Support/Herd/config/php/84/php.ini


Directive => Local Value => Master Value
xdebug.mode => develop => develop
xdebug.start_with_request => default => default
xdebug.start_upon_error => default => default
xdebug.output_dir => /var/tmp/ => /var/tmp/
xdebug.use_compression => 1 => 1
xdebug.trigger_value => no value => no value
xdebug.file_link_format => no value => no value
xdebug.filename_format => no value => no value
xdebug.log => no value => no value
xdebug.log_level => 7 => 7
xdebug.var_display_max_children => 128 => 128
xdebug.var_display_max_data => 512 => 512
xdebug.var_display_max_depth => 3 => 3
xdebug.max_nesting_level => 512 => 512
xdebug.cli_color => 0 => 0
xdebug.force_display_errors => Off => Off
xdebug.force_error_reporting => 0 => 0
xdebug.halt_level => 0 => 0
xdebug.max_stack_frames => -1 => -1
xdebug.show_error_trace => Off => Off
xdebug.show_exception_trace => Off => Off
xdebug.show_local_vars => Off => Off
xdebug.dump.COOKIE => no value => no value
xdebug.dump.ENV => no value => no value
xdebug.dump.FILES => no value => no value
xdebug.dump.GET => no value => no value
xdebug.dump.POST => no value => no value
xdebug.dump.REQUEST => no value => no value
xdebug.dump.SERVER => no value => no value
xdebug.dump.SESSION => no value => no value
xdebug.dump_globals => On => On
xdebug.dump_once => On => On
xdebug.dump_undefined => Off => Off
xdebug.profiler_output_name => cachegrind.out.%p => cachegrind.out.%p
xdebug.profiler_append => Off => Off
xdebug.cloud_id => no value => no value
xdebug.client_host => localhost => localhost
xdebug.client_port => 9003 => 9003
xdebug.discover_client_host => Off => Off
xdebug.client_discovery_header => HTTP_X_FORWARDED_FOR,REMOTE_ADDR => HTTP_X_FORWARDED_FOR,REMOTE_ADDR
xdebug.idekey => no value => no value
xdebug.connect_timeout_ms => 200 => 200
xdebug.scream => Off => Off
xdebug.gc_stats_output_name => gcstats.%p => gcstats.%p
xdebug.trace_output_name => trace.%c => trace.%c
xdebug.trace_format => 0 => 0
xdebug.trace_options => 0 => 0
xdebug.collect_assignments => Off => Off
xdebug.collect_params => On => On
xdebug.collect_return => Off => Off

Partial xdebug_info output:

Directive => Local Value => Master Value
xdebug.mode => develop => develop
...
xdebug.log_level => 7 => 7
...
xdebug.idekey => no value => no value

It accepts a category parameter:

% php -r "print_r(xdebug_info('mode'));"

Array
(
    [0] => develop
)
% XDEBUG_MODE=debug php -r "print_r(xdebug_info('mode'));"

Array
(
    [0] => debug
)

It seems there is only 'mode' as a value that can be passed:

% php -r "print_r(xdebug_info('idekey'));"   

Warning: xdebug_info(): The information group 'idekey' is not available in Command line code on line 1

No tests in xdebug/xdebug suggested any other valid values.

I wrote the code to allow specifying the idekey: BrianHenryIE@951eb46

But after reading a bit more I don't know if it's worthwhile:

https://xdebug.org/docs/all_settings#idekey

Controls which IDE Key Xdebug should pass on to the debugging client or proxy. The IDE Key is only important for use with the DBGp Proxy Tool, although some IDEs are incorrectly picky as to what its value is.

https://www.jetbrains.com/help/phpstorm/configuring-xdebug.html#updatingPhpIni

To enable multi-user debugging via Xdebug proxies, locate the xdebug.idekey setting and assign it a value of your choice. This value will be used to register your IDE on Xdebug proxy servers.

I've still to actually run the code to test it but it reads like how I remember doing it before.

TODO:

  • Get opinions on always enabling Xdebug when the parent process has it enabled
  • Get feedback on value of idekey configuration
  • Test the code by running and confirm functionality
  • Compare changes between Xdebug 2 and Xdebug 3 to determine if this is compatible with both or requires v3 (xdebug_info is v3 only)
  • Consider adding wp-cli.yml/behat.yml config option

@swissspidy
Copy link
Member

Get opinions on always enabling Xdebug when the parent process has it enabled

Personally I'd want separate options, to have more flexibility and not accidentally slow down my whole test suite if I want to only debug the test runner and not the commands executed by it.

Compare changes between Xdebug 2 and Xdebug 3 to determine if this is compatible with both or requires v3 (xdebug_info is v3 only)

Should be reasonable to support only Xdebug 3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Enable Xdebug in Behat tests

3 participants