From cf7fc454ec1789603b360d69db83faf49b1e3ef1 Mon Sep 17 00:00:00 2001 From: Florian Pritz Date: Fri, 22 Jul 2016 14:31:11 +0200 Subject: Add code coverage output Signed-off-by: Florian Pritz --- application/controllers/tools.php | 17 ++++++++++++++++ application/test/Test.php | 7 +++++++ composer.json | 5 +++++ public_html/index.php | 41 +++++++++++++++++++++++++++++++++++++++ run-tests.sh | 12 +++++++++--- 5 files changed, 79 insertions(+), 3 deletions(-) create mode 100644 composer.json diff --git a/application/controllers/tools.php b/application/controllers/tools.php index 845597b08..e90ed6d5f 100644 --- a/application/controllers/tools.php +++ b/application/controllers/tools.php @@ -88,6 +88,7 @@ class Tools extends MY_Controller { try { $test->setTestNamePrefix($method->name." - "); $test->init(); + $test->setTestID("{$testcase}->{$method->name}"); $test->{$method->name}(); $test->cleanup(); } catch (\Exception $e) { @@ -97,10 +98,26 @@ class Tools extends MY_Controller { } } } + if ($exitcode == 0) { $test->done_testing(); } else { exit($exitcode); } } + + function generate_coverage_report() + { + include APPPATH."../vendor/autoload.php"; + $coverage = new \SebastianBergmann\CodeCoverage\CodeCoverage(); + foreach (glob(FCPATH."/test-coverage-data/*") as $file) { + $coverage->merge(unserialize(file_get_contents($file))); + } + + //$writer = new \SebastianBergmann\CodeCoverage\Report\Text(); + //print $writer->process($coverage, 'code-coverage-report'); + $writer = new \SebastianBergmann\CodeCoverage\Report\Html\Facade(); + print $writer->process($coverage, 'code-coverage-report'); + print "Report saved to ./code-coverage-report/index.html\n"; + } } diff --git a/application/test/Test.php b/application/test/Test.php index 925fe131e..a0ebf880e 100644 --- a/application/test/Test.php +++ b/application/test/Test.php @@ -26,6 +26,7 @@ class TestMore extends \TestMore { abstract class Test { protected $t; protected $server = ""; + private $testid = ""; public function __construct() { @@ -38,6 +39,11 @@ abstract class Test { $this->server = $server; } + public function setTestID($testid) + { + $this->testid = $testid; + } + // Method: POST, PUT, GET etc // Data: array("param" => "value") ==> index.php?param=value // Source: http://stackoverflow.com/a/9802854/953022 @@ -77,6 +83,7 @@ abstract class Test { curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($curl, CURLOPT_HTTPHEADER, array( "Accept: application/json", + "X-Testsuite-Testname: API request from ".$this->testid, "Expect: ", )); diff --git a/composer.json b/composer.json new file mode 100644 index 000000000..cb0ee35fa --- /dev/null +++ b/composer.json @@ -0,0 +1,5 @@ +{ + "require": { + "phpunit/php-code-coverage": "^4.0" + } +} diff --git a/public_html/index.php b/public_html/index.php index de9d2a16c..3c531e64c 100644 --- a/public_html/index.php +++ b/public_html/index.php @@ -207,6 +207,18 @@ function _exception_handler($severity, $message, $filepath, $line) { return \libraries\ExceptionHandler::error_handler($severity, $message, $filepath, $line); } +// Source: http://stackoverflow.com/a/15875555 +function guidv4() +{ + $data = openssl_random_pseudo_bytes(16); + assert(strlen($data) == 16); + + $data[6] = chr(ord($data[6]) & 0x0f | 0x40); // set version to 0100 + $data[8] = chr(ord($data[8]) & 0x3f | 0x80); // set bits 6-7 to 10 + + return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4)); +} + /* * -------------------------------------------------------------------- * LOAD THE BOOTSTRAP FILE @@ -215,6 +227,29 @@ function _exception_handler($severity, $message, $filepath, $line) { * And away we go... * */ + +$testname = null; + +if (getenv("ENVIRONMENT") === "testsuite") { + if (function_exists("phpdbg_get_executable")) { + $testname = implode(' ', $argv); + } elseif (isset($_SERVER["HTTP_X_TESTSUITE_TESTNAME"])) { + $testname = $_SERVER["HTTP_X_TESTSUITE_TESTNAME"]; + } +} + +if ($testname) { + include APPPATH."../vendor/autoload.php"; + $filter = new \SebastianBergmann\CodeCoverage\Filter(); + $filter->addDirectoryToWhitelist(APPPATH); + $filter->removeDirectoryFromWhitelist(APPPATH."/third_party/"); + // Force phpdbg for speed + //$driver = new \SebastianBergmann\CodeCoverage\Driver\PHPDBG(); + $driver = null; + $coverage = new \SebastianBergmann\CodeCoverage\CodeCoverage($driver, $filter); + $coverage->start($testname); +} + try { require_once BASEPATH.'core/CodeIgniter.php'; } catch (\exceptions\NotAuthenticatedException $e) { @@ -230,6 +265,12 @@ try { } } catch (\exceptions\PublicApiException $e) { show_error(nl2br(htmlspecialchars($e->__toString())), $e->get_http_error_code()); +} finally { + if ($testname) { + $coverage->stop(); + $outputfile = FCPATH."/test-coverage-data/".guidv4(); + file_put_contents($outputfile, serialize($coverage)); + } } /* End of file index.php */ diff --git a/run-tests.sh b/run-tests.sh index 23dd74ac4..35a23cbdc 100755 --- a/run-tests.sh +++ b/run-tests.sh @@ -35,12 +35,18 @@ cleanup() { php -S "$ip:$port" -t public_html 2>/dev/null 1>&2 & +mkdir -p test-coverage-data + while ! curl -s "$url" >/dev/null; do sleep 0.1; done # run tests -php index.php tools drop_all_tables || exit 1 -php index.php tools update_database || exit 1 -prove --ext .php --state=hot,slow,all,save --timer -o -e "php index.php tools test $url" -r "$@" application/test/tests/ +phpdbg -qrr index.php tools drop_all_tables || exit 1 +phpdbg -qrr index.php tools update_database || exit 1 +prove --ext .php --state=hot,slow,all,save --timer -o -e "phpdbg -qrr index.php tools test $url" -r "$@" application/test/tests/ || exit 1 + + +php index.php tools generate_coverage_report +rm -rf test-coverage-data -- cgit v1.2.3-24-g4f1b