public static function tests_pchart2() { /* $xmlStr = <<<EOT <testsuites> <testsuite2 name="whaever"> <testsuite name="DatabaseTest" file="/Users/pfonseca/Dev/cintient/src/tests/DatabaseTest.php" tests="23" assertions="79" failures="0" errors="0" time="0.129403"> <testsuite name="DatabaseTest::testExecuteNoParamsBinding" tests="5" assertions="15" failures="0" errors="0" time="0.028787"> <testcase name="testExecuteNoParamsBinding with data set #0" assertions="3" time="0.010916"/> <testcase name="testExecuteNoParamsBinding with data set #1" assertions="3" time="0.004554"/> <testcase name="testExecuteNoParamsBinding with data set #2" assertions="3" time="0.004264"/> <testcase name="testExecuteNoParamsBinding with data set #3" assertions="3" time="0.004306"/> <testcase name="testExecuteNoParamsBinding with data set #4" assertions="3" time="0.004747"/> </testsuite> <testsuite name="DatabaseTest::testQueryNoParamsBinding" tests="1" assertions="3" failures="0" errors="0" time="0.004441"> <testcase name="testQueryNoParamsBinding with data set #0" assertions="3" time="0.004441"/> </testsuite> <testsuite name="DatabaseTest::testQueryParamsBinding" tests="1" assertions="3" failures="0" errors="0" time="0.004417"> <testcase name="testQueryParamsBinding with data set #0" assertions="3" time="0.004417"/> </testsuite> <testsuite name="DatabaseTest::testQueryParamsBindingExcessValues" tests="1" assertions="3" failures="0" errors="0" time="0.005673"> <testcase name="testQueryParamsBindingExcessValues with data set #0" assertions="3" time="0.005673"/> </testsuite> </testsuite> </testsuite2> </testsuites> EOT; */ $xmlStr = <<<EOT <aa> <aa1> <aa2 name="DatabaseTest" file="/Users/pfonseca/Dev/cintient/src/tests/DatabaseTest.php" tests="23" assertions="79" failures="0" errors="0" time="0.129403"> <aa3 name="DatabaseTest::testExecuteNoParamsBinding" tests="5" assertions="15" failures="3" errors="0" time="0.028787"> <aa41 name="testExecuteNoParamsBinding with data set #0" assertions="3" time="0.010916"/> <aa42 name="testExecuteNoParamsBinding with data set #1" assertions="3" time="0.004554"/> <aa43 name="testExecuteNoParamsBinding with data set #1" assertions="3" time="0.004554"/> <aa44 name="testExecuteNoParamsBinding with data set #1" assertions="3" time="0.004554"/> <aa45 name="testExecuteNoParamsBinding with data set #1" assertions="3" time="0.004554"/> <aa46 name="testExecuteNoParamsBinding with data set #1" assertions="3" time="0.004554"/> </aa3> <aa4 name="DatabaseTest::testExecuteParamsBinding" tests="5" assertions="12" failures="1" errors="0" time="0.010916"> <aa41 name="testExecuteNoParamsBinding with data set #0" assertions="3" time="0.010916"/> <aa42 name="testExecuteNoParamsBinding with data set #1" assertions="3" time="0.004554"/> <aa43 name="testExecuteNoParamsBinding with data set #1" assertions="3" time="0.004554"/> <aa44 name="testExecuteNoParamsBinding with data set #1" assertions="3" time="0.004554"/> </aa4> <aa5 name="DatabaseTest::testQuery" tests="5" assertions="4" failures="0" errors="0" time="0.004554"> <aa51 name="testExecuteNoParamsBinding with data set #0" assertions="3" time="0.010916"/> <aa52 name="testExecuteNoParamsBinding with data set #1" assertions="3" time="0.004554"/> <aa53 name="testExecuteNoParamsBinding with data set #1" assertions="3" time="0.004554"/> <aa54 name="testExecuteNoParamsBinding with data set #1" assertions="3" time="0.004554"/> </aa5> <aa6 name="DatabaseTest::testInsert" tests="5" assertions="7" failures="6" errors="0" time="0.014587"> <aa61 name="testExecuteNoParamsBinding with data set #0" assertions="3" time="0.010916"/> </aa6> <aa7 name="DatabaseTest::testBeginTransaction" tests="5" assertions="25" failures="4" errors="0" time="0.023787"> <aa71 name="testExecuteNoParamsBinding with data set #0" assertions="3" time="0.010916"/> </aa7> <aa6 name="DatabaseTest::testInsert" tests="5" assertions="7" failures="6" errors="0" time="0.014587"> <aa61 name="testExecuteNoParamsBinding with data set #0" assertions="3" time="0.010916"/> </aa6> <aa7 name="DatabaseTest::testBeginTransaction" tests="5" assertions="25" failures="4" errors="0" time="0.023787"> <aa71 name="testExecuteNoParamsBinding with data set #0" assertions="3" time="0.010916"/> </aa7> </aa2> <ab2 name="DatabaseTest" file="/Users/pfonseca/Dev/cintient/src/tests/DatabaseTest.php" tests="23" assertions="79" failures="0" errors="0" time="0.129403"> <ab6 name="DatabaseTest::testInsert" tests="5" assertions="7" failures="6" errors="0" time="0.018787"> <ab61 name="testExecuteNoParamsBinding with data set #0" assertions="3" time="0.010916"/> </ab6> <ab7 name="DatabaseTest::testBeginTransaction" tests="5" assertions="25" failures="4" errors="0" time="0.028787"> <ab71 name="testExecuteNoParamsBinding with data set #0" assertions="3" time="0.010916"/> </ab7> </ab2> </aa1> </aa> EOT; // // Access file testsuites directly (last level before testcases). // This can't be a closure because of its recursiveness. // function f($node) { if (isset($node->attributes()->file)) { return $node; } else { return f($node->children()); } } $xml = new SimpleXMLElement($xmlStr); $classes = array(); $xmls = $xml->children(); /* foreach ($xmls as $node) { $getRootNode = f($node); $classXml = f($node); $class = new TestClass(); $class->setName($classXml->getName()); $class->setFile((string)$classXml->attributes()->file); $class->setTests((string)$classXml->attributes()->tests); $class->setAssertions((string)$classXml->attributes()->assertions); $class->setFailures((string)$classXml->attributes()->failures); $class->setErrors((string)$classXml->attributes()->errors); $class->setTime((string)$classXml->attributes()->time); $methods = array(); foreach ($classXml->children() as $methodXml) { $method = new TestMethod(); $method->setName($methodXml->getName()); $method->setTests((string)$methodXml->attributes()->tests); $method->setAssertions((string)$methodXml->attributes()->assertions); $method->setFailures((string)$methodXml->attributes()->failures); $method->setErrors((string)$methodXml->attributes()->errors); $method->setTime((string)$methodXml->attributes()->time); $cases = array(); foreach ($methodXml->children() as $caseXml) { $case = new TestCase(); $case->setName((string)$caseXml->getName()); $case->setAssertions((string)$caseXml->attributes()->assertions); $case->setTime((string)$caseXml->attributes()->time); $cases[] = $case; } $method->setTestCases($cases); $methods[] = $method; } $class->setTestMethods($methods); $classes[] = $class; }*/ foreach ($xmls as $node) { $assertions = 0; // total number of "test" points $successes = array(); // assertions - failures $failures = array(); $testMethods = array(); $classXml = f($node); $class = new TestClass(); $class->setName($classXml->getName()); $class->setFile((string) $classXml->attributes()->file); $class->setTests((string) $classXml->attributes()->tests); $class->setAssertions((string) $classXml->attributes()->assertions); $class->setFailures((string) $classXml->attributes()->failures); $class->setErrors((string) $classXml->attributes()->errors); $class->setTime((string) $classXml->attributes()->time); $methods = array(); $i = 0; foreach ($classXml->children() as $methodXml) { $method = new TestMethod(); $method->setName($methodXml->getName()); $method->setTests((string) $methodXml->attributes()->tests); $method->setAssertions((string) $methodXml->attributes()->assertions); $method->setFailures((string) $methodXml->attributes()->failures); $method->setErrors((string) $methodXml->attributes()->errors); $method->setTime((string) $methodXml->attributes()->time); /* $cases = array(); foreach ($methodXml->children() as $caseXml) { $case = new TestCase(); $case->setName((string)$caseXml->getName()); $case->setAssertions((string)$caseXml->attributes()->assertions); $case->setTime((string)$caseXml->attributes()->time); $cases[] = $case; } $method->setTestCases($cases); */ $methods[] = $method; $time = (double) $methodXml->attributes()->time * 1000; // to milliseconds $testMethods[] = $methodXml->attributes()->name; $f = (double) $methodXml->attributes()->failures * $time / (double) $methodXml->attributes()->assertions; $successes[] = (double) $time - (double) $f; $failures[] = $f; $i++; } $chartWidth = 700; if ($i == 1) { $i++; } $chartHeight = 25 * $i + 60; /* pChart library inclusions */ include 'lib/pChart/class/pData.class'; include 'lib/pChart/class/pDraw.class'; include 'lib/pChart/class/pImage.class'; $MyData = new pData(); $MyData->addPoints($successes, "Ok"); $MyData->addPoints($failures, "Fail"); $MyData->setPalette("Ok", array("R" => 124, "G" => 196, "B" => 0, "Alpha" => 100)); $MyData->setPalette("Fail", array("R" => 254, "G" => 15, "B" => 0, "Alpha" => 100)); $MyData->setAxisName(0, "Time (ms)"); //$MyData->setAxisUnit(0,"ms"); $MyData->addPoints($testMethods, " "); $MyData->setAbscissa(" "); /* Create the pChart object */ // // ~40px for each test // $myPicture = new pImage($chartWidth, $chartHeight, $MyData); $myPicture->Antialias = false; $myPicture->drawGradientArea(0, 0, $chartWidth, $chartHeight, DIRECTION_VERTICAL, array("StartR" => 100, "StartG" => 100, "StartB" => 100, "EndR" => 50, "EndG" => 50, "EndB" => 50, "Alpha" => 100)); /* Write the picture title */ $myPicture->setFontProperties(array("FontName" => CINTIENT_INSTALL_DIR . "lib/pChart/fonts/pf_arma_five.ttf", "FontSize" => 6, "R" => 255, "G" => 255, "B" => 255)); $myPicture->drawText(10, 13, "Unit tests on " . $classXml->getName(), array("R" => 255, "G" => 255, "B" => 255)); /* Draw the scale and the chart */ $myPicture->setGraphArea(240, 40, 640, $chartHeight - 20); $myPicture->drawFilledRectangle(240, 40, 640, $chartHeight - 20, array("R" => 255, "G" => 255, "B" => 255, "Surrounding" => -100, "Alpha" => 10)); $myPicture->drawScale(array("Pos" => SCALE_POS_TOPBOTTOM, "Mode" => SCALE_MODE_ADDALL, "DrawSubTicks" => true, "MinDivHeight" => 20, 'GridTicks' => 2, 'DrawXLines' => true, 'DrawYLines' => ALL)); $myPicture->setShadow(TRUE, array("X" => 1, "Y" => 1, "R" => 0, "G" => 0, "B" => 0, "Alpha" => 10)); $myPicture->drawStackedBarChart(array("Interleave" => 2, "Gradient" => false)); $myPicture->drawLegend(15, $chartHeight - 15, array("Style" => LEGEND_NOBORDER, "Mode" => LEGEND_HORIZONTAL)); $myPicture->setShadow(FALSE); /* Write the chart legend */ //$myPicture->drawLegend(510,205,array("Style"=>LEGEND_NOBORDER,"Mode"=>LEGEND_HORIZONTAL)); /* Render the picture (choose the best way) */ $myPicture->autoOutput("pictures/example.drawStackedBarChart.png"); $class->setTestMethods($methods); $classes[] = $class; } // // We're exactly at the test class (file) root level, with level 1 being // the unit test (method of the original class) and level 2 being // the various datasets used in the test (each a test case). // /* @ 700x230 Stacked bar chart drawing example. */ exit; }
public function getViewData(array $params = array()) { $junitReportFile = $this->getPtrProjectBuild()->getBuildDir() . CINTIENT_JUNIT_REPORT_FILENAME; if (!is_file($junitReportFile)) { SystemEvent::raise(SystemEvent::ERROR, "Junit file not found. [PID={$this->getProjectId()}] [BUILD={$this->getProjectBuildId()}] [FILE={$junitReportFile}]", __METHOD__); return false; } try { $xml = new SimpleXMLElement($junitReportFile, 0, true); } catch (Exception $e) { SystemEvent::raise(SystemEvent::ERROR, "Problems processing Junit XML file. [PID={$this->getProjectId()}] [BUILD={$this->getProjectBuildId()}]", __METHOD__); return false; } // Apparently using call_user_func(__FUNCTION__) inside a closure, // doesn't work... Anyway I'm just going for a closure here, to // avoid the whole function definition crap here, inside a method. // // This closure takes a SimpleXMLElement loaded with the Junit report // and searches for the first element with a file attribute. That // level is the Class Test level, and what we want here is to iterate // over all class tests. $f = function ($node) use(&$parent, &$f) { if (isset($node->attributes()->file)) { return $parent->children(); } else { $parent = $node; return $f($node->children()); } }; $parent = $xml; $classTestsXml = $f($xml->children()); $classes = array(); foreach ($classTestsXml as $node) { $imageFilename = ''; $methodsNames = array(); $methods = array(); $class = new TestClass(); $class->setName((string) $node->attributes()->name); $class->setFile((string) $node->attributes()->file); $class->setTests((string) $node->attributes()->tests); $class->setAssertions((string) $node->attributes()->assertions); $class->setFailures((string) $node->attributes()->failures); $class->setErrors((string) $node->attributes()->errors); $class->setTime((string) $node->attributes()->time); $class->setChartFilename(md5($this->getProjectId() . $this->getProjectBuildId() . $class->getFile()) . '.png'); // Right here we're exactly at the test class (file) root level, // with level 1 being the unit test (method of the original class) // and level 2 being the various datasets used in the test (each a // test case). foreach ($node->children() as $methodXml) { $time = (double) $methodXml->attributes()->time * 1000; // to milliseconds $methodsNames[] = (string) $methodXml->attributes()->name; $f = (double) $methodXml->attributes()->failures * $time / (double) $methodXml->attributes()->assertions; $method = new TestMethod(); $method->setName((string) $methodXml->attributes()->name); $method->setTests((string) $methodXml->attributes()->tests); $method->setAssertions((string) $methodXml->attributes()->assertions); $method->setFailures((string) $methodXml->attributes()->failures); $method->setErrors((string) $methodXml->attributes()->errors); $method->setTime((string) $methodXml->attributes()->time); $method->setCalculatedOks((double) $time - (double) $f); $method->setCalculatedFaileds($f); $methods[] = $method; } $class->setTestMethods($methods); $classes[] = $class; } $ret = array(); $ret['project_buildJunit'] = $classes; return $ret; }