GitBucket
4.21.2
Toggle navigation
Snippets
Sign in
Files
Branches
1
Releases
Issues
Pull requests
Labels
Priorities
Milestones
Wiki
Forks
nigel.stanger
/
sqlmarker
Browse code
Added per-test counters on top of per-suite.
master
1 parent
0eccaa4
commit
51282aa7be9b1f1d87cd9e842a3da4dd70f2f94d
Nigel Stanger
authored
on 28 Jun 2013
Patch
Showing
2 changed files
Unit_testing/SimpleTestListener.php
Unit_testing/test.php
Ignore Space
Show notes
View
Unit_testing/SimpleTestListener.php
<?php class SimpleTestListener implements PHPUnit_Framework_TestListener { /** * When you're running test suites, the various count methods in TestResult return only the total number of tests, fails, etc., for the entire Test, even if you filter the tests to be run within a given suite. We therefore need to keep track of these within the test listener for each suite and test. The results are indexed by suite/test name, which will be something like "BDL_Test_Staff_structure::testFoo"/"testFoo". */ private $passes = array(); private $fails = array(); private $errors = array(); private $incompletes = array(); private $skips = array(); private $tests = array(); /** * These keep track of the counts within a given suite execution, and are reset at the start of every new suite. I'm not sure whether nested suites are stored as actual TestSuite objects. If not, this could mean that the counts for the enclosing suites may be wrong? */ private $suitePassCount = 0; private $suiteFailCount = 0; private $suiteErrorCount = 0; private $incompleteCount = 0; private $suiteSkipCount = 0; private $suiteTestCount = 0; public function countPasses( $name ) { return $this->passes[ $name ]; } public function countFails( $name ) { return $this->fails[ $name ]; } public function countErrors( $name ) { return $this->errors[ $name ]; } public function countIncompletes( $name ) { return $this->incompletes[ $name ]; } public function countSkips( $name ) { return $this->skips[ $name ]; } public function countTests( $name ) { return $this->tests[ $name ]; } public function wasSuccessful( $name ) { return ( $this->countPasses( $name ) === $this->countTests( $name ) ); } public function addError(PHPUnit_Framework_Test $test, Exception $e, $time) { echo "ERROR! " . $e->getMessage() . "\n"; $this->suiteErrorCount++; $this->errors[ $test->getName() ] = 1; } public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time) { echo "FAILED! " . $e->getMessage() . "\n"; $this->suiteFailCount++; $this->fails[ $test->getName() ] = 1; } public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time) { echo "INCOMPLETE: " . $e->getMessage() . "\n"; $this->incompleteCount++; $this->incompletes[ $test->getName() ] = 1; } public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time) { echo "SKIPPED: " . $e->getMessage() . "\n"; $this->suiteSkipCount++; $this->skips[ $test->getName() ] = 1; } public function startTest(PHPUnit_Framework_Test $test) { // printf("@@@ Test '%s' started.\n", $test->getName()); $this->suiteTestCount++; $this->tests[ $test->getName() ] = 1; } public function endTest(PHPUnit_Framework_Test $test, $time) { // printf("@@@ Test '%s' ended.\n", $test->getName()); if ( $test->getStatus() === PHPUnit_Runner_BaseTestRunner::STATUS_PASSED ) { echo "OK\n"; $this->suitePassCount++; $this->passes[ $test->getName() ] = 1; } } public function startTestSuite(PHPUnit_Framework_TestSuite $suite) { // printf("@@@ TestSuite '%s' started.\n", $suite->getName()); $this->suitePassCount = $this->suiteFailCount = $this->suiteErrorCount = $this->incompleteCount = $this->suiteSkipCount = $this->suiteTestCount = 0; } public function endTestSuite(PHPUnit_Framework_TestSuite $suite) { // printf("@@@ TestSuite '%s' ended.\n", $suite->getName()); $this->passes[ $suite->getName() ] = $this->suitePassCount; $this->fails[ $suite->getName() ] = $this->suiteFailCount; $this->errors[ $suite->getName() ] = $this->suiteErrorCount; $this->incompletes[ $suite->getName() ] = $this->incompleteCount; $this->skips[ $suite->getName() ] = $this->suiteSkipCount; $this->tests[ $suite->getName() ] = $this->suiteTestCount; } } ?>
<?php class SimpleTestListener implements PHPUnit_Framework_TestListener { /** * When you're running test suites, the various count methods in TestResult return only the total number of tests, fails, etc., for the entire Test, even if you filter the tests to be run within a given suite. We therefore need to keep track of these within the test listener for each suite. The results are indexed by suite name, which will be something like "BDL_Test_Staff_structure::testFoo". */ private $passes = array(); private $fails = array(); private $errors = array(); private $incompletes = array(); private $skips = array(); private $tests = array(); /** * These keep track of the counts within a given suite execution, and are reset at the start of every new suite. I'm not sure whether nested suites are stored as actual TestSuite objects. If not, this could mean that the counts for the enclosing suites may be wrong? */ private $passCount = 0; private $failCount = 0; private $errorCount = 0; private $incompleteCount = 0; private $skipCount = 0; private $testCount = 0; public function countPasses( $suiteName ) { return $this->passes[ $suiteName ]; } public function countFails( $suiteName ) { return $this->fails[ $suiteName ]; } public function countErrors( $suiteName ) { return $this->errors[ $suiteName ]; } public function countIncompletes( $suiteName ) { return $this->incompletes[ $suiteName ]; } public function countSkips( $suiteName ) { return $this->skips[ $suiteName ]; } public function countTests( $suiteName ) { return $this->tests[ $suiteName ]; } public function addError(PHPUnit_Framework_Test $test, Exception $e, $time) { echo "ERROR! " . $e->getMessage() . "\n"; $this->errorCount++; } public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time) { echo "FAILED! " . $e->getMessage() . "\n"; $this->failCount++; } public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time) { echo "INCOMPLETE: " . $e->getMessage() . "\n"; $this->incompleteCount++; } public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time) { echo "SKIPPED: " . $e->getMessage() . "\n"; $this->skipCount++; } public function startTest(PHPUnit_Framework_Test $test) { // printf("Test '%s' started.\n", $test->getName()); $this->testCount++; } public function endTest(PHPUnit_Framework_Test $test, $time) { // printf("Test '%s' ended.\n", $test->getName()); if ( $test->getStatus() === PHPUnit_Runner_BaseTestRunner::STATUS_PASSED ) { echo "OK\n"; $this->passCount++; } } public function startTestSuite(PHPUnit_Framework_TestSuite $suite) { // printf("TestSuite '%s' started.\n", $suite->getName()); $this->passCount = $this->failCount = $this->errorCount = $this->incompleteCount = $this->skipCount = $this->testCount = 0; } public function endTestSuite(PHPUnit_Framework_TestSuite $suite) { // printf("TestSuite '%s' ended.\n", $suite->getName()); $this->passes[ $suite->getName() ] = $this->passCount; $this->fails[ $suite->getName() ] = $this->failCount; $this->errors[ $suite->getName() ] = $this->errorCount; $this->incompletes[ $suite->getName() ] = $this->incompleteCount; $this->skips[ $suite->getName() ] = $this->skipCount; $this->tests[ $suite->getName() ] = $this->testCount; } } ?>
Ignore Space
Show notes
View
Unit_testing/test.php
<?php require_once "PHPUnit/Autoload.php"; require_once 'SimpleTestListener.php'; require_once "BDL_Test_Staff_structure.php"; require_once "BDL_Test_Staff_data.php"; $result = new PHPUnit_Framework_TestResult; $listener = new SimpleTestListener; $result->addListener( $listener ); $suite = new PHPUnit_Framework_TestSuite( 'BDL_Test_Staff_structure' ); // Critical to data testing. $testResult = $suite->run( $result, '/testTableExists/' ); if ( $listener->wasSuccessful( 'testTableExists' ) ) { echo ">>> Table exists.\n"; // Critical to data testing. $testResult = $suite->run( $result, '/testColumnExists/' ); if ( $listener->wasSuccessful( 'BDL_Test_Staff_structure::testColumnExists' ) ) { echo ">>> Table contains all the expected columns.\n"; $testResult = $suite->run( $result, '/testColumnDataType/' ); if ( $listener->wasSuccessful( 'BDL_Test_Staff_structure::testColumnDataType' ) ) echo ">>> All columns have the expected data types.\n"; $testResult = $suite->run( $result, '/testColumnLength/' ); if ( $listener->wasSuccessful( 'BDL_Test_Staff_structure::testColumnLength' ) ) echo ">>> All columns have the expected lengths.\n"; $testResult = $suite->run( $result, '/testColumnNullability/' ); if ( $listener->wasSuccessful( 'BDL_Test_Staff_structure::testColumnNullability' ) ) echo ">>> All columns have the expected nullability.\n"; } // Not critical to data testing. $testResult = $suite->run( $result, '/testPK.*/' ); if ( $listener->wasSuccessful( 'testPKExists' ) ) { echo ">>> Primary key exists.\n"; } if ( $listener->wasSuccessful( 'testPKColumns' ) ) { echo ">>> Primary key includes only the expected columns.\n"; } // Not critical to data testing. $testResult = $suite->run( $result, '/testConstraintsNamed/' ); if ( $listener->wasSuccessful( 'BDL_Test_Staff_structure::testConstraintsNamed' ) ) echo ">>> All constraints that should be are explicitly named.\n"; } /* If the table or required columns are missing or misnamed, we need to skip the data testing entirely, as the INSERTs will just error out. We can't incorporate this into the if above, because we're using a completely different test suite. */ if ( ( $listener->wasSuccessful( 'testTableExists' ) ) && ( $listener->wasSuccessful( 'BDL_Test_Staff_structure::testColumnExists' ) ) ) { $suite = new PHPUnit_Framework_TestSuite( 'BDL_Test_Staff_data' ); $testResult = $suite->run( $result, '/testColumnLegalValue/' ); if ( $listener->wasSuccessful( 'BDL_Test_Staff_data::testColumnLegalValue' ) ) { printf( ">>> All %d legal values tested were accepted.\n", $listener->countTests( 'BDL_Test_Staff_data::testColumnLegalValue' ) ); } $testResult = $suite->run( $result, '/testColumnIllegalValueExplicit/' ); if ( $listener->wasSuccessful( 'BDL_Test_Staff_data::testColumnIllegalValueExplicit' ) ) { printf( ">>> All %d illegal values tested were rejected by a CHECK constraint.\n", $listener->countTests( 'BDL_Test_Staff_data::testColumnIllegalValueExplicit' ) ); } else { $checkFails = $listener->countFails( 'BDL_Test_Staff_data::testColumnIllegalValueExplicit' ); printf( ">>> %d of %d illegal values tested %s not rejected by a CHECK constraint.\n", $checkFails, $listener->countTests( 'BDL_Test_Staff_data::testColumnIllegalValueExplicit' ), ( $checkFails > 1 ) ? "were" : "was" ); echo ">>> Checking values against column length...\n"; /* Unfortunately, we can't test just the columns that failed the CHECK test. The failed TestCases are in $testResult->failures(), but we need the column name, which is hidden away in the private $data member of TestCase. We therefore have to test all the illegal values again to see if they're larger than the column. We then make the big assumption that if all the values that failed the CHECK test did so because they exceeded the column length. If this is correct, then the number of CHECK fails will equal the number of column length passes. If not, then something more serious has probably gone wrong! */ $testResult = $suite->run( $result, '/testColumnIllegalValueImplicit/' ); $implicitPasses = $listener->countPasses( 'BDL_Test_Staff_data::testColumnIllegalValueImplicit' ); printf( ">>> %d of %d illegal values tested %s rejected by exceeding the column length.\n", $implicitPasses, $listener->countTests( 'BDL_Test_Staff_data::testColumnIllegalValueImplicit' ), ( $implicitPasses > 1 ) ? "were" : "was" ); // Any leftovers? if ( $implicitPasses != $checkFails ) { /* $checkFails must by definition be >= $implicitPasses, as a "length exceeded" will /always/ fail the CHECK test, and a "check constraint" will /always/ fail the column length test. The two values will only differ when there are other exceptions in the mix, which will fail both tests. For example, suppose that two values fail the CHECK test with "length exceeded", one fails with "foo exception" and the remaining two pass. The first two will pass the column length test, and the remaining three will fail. */ printf( ">>> %d illegal values %s were rejected in both tests—check for something unusual.\n", $checkFails - $implicitPasses, ( ( $checkFails - $implicitPasses ) > 1 ) ? "were" : "was" ); } else { echo ">>> This is OK, but not necessarily safe, as the column length may change in future.\n"; } } } ?>
<?php require_once "PHPUnit/Autoload.php"; require_once 'SimpleTestListener.php'; require_once "BDL_Test_Staff_structure.php"; require_once "BDL_Test_Staff_data.php"; $result = new PHPUnit_Framework_TestResult; $listener = new SimpleTestListener; $result->addListener( $listener ); $suite = new PHPUnit_Framework_TestSuite( 'BDL_Test_Staff_structure' ); $testresult = $suite->run( $result, '/testTableExists/' ); if ( $testresult->wasSuccessful() ) { echo ">>> Table exists.\n"; $testresult = $suite->run( $result, '/testColumnExists/' ); if ( $testresult->wasSuccessful() ) { echo ">>> Table contains all the expected columns.\n"; $testresult = $suite->run( $result, '/testColumnDataType/' ); if ( $testresult->wasSuccessful() ) echo ">>> All columns have the expected data types.\n"; $testresult = $suite->run( $result, '/testColumnLength/' ); if ( $testresult->wasSuccessful() ) echo ">>> All columns have the expected lengths.\n"; $testresult = $suite->run( $result, '/testColumnNullability/' ); if ( $testresult->wasSuccessful() ) echo ">>> All columns have the expected nullability.\n"; } $testresult = $suite->run( $result, '/testPK.*/' ); if ( $testresult->wasSuccessful() ) { echo ">>> Primary key exists and includes only the expected columns.\n"; } $testresult = $suite->run( $result, '/testConstraintsNamed/' ); if ( $testresult->wasSuccessful() ) echo ">>> All constraints that should be are explicitly named.\n"; } $suite = new PHPUnit_Framework_TestSuite( 'BDL_Test_Staff_data' ); $testresult = $suite->run( $result, '/testColumnLegalValue/' ); if ( $testresult->wasSuccessful() ) { printf( ">>> All %d legal values tested were accepted.\n", $listener->countTests( 'BDL_Test_Staff_data::testColumnLegalValue' ) ); } $testresult = $suite->run( $result, '/testColumnIllegalValueExplicit/' ); if ( $testresult->wasSuccessful() ) { printf( ">>> All %d illegal values tested were rejected by a CHECK constraint.\n", $listener->countTests( 'BDL_Test_Staff_data::testColumnIllegalValueExplicit' ) ); } else { $checkFails = $listener->countFails( 'BDL_Test_Staff_data::testColumnIllegalValueExplicit' ); printf( ">>> %d of %d illegal values tested %s not rejected by a CHECK constraint.\n", $checkFails, $listener->countTests( 'BDL_Test_Staff_data::testColumnIllegalValueExplicit' ), ( $checkFails > 1 ) ? "were" : "was" ); echo ">>> Checking values against column length...\n"; /* Unfortunately, we can't test just the columns that failed the CHECK test. The failed TestCases are in $testresult->failures(), but we need the column name, which is hidden away in the private $data member of TestCase. We therefore have to test all the illegal values again to see if they're larger than the column. We then make the big assumption that if all the values that failed the CHECK test did so because they exceeded the column length. If this is correct, then the number of CHECK fails will equal the number of column length passes. If not, then something more serious has probably gone wrong! */ $testresult = $suite->run( $result, '/testColumnIllegalValueImplicit/' ); $implicitPasses = $listener->countPasses( 'BDL_Test_Staff_data::testColumnIllegalValueImplicit' ); printf( ">>> %d of %d illegal values tested %s rejected by exceeding the column length.\n", $implicitPasses, $listener->countTests( 'BDL_Test_Staff_data::testColumnIllegalValueImplicit' ), ( $implicitPasses > 1 ) ? "were" : "was" ); // Any leftovers? if ( $implicitPasses != $checkFails ) { /* $checkFails must by definition be >= $implicitPasses, as a "length exceeded" will /always/ fail the CHECK test, and a "check constraint" will /always/ fail the column length test. The two values will only differ when there are other exceptions in the mix, which will fail both tests. For example, suppose that two values fail the CHECK test with "length exceeded", one fails with "foo exception" and the remaining two pass. The first two will pass the column length test, and the remaining three will fail. */ printf( ">>> %d illegal values %s were rejected in both tests—check for something unusual.\n", $checkFails - $implicitPasses, ( ( $checkFails - $implicitPasses ) > 1 ) ? "were" : "was" ); } else { echo ">>> This is OK, but not necessarily safe, as the column length may change in future.\n"; } // $lengthPasses = } ?>
Show line notes below