1
votes

While debugging test class (child class of PHPUnit_Framework_TestCase) in PhpStorm it stops on breakpoints that are set in this class, but not stopping in controller (Symfony) that request point to.

//test class - here debugger stops
class FooControllerTest extends \PHPUnit_Framework_TestCase
{
    public function testPOST()
    {
        $response = $this->client->post('/api/foo', [
           'body' => json_encode($data)
        ]);

.

//controller - here debugger not stopping
/**
 * @Route("/api/foo")
 * @Method("POST")
 */
public function newAction(Request $request)
{
    //...
    return new Response($json, 201, array(
        'Content-Type' => 'application/json'
    ));

Request enters to this controller for sure, because I can change http code there and this change is readable in test class after client->post( line

How to debug controller while testing?

2
Quite possibly it's done as additional/separate request and "debug me" flag is not passed with it. It's also possible that IDE setup to handle max 1 simultaneous debug sessions (default setting). For 1st point -- maybe configure xdebug to debug ANY incoming request without any flags (xdebug.remote_autostart=1). Not ideal in other situations, obviously. Or add xdebug cookie or GET parameter to such request. Can also try placing xdebug_break(); in actual code -- should work. - LazyOne
For 2nd point -- increase that number in IDE settings (hint: use search box in Settings/Preferences screen with "xdebug" as keyword) - LazyOne
@LazyOne Thanks, added GET parameter and its working. Solution with xdebug.remote_autostart=1 and xdebug_break(); after increased number of simultaneous session not worked. I will add it as an answer, You can copy my answer to Your if you care about points (then I will remove my) - Sruj

2 Answers

0
votes

If you are testing your api with Symfony and PHPUnit, there are a few recommendations that I can give you, providing the fact that I don't really and fully understand what you mean by "debugging the controller".

First: When a test fails, attach a listener to PHPUnit that will print the PSR-7 HTTP Request and Response bodies. If you're using Guzzle 6, that can be achieved pretty easily. Here are some docs to help you:

Second: Enable the profiler in your config_test.yml. That way the profiler will collect info for your tests and will make your debugging easier. Since you are printing the Psr7 Request and Response strings, the headers will include a link to the profiler for that request.

That with a SQLite database make my setup for testing, and I found it pretty helful. Now, if you really want to jump to the next level, you should use Behat. :)

0
votes

In PhpStrom you need to prepare Simultaneous debugging sessions. So in your case inside Test class add GET parameter to URL:

class FooControllerTest extends \PHPUnit_Framework_TestCase
{
    public function testPOST()
    {
        //...
        $response = $this->client->post('/api/foo'. '?' . $this->getDebugQuery(), [
            'body' => json_encode($data)
        ]);
        //...

    }

    private function getDebugQuery()
    {
        $debuggingQuerystring = '';
        if (isset($_GET['XDEBUG_SESSION_START'])) { // xdebug
            $debuggingQuerystring = 'XDEBUG_SESSION_START=' . $_GET['XDEBUG_SESSION_START'];
        }
        if (isset($_COOKIE['XDEBUG_SESSION'])) { // xdebug (cookie)
            $debuggingQuerystring = 'XDEBUG_SESSION_START=PHPSTORM';
        }
        if (isset($_GET['start_debug'])) { // zend debugger
            $debuggingQuerystring = 'start_debug=' . $_GET['start_debug'];
        }
        if (empty($debuggingQuerystring)) {
            $debuggingQuerystring = 'XDEBUG_SESSION_START=PHPSTORM';
        }

        return $debuggingQuerystring;
    }

and toggle the “Listen debugger connections” button.