Since simpletest is meant for testing/development, it would be helpful if it fully supported debugging.

As things are now, if you want to debug what happens inside the drupalPost/drupalGet requests in Simpletest [debug in the sense of "step through the code in a debugger", such as xdebug or Zend], you have to do something like what is described on the bottom of this page:
http://drupal.org/node/30011

Namely, you either need to set up a separate Apache virtual server and use that, or you need to hack drupalPost/drupalGet to add something like this near the top to add the debugging session information to the URL before it is passed through curl:

if (!isset($options['query'])) {
  $options['query'] = array();
}
$options['query'] += array('XDEBUG_SESSION_START' => 'ECLIPSE_DPGP');

It would be nice if SimpleTest could do this automatically. Two methods I thought of:
a) Detect an XDEBUG_SESSION_START cookie in the environment when the test is launched, and do the above if it's there. This could be problematic, because you may not be able to anticipate exactly what environment variable you're looking for, depending on how people debug (e.g. xdebug vs. zend - I have no idea what the env variable is for zend, and are there other debuggers?). So that's probably not the best idea.

b) Have a config option to add query variable(s) to all URL requests. It could be set up so that on a config screen, you would enter "XDEBUG_SESSION_START" in one box, and "ECLIPSE_DPGP" in another (or whatever the equivalents are for your particular debugging setup), to define your debug environment variable needs, and then have a "debug these tests" checkbox on the "Run Tests" screen. If the box was checked and the options were set, the code above would be added to drupalGet/drupalPost before the cURL call during the test run.

I think it would be useful... thoughts?

Files: 
CommentFileSizeAuthor
#31 drupal-simpletest_xdebug-889338-31.patch2.44 KBheddn
FAILED: [[SimpleTest]]: [MySQL] 41,162 pass(es), 1 fail(s), and 0 exception(s).
[ View ]
#19 drupal-889338-19.patch1.48 KBdawehner
PASSED: [[SimpleTest]]: [MySQL] 56,801 pass(es).
[ View ]
#17 interdiff.txt1.01 KBdawehner
#17 drupal-889338-17.patch1.47 KBdawehner
PASSED: [[SimpleTest]]: [MySQL] 56,885 pass(es).
[ View ]
#16 WebtestBase-xdebug-889338-16.patch1.07 KBdas-peter
PASSED: [[SimpleTest]]: [MySQL] 55,994 pass(es).
[ View ]
#13 WebtestBase-xdebug-889338-13.patch1.04 KBdas-peter
PASSED: [[SimpleTest]]: [MySQL] 55,778 pass(es).
[ View ]
#8 WebtestBase-xdebug-889338-8.patch2.08 KByched
PASSED: [[SimpleTest]]: [MySQL] 55,539 pass(es).
[ View ]

Comments

salvis’s picture

There's definitely a need to be able to step into / break inside drupalGet()/drupalPost().

I don't have a good grasp of the variety of debugging solutions, but isn't proposal a) a sort of a mandatory solution, which would always slow down your test runs, even when you only want to debug the test, without any need for stepping into drupalGet()/drupalPost()?

jhodgdon’s picture

I got this working by following the procedure linked to above, so you might try that too. I also edited that page with some updated suggestions. I'm not sure any more whether it's necessary to put this into the Simpletest class...

salvis’s picture

Thank you. I haven't been desperate enough yet, but I'll try it when I need to.

jhodgdon’s picture

Status:Active» Fixed

I think the handbook page edit mentioned above is sufficient for this to be considered fixed.

Status:Fixed» Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

yched’s picture

Title:Support xdebug in WebTestBase ?» Support debugging better

Reopening.

Having to set up a separate Apache virtual server, or patching WebTestBase on and off again and again is a pain.
Could be as simple as WebTestBase::curlExec() forwarding XDEBUG_SESSION_START if it finds it in the cookie ?

yched’s picture

Title:Support debugging better» Support xdebug in WebTestBase ?
Version:7.x-dev» 8.x-dev
Status:Closed (fixed)» Active

Retitling.

yched’s picture

Title:Support debugging better» Support xdebug in WebTestBase ?
Status:Active» Needs review
StatusFileSize
new2.08 KB
PASSED: [[SimpleTest]]: [MySQL] 55,539 pass(es).
[ View ]

Patch.

das-peter’s picture

Yeah, that's exactly what I need too!
I was using something like this so far in WebTestBase::curlExec():

<?php
   
// Forward xdebug session.
   
