0

I'm writing integration tests for a SOAP API (code example s. below).

Now I got an error and want to debug my server-side code (in PhpStorm). But the debugger considers only the breakpoints in the test and ignores the server-side code.

OK, I probably roughly understand why: The call of the $soapClient->doSomething(...); starts a new HTTP request. How to get this "sub-request" (from the point of view of PhpUnit) debugged?


Integration test's code:

class UserIntegrationTest extends TestCaseBase
{
    const URL = "http://my-server.loc/soapapi/user/wsdl";
    public static $classMap = [];
    /** @var SoapClient */
    private $soapClient;


    /** @var ConfigurationServiceInterface */
    private $config;

    public function setUp()
    {
        parent::setUp();

        $options = [
            'exceptions' => true,
            'login' => 'foo',
            'password' => 'pwd',
            'encoding' => 'utf-8',
//            'proxy_host' => '192.168.2.96',
//            'proxy_port' => '8080',
            'classmap' => [],
            'connection_timeout' => 5,
        ];

        $this->soapClient = new SoapClient(self::URL, $options);
    }

    /**
     * @test
     * @group integration
     */
    public function testDoSomething()
    {
        $options = array(
            'exceptions' => true,
            'login' => 'foo',
            'password' => 'pwd',
            'encoding' => 'utf-8',
//            'proxy_host' => '192.168.2.96',
//            'proxy_port' => '8080',
            'classmap' => [],
            'connection_timeout' => 5,
        );

        $soapClient = new SoapClient(self::URL, $options);

        $message = new MyMessage();
        $message->x = 1;
        $message->y = 2;
        $result = $soapClient->doSomething($message);
    }

    protected function getDataSet()
    {
        return new ArrayDataSet([
            'users' => [
                [
                    'id' => 1,
                    'username' => 'foo',
                    'password' => '...',
                ],
            ],
            ...
        ]);
    }
}
automatix
  • 14,018
  • 26
  • 105
  • 230

2 Answers2

0

The solution is to append ?XDEBUG_SESSION_START=ECLIPSE_DBGP to the URI called by the SOAP client. So in the port segment of the WSDL

<port name="UserPort" binding="tns:UserBinding">
    <soap:address location="http://my-server.loc/soapapi/user"/>
</port>

the location needs to be extended by the Xdebug query and look like this:

http://my-server.loc/soapapi/user?XDEBUG_SESSION_START=ECLIPSE_DBGP

Sure, the productive WSDL should not contain such location. But WSDLs are usually generated (e.g. by Zend\Soap\AutoDiscover) and the URI can be easily made dynamically configurable.

automatix
  • 14,018
  • 26
  • 105
  • 230
  • 1
    ... or just configure `xdebug.remote_autostart = 1` in php.ini -- xdebug will attempt to debug _every single request_ regardless of "debug me" parameter/cookie. Drawback -- affects ALL requests and not just SOAP. – LazyOne Jun 14 '17 at 15:20
  • I didn't want to change the Xdebug's behavior. But for someone, who has no problem with it, sure, it also would work and would be even a better/simpler solution. – automatix Jun 14 '17 at 16:22
0

You can do this by setting the XDEBUG_SESSION cookie in your client application.

I believe this is a better alternative than the accepted answer, as it does not require changing the server-side code (WSDL).

For example, using PHP SoapClient as per the OP's code sample

$soapClient = new SoapClient(self::URL, $options);
$soapClient->__setCookie('XDEBUG_SESSION', 'PHPSTORM');

Then in PhpStorm, Start listening for PHP Debug Connections and run your test script.

dregad
  • 1,150
  • 8
  • 21