4月
8
2008
分類:
最近更新:
2008-04-08
PHPUnit 自定 TestSuite 輸出樣式,輸出為 HTML 網頁
PHPUnit 預置了一個純文字型式的 TextUI Runner,在大多數情形下,它足夠應付我們的需求。不過,當我想要把 TestSuite 放到專案網頁上,讓小組成員 - 特別是 PM - 可以上網查看立即的測試結果時,那個文字型式的 TextUI Runner 就顯得太簡略了。至少要把測試工作及結果輸出成 HTML 的條列式清單,最好還加上顏色區別成功或失敗。
所幸 PHPUnit 提供了良好的擴充性,要自定一個可以將測試內容輸出為 HTML 網頁的 HTML Runner 相當簡單。
自定輸出樣式的方法很多,我選擇透過擴展 PHPUnit_Framework_TestListener 來實現。See also: Implement PHPUnit_Framework_TestListener.
另一方面,我將測試案例清單放置在另一個檔案中。在本例中,測試案例清單之文件名稱為 UnitTestSuiteList.php。
<?php
/**
* 測試案例清單。
*/
$testCases = array(
'AbcTest.php',
'XyzTest.php'
);
?>
HTML Runner, UnitTestSuite.php
<?php
if (!defined('PHPUnit_MAIN_METHOD')) {
define('PHPUnit_MAIN_METHOD', '');
}
//測試案例清單
require_once 'UnitTestSuiteList.php';
require_once 'PHPUnit/Framework.php';
class HtmlTestListener implements PHPUnit_Framework_TestListener {
protected $lastTestStatus;
private function _name(PHPUnit_Framework_Test $test)
{
$name = $test->getName();
if (preg_match_all('/[A-Z][a-z0-9]+/', $name, $words)) {
$words = $words[0];
$showName = array_shift($words);
foreach ($words as $word) {
$showName .= ' ' . strtolower($word);
}
return $showName;
}
return $name;
}
public function addError(PHPUnit_Framework_Test $test,
Exception $e,
$time)
{
$this->lastTestStatus = 'e';
}
public function addFailure(PHPUnit_Framework_Test $test,
PHPUnit_Framework_AssertionFailedError $e,
$time)
{
$this->lastTestStatus = 'f';
}
public function addIncompleteTest(PHPUnit_Framework_Test $test,
Exception $e,
$time)
{
$this->lastTestStatus = 'i';
}
public function addSkippedTest(PHPUnit_Framework_Test $test,
Exception $e,
$time)
{
$this->lastTestStatus = 's';
}
public function startTest(PHPUnit_Framework_Test $test)
{
$this->lastTestStatus = 'p'; //pass
}
public function endTest(PHPUnit_Framework_Test $test, $time)
{
echo '<li>[';
switch ( $this->lastTestStatus ) {
case 'e':
echo '<span class="error">E</span>';
break;
case 'f':
echo '<span class="failure">F</span>';
break;
case 'i':
echo '<span class="incomplete">I</span>';
break;
case 's':
echo '<span class="skipped">S</span>';
break;
default:
echo '<span class="pass">P</span>';
break;
}
echo ']', $this->_name($test), "</li>\n";
}
public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
{
if ('' != $suite->getName())
printf("<div class='test_suite'>%s:</div><ul>\n", $suite->getName());
}
public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
{
if ('' != $suite->getName())
printf("</ul></div>\n");
}
}
?>
<style type="text/css">
.pass,
.error,
.failure,
.incomplete,
.skipped {
font-family: monospace, courier;
}
.pass {
background-color: #00cc00;
}
.error {
background-color: #CC0000;
}
.failure {
background-color: red;
}
.incomplete {
background-color: #ffff99;
}
.skipped {
background-color: #CCFFCC;
}
</style>
<div>
[<span class="pass">P</span>]: Pass;
[<span class="failure">F</span>]: Failure;
[<span class="incomplete">I</span>]: Incomplete;
[<span class="skipped">S</span>]: Skipped;
[<span class="error">E</span>]: Error.
</div>
<hr/>
<?php
$suite = new PHPUnit_Framework_TestSuite;
$result = new PHPUnit_Framework_TestResult;
$result->addListener(new HtmlTestListener);
foreach ($testCases as $testCase) {
require_once $testCase;
preg_match('/\/(\w+)\.php$/', $testCase, $matches);
$testCaseClassName = $matches[1];
$suite->addTestSuite($testCaseClassName);
}
// Run the tests.
echo '<p>Start. Timestamp:', date('Y-m-d h:i:s'), '</p>';
$suite->run($result);
echo '<div><pre>';
if ($result->wasSuccessful() &&
$result->allCompletlyImplemented() &&
$result->noneSkipped())
{
printf(
"\nOK (%d test%s)\n",
count($result),
(count($result) == 1) ? '' : 's'
);
}
else if ((!$result->allCompletlyImplemented() ||
!$result->noneSkipped())&&
$result->wasSuccessful())
{
printf(
"\nOK, but incomplete or skipped tests!\n" .
" Tests: %d \n Incomplete: %s \n Skipped: %s.\n",
count($result),
$result->notImplementedCount(),
$result->skippedCount()
);
}
else
{
printf(
"\nFAILURES!\n" .
" Tests: %d \n Failures: %s \n Errors: %s \n Incomplete: %s \n Skipped: %s.\n",
count($result),
$result->failureCount(),
$result->errorCount(),
$result->notImplementedCount(),
$result->skippedCount()
);
}
echo '</pre></div>';
echo '<p>End. Timestamp:', date('Y-m-d h:i:s'), '</p>';
?>

樂多舊網址: http://blog.roodo.com/rocksaying/archives/5829661.html
樂多舊回應