if (isset($_COOKIE['XDEBUG_SESSION'])) {
      if (!isset(
$curl_options[CURLOPT_COOKIE])) {
       
$curl_options[CURLOPT_COOKIE] = '';
      }
      if (!empty(
$curl_options[CURLOPT_COOKIE]) && substr(trim($curl_options[CURLOPT_COOKIE]), -1, 1) != ';') {
       
$curl_options[CURLOPT_COOKIE] .= '; ';
      }
     
$curl_options[CURLOPT_COOKIE] .= 'XDEBUG_SESSION=' . $_COOKIE['XDEBUG_SESSION'] . '; ';
    }

   
curl_setopt_array($this->curlHandle, $this->additionalCurlOptions + $curl_options);
?>

But I can't say if there's a difference between passing the xdebug session as url parameter or as cookie.

dawehner’s picture

I tried out the patch but it didn't worked for me. Maybe that's just my setup of xdebug.

dawehner’s picture

Status:Needs review» Reviewed & tested by the community

Yched helped me out: For some odd reasons PHPStorm had setup a max. amount of connection to 1, so the subconnection didn't got picked up.

Damien Tournoud’s picture

Status:Reviewed & tested by the community» Needs work
<?php
+        $options = drupal_parse_url($curl_options[CURLOPT_URL]);
+       
$options += array('query' => array());
+       
$options['query'] += array('XDEBUG_SESSION_START' => $_COOKIE['XDEBUG_SESSION']);
+       
$curl_options[CURLOPT_URL] = url($options['path'], $options);
?>

url() is really not meant for that. If you really want to do URL parsing this late in the process, use lower-level functions.

das-peter’s picture

Status:Needs work» Needs review
StatusFileSize
new1.04 KB
PASSED: [[SimpleTest]]: [MySQL] 55,778 pass(es).
[ View ]

