When using phpunit to generate code coverage, take into account what is executed...
authorgggeek <giunta.gaetano@gmail.com>
Sun, 22 Mar 2015 00:21:43 +0000 (00:21 +0000)
committergggeek <giunta.gaetano@gmail.com>
Sun, 22 Mar 2015 00:21:43 +0000 (00:21 +0000)
NEWS
demo/server/server.php
tests/3LocalhostTest.php
tests/phpunit_coverage.php [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index b1b1e49..236358c 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -19,13 +19,20 @@ even though we strongly urge you to use more recent versions.
 * improved: all php code is now formatted according to the PSR-2 standard
 
 * improved: this release is now tested using Travis ( https://travis-ci.org/ ).
+  Tests are executed using all php versions from 5.3 to 7.0 nightly, plus HHVM
 
 * improved: no need to call anymore $client->setSSLVerifyHost(2) to silence a curl warning when using https
   with recent curl builds
 
 * improved: phpunit is now installed via composer, not bundled anymore
 
-* improved: debug messages are not html-escaped when executing from the command line
+* improved: when phpunit is used to generate code-coverage data, the code executed server-side is accounted for
+
+* improved: debug messages are not html-escaped any more when executing from the command line
+
+* improved: a specific option allow users to decide the version of SSL to use for https calls.
+  This is useful f.e. for the testing suite, when the server target of calls has no proper ssl certificate,
+  and the cURL extension has been compiled with GnuTLS (such as Travis)
 
 
 XML-RPC for PHP version 3.0.0 - 2014/6/15
index 5f34c75..b6fa526 100644 (file)
@@ -17,6 +17,17 @@ if ($_SERVER['REQUEST_METHOD'] != 'POST' && isset($_GET['showSource'])) {
 
 include_once __DIR__ . "/../../vendor/autoload.php";
 
+// out-of-band information: let the client manipulate the server operations.
+// we do this to help the testsuite script: do not reproduce in production!
+if (isset($_COOKIE['PHPUNIT_SELENIUM_TEST_ID']) && extension_loaded('xdebug')) {
+    $GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY'] = '/tmp/phpxmlrpc_coverage';
+    if (!is_dir($GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY'])) {
+        mkdir($GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY']);
+    }
+
+    include_once __DIR__ . "/../../vendor/phpunit/phpunit-selenium/PHPUnit/Extensions/SeleniumCommon/prepend.php";
+}
+
 include_once __DIR__ . "/../../lib/xmlrpc.inc";
 include_once __DIR__ . "/../../lib/xmlrpcs.inc";
 include_once __DIR__ . "/../../lib/xmlrpc_wrappers.inc";
@@ -36,7 +47,7 @@ class xmlrpc_server_methods_container
     }
 
     /**
-     * Method used to testcatching of exceptions in the server.
+     * Method used to test catching of exceptions in the server.
      */
     public function exceptiongenerator($m)
     {
@@ -877,3 +888,9 @@ if (isset($_GET['EXCEPTION_HANDLING'])) {
 }
 $s->service();
 // that should do all we need!
+
+// out-of-band information: let the client manipulate the server operations.
+// we do this to help the testsuite script: do not reproduce in production!
+if (isset($_COOKIE['PHPUNIT_SELENIUM_TEST_ID']) && extension_loaded('xdebug')) {
+    include_once __DIR__ . "/../../vendor/phpunit/phpunit-selenium/PHPUnit/Extensions/SeleniumCommon/append.php";
+}
\ No newline at end of file
index a773548..0dce568 100644 (file)
@@ -8,21 +8,25 @@ include_once __DIR__ . '/parse_args.php';
 class LocalhostTest extends PHPUnit_Framework_TestCase
 {
     /** @var xmlrpc_client $client */
-    public $client = null;
-    public $method = 'http';
-    public $timeout = 10;
-    public $request_compression = null;
-    public $accepted_compression = '';
-    public $args = array();
+    protected $client = null;
+    protected $method = 'http';
+    protected $timeout = 10;
+    protected $request_compression = null;
+    protected $accepted_compression = '';
+    protected $args = array();
 
     protected static $failed_tests = array();
 
+    protected $testId;
+    /** @var boolean $collectCodeCoverageInformation */
+    protected $collectCodeCoverageInformation;
+    protected $coverageScriptUrl;
+
     public static function fail($message = '')
     {
-        // save in global var that this particular test has failed
+        // save in a static var that this particular test has failed
         // (but only if not called from subclass objects / multitests)
         if (function_exists('debug_backtrace') && strtolower(get_called_class()) == 'localhosttests') {
-            global $failed_tests;
             $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
             for ($i = 0; $i < count($trace); $i++) {
                 if (strpos($trace[$i]['function'], 'test') === 0) {
@@ -36,8 +40,41 @@ class LocalhostTest extends PHPUnit_Framework_TestCase
     }
 
     /**
-     * @todo be smarter with setup, do not use global variables anymore
+     * Reimplemented to allow us to collect code coverage info from the target server.
+     * Code taken from PHPUnit_Extensions_Selenium2TestCase
+     *
+     * @param PHPUnit_Framework_TestResult $result
+     * @return PHPUnit_Framework_TestResult
+     * @throws Exception
      */
+    public function run(PHPUnit_Framework_TestResult $result = NULL)
+    {
+        $this->testId = get_class($this) . '__' . $this->getName();
+
+        if ($result === NULL) {
+            $result = $this->createResult();
+        }
+
+        $this->collectCodeCoverageInformation = $result->getCollectCodeCoverageInformation();
+
+        parent::run($result);
+
+        if ($this->collectCodeCoverageInformation) {
+            $coverage = new PHPUnit_Extensions_SeleniumCommon_RemoteCoverage(
+                $this->coverageScriptUrl,
+                $this->testId
+            );
+            $result->getCodeCoverage()->append(
+                $coverage->get(), $this
+            );
+        }
+
+        // do not call this before to give the time to the Listeners to run
+        //$this->getStrategy()->endOfTest($this->session);
+
+        return $result;
+    }
+
     public function setUp()
     {
         $this->args = argParser::getArgs();
@@ -53,10 +90,16 @@ class LocalhostTest extends PHPUnit_Framework_TestCase
         }
         $this->client->request_compression = $this->request_compression;
         $this->client->accepted_compression = $this->accepted_compression;
+
+        $this->coverageScriptUrl = 'http://' . $this->args['LOCALSERVER'] . '/' . str_replace( '/demo/server/server.php', 'tests/phpunit_coverage.php', $this->args['URI'] );
     }
 
-    public function send($msg, $errrorcode = 0, $return_response = false)
+    protected function send($msg, $errrorcode = 0, $return_response = false)
     {
+        if ($this->collectCodeCoverageInformation) {
+            $this->client->setCookie('PHPUNIT_SELENIUM_TEST_ID', $this->testId);
+        }
+
         $r = $this->client->send($msg, $this->timeout, $this->method);
         // for multicall, return directly array of responses
         if (is_array($r)) {
@@ -574,6 +617,12 @@ And turned it into nylon';
         if (!$r->faultCode()) {
             $v = $r->value();
             $v = php_xmlrpc_decode($v);
+
+            // take care for the extra cookie used for coverage collection
+            if (isset($v['PHPUNIT_SELENIUM_TEST_ID'])) {
+                unset($v['PHPUNIT_SELENIUM_TEST_ID']);
+            }
+
             // on IIS and Apache getallheaders returns something slightly different...
             $this->assertEquals($v, $cookies);
         }
diff --git a/tests/phpunit_coverage.php b/tests/phpunit_coverage.php
new file mode 100644 (file)
index 0000000..ae7b998
--- /dev/null
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Used to serve back the server-side code coverage results to phpunit-selenium
+ *
+ * @copyright (C) 2007-2015 G. Giunta
+ * @license code licensed under the BSD License: see file license.txt
+ **/
+
+$coverageFile = realpath(__DIR__ . "/../vendor/phpunit/phpunit-selenium/PHPUnit/Extensions/SeleniumCommon/phpunit_coverage.php");
+
+// has to be the same value as used in server.php
+$GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY'] = '/tmp/phpxmlrpc_coverage';
+
+chdir($GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY']);
+
+include_once $coverageFile;
\ No newline at end of file