Well then, here's my approach as a patch.
Only thing I'm still not sure about is whether there's a difference between using cookies or an url parameter (I don't think so) and if setting CURLOPT_COOKIE could interfere with the cookie handling in the tests (I actually had never a problem with that).
Let's see what the testbot says.

yched’s picture

#13 works for me too.

yched’s picture

I'd suggest this slightly simpler shape for the code though :

<?php
      $curl_options
+= array(
       
CURLOPT_COOKIE => '',
      );
     
// Ensure any existing cookie data string ends with the correct separator.
     
if (!empty($curl_options[CURLOPT_COOKIE])) {
       
$curl_options[CURLOPT_COOKIE] = rtrim($curl_options[CURLOPT_COOKIE], '; ') . '; ';
      }
     
$curl_options[CURLOPT_COOKIE] .= 'XDEBUG_SESSION=' . $_COOKIE['XDEBUG_SESSION'] . '; ';
?>
das-peter’s picture

StatusFileSize
new1.07 KB
PASSED: [[SimpleTest]]: [MySQL] 55,994 pass(es).
[ View ]

Good idea, and here we go.

dawehner’s picture

StatusFileSize
new1.47 KB
PASSED: [[SimpleTest]]: [MySQL] 56,885 pass(es).
[ View ]
new1.01 KB

It works really great if you have allow three external connections in your debugger. Here is some more explanation and documentation.

damiankloip’s picture

+++ b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.phpundefined
@@ -1044,6 +1044,24 @@ protected function curlExec($curl_options, $redirect = FALSE) {
+    // so you can't debug actual running code. In order to make debuggers this

Make debuggers work?

+++ b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.phpundefined
@@ -1044,6 +1044,24 @@ protected function curlExec($curl_options, $redirect = FALSE) {
+    // at least 3 external connections.

Not sure if this should be 'three' - maybe xjm is a good person to ask. I will make the wrong decision here :)

dawehner’s picture

StatusFileSize
new1.48 KB
PASSED: [[SimpleTest]]: [MySQL] 56,801 pass(es).
[ View ]

Just corrected both.

das-peter’s picture

This looks good to me - and I'd like to set it to RTBC.
However it would be great if we had something like http://drupal.org/debugging or http://drupal.org/xdebug to document how to use debuggers / set up IDE's and add the link to the doc-block.
I hope we'll create such a page today at the DrupalCon Portland sprint.

jhodgdon’s picture

das-peter: Sounds like a great idea! There are some notes on http://drupal.org/node/30011 and a troubleshooting section http://drupal.org/troubleshooting that may have info.

if you create a page under Troubleshooting somewhere (I think that would be a good place?) and link here, we can make sure it gets an alias (or you can get someone at the sprint to add it if you don't have permission).

yched’s picture

Bump - this has been a total life saver for the past month :-)

swentel’s picture

Status:Needs review» Reviewed & tested by the community

Let's do this!

das-peter’s picture

I didn't manage to create the document page as I hoped :| And there was a discussion about supporting cli (no cookies) and zend debugger.
However, there's nothing wrong with the current implementation and it's really handy.
Thus +1 for getting this in asap.

alexpott’s picture

Title:Support xdebug in WebTestBase ?» Add support for xdebug in WebTestBase
Status:Reviewed & tested by the community» Fixed

Committed f63db4c and pushed to 8.x. Thanks!

Status:Fixed» Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

tstoeckler’s picture

yched’s picture

Am I the only one for which this doesn't anymore ?
When running a WebTest, setting a breakpoint in the "tested" side just seems to make the curl_exec() call in WebTestBase::curlExec() just die.

(note: I started seeing this a couple weeks ago, well before #2134259: Make the Simpletest XDebug integration work for CLI requests was added)

roderik’s picture

Probably not important here - but in my case, curl_exec() just hung indefinitely (not crashed).

After a day of tracing the problem I found out I am apparently starting PHPStorm debug sessions 'the wrong way'. Updated docs.

heddn’s picture

Version:8.0.x-dev» 7.x-dev
Status:Closed (fixed)» Patch (to be ported)

Let's see if we can get this backported.

heddn’s picture

Status:Patch (to be ported)» Needs review
StatusFileSize
new2.44 KB
FAILED: [[SimpleTest]]: [MySQL] 41,162 pass(es), 1 fail(s), and 0 exception(s).
[ View ]

And here goes a patch.

frankcarey’s picture

This worked for me and I'm using codebug http://codebugapp.com/ which isn't integrated with an IDE, so it took a couple extra things..

1) This REQUIRES setting a cookie during your request when viewing the tests page. To do that outside an IDE, I just used the chrome plugin. https://chrome.google.com/webstore/detail/xdebug-helper/eadndfjplgieldjb... It looks like using this url will set the cookie as well: admin/config/development/testing?XDEBUG_SESSION_START=XDEBUG_ECLIPSE

2) using xdebug_break(); for initial breakpoints worked since it's more tricky to set breakpoints with my setup, but once that fires, I can add additional breakpoints.

=== UPDATE ====

Correction, this doesn't seem to work on subsequent requests. I see calls that look correct to say the contact form when running the contact tests ( http://d7dev.local/contact?XDEBUG_SESSION_START=XDEBUG_ECLIPSE) but my xdebug_break(); calls in contact.pages.inc seem to be unheeded.

This was the code i used for the contact module..

<?php
function contact_site_form($form, &$form_state) {
  global
$user;
 
xdebug_break();
 
// Check if flood control has been activated for sending e-mails.
 //...
?>

Some other notes: I'm using php 5.4.36 in this environment and many tests are failing
Screen grab of test result showing failed tests and params being added

frankcarey’s picture

StatusFileSize
new131.4 KB
frankcarey’s picture

OK, so I finally got this to work. Some other details of my environment is that I'm working on a vagrant VM so that adds some wrinkles too..

1) If you are running tests via simpletest module on a VM, you need to make sure that xdebug.remote_connect_back is disabled, and you use the xdebug.remote_host setting instead (with the IP address of the xdebug client from within the VM.. like xdebug.remote_host = 33.33.33.1 for my machine. xdebug.remote_connect_back will clobber remote host, and since the requests are basically coming from localhost when drupal sends them, it will be looking for an xdebug client at 127.0.0.1:9000 instead of your actual machine.

2) At least for my debugger, it seems to get somewhat messed up with multiple sessions. What I had to do to get it working finally was to only enable the debugger AFTER I started the tests running. Then each separate request is handled by the debugger, including xdebug_break() breakpoints. I'm guessing that once the session starts for the test-runner itself, the debugger doesn't pick up on the new sessions and just ignores them.

3) Don't forget to set your local /etc/hosts file so that your development url continues to work when requested locally. For me it's d7dev.local, so I had to add that to the VM's /etc/hosts file as well. All the errors I was getting was because it was making requests and getting the default apache response :/ That also means that my custom breakpoints never had a change to run, because the right code wasn't being called by the drupal tests.

4) A simple way to test things are working before even testing this patch is to use curl from the command line like so : curl http://mysite.local?XDEBUG_SESSION_START=XDEBUG_ECLIPSE .. replace XDEBUG_ECLIPSE with whatever string you have configured with your IDE. If you are working with a local VM, then make sure to run the curl command within the VM (ssh in and run it).

frankcarey’s picture

Status:Needs review» Reviewed & tested by the community

Status:Reviewed & tested by the community» Needs work

The last submitted patch, 31: drupal-simpletest_xdebug-889338-31.patch, failed testing.

David_Rothstein’s picture

Status:Needs work» Reviewed & tested by the community

Testbot fluke.

Status:Reviewed & tested by the community» Needs work

The last submitted patch, 31: drupal-simpletest_xdebug-889338-31.patch, failed testing.

stefan.r’s picture

Status:Needs work» Reviewed & tested by the community