I have a PHPUnit bootstrap file that creates a test DB used for DB-related unit tests, and registers a shutdown function to destroy the DB once the tests complete. A fresh database for every run!
The problem: when tests fail, I want to hold onto the database for debugging purposes. At present, I have to manually disable my register_shutdown_function()
call and then rerun the tests.
If I could access PHPUnit's final success/fail state for the run, I could dynamically trigger the database destruction process based on a switch within the PHPUnit bootstrap file.
PHPUnit stores this info somewhere in order to trigger the proper outcome event, i.e. the output OK
vs FAILURES!
. However from what I've uncovered, this information is not exposed to a user-level bootstrap file. Anyone ever done anything like this?
If you want to explore, here's a stack trace of PHPUnit that occurs when you run PHPUnit from the command line...
PHP 1. {main}() /usr/bin/phpunit:0
PHP 2. PHPUnit_TextUI_Command::main() /usr/bin/phpunit:46
PHP 3. PHPUnit_TextUI_Command->run() /usr/share/php/PHPUnit/TextUI/Command.php:130
PHP 4. PHPUnit_TextUI_Command->handleArguments() /usr/share/php/PHPUnit/TextUI/Command.php:139
PHP 5. PHPUnit_TextUI_Command->handleBootstrap() /usr/share/php/PHPUnit/TextUI/Command.php:620
PHP 6. PHPUnit_Util_Fileloader::checkAndLoad() /usr/share/php/PHPUnit/TextUI/Command.php:867
PHP 7. PHPUnit_Util_Fileloader::load() /usr/share/php/PHPUnit/Util/Fileloader.php:79
PHP 8. include_once() /usr/share/php/PHPUnit/Util/Fileloader.php:95
PHP 9. [YOUR PHPUNIT BOOTSTRAP RUNS HERE]
For accessing the state of PHPUnit test cases I usually recommend using:
See the docs: PHPUnit_Framework_TestListener
and how to add it to the xml config.
A small sample:
<listeners>
<listener class="DbSetupListener" file="/optional/path/to/DbSetupListener.php"/>
</listeners>
<?php
class DbSetupListener implements PHPUnit_Framework_TestListener {
private $setupHappend = false;
public function addError(PHPUnit_Framework_Test $test, Exception $e, $time) {
$this->error = true;
}
public function addFailure(PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time) {
$this->error = true;
}
public function addIncompleteTest(PHPUnit_Framework_Test $test, Exception $e, $time) { }
public function addSkippedTest(PHPUnit_Framework_Test $test, Exception $e, $time) { }
public function startTest(PHPUnit_Framework_Test $test) { }
public function endTest(PHPUnit_Framework_Test $test, $time) { }
public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
{
if(!$this->setupHappend) {
$this->setupDatabase();
$this->setupHappend = true;
}
}
public function endTestSuite(PHPUnit_Framework_TestSuite $suite) {
// If you have multiple test suites this is the wrong place to do anything
}
public function __destruct() {
if($this->error) {
// Something bad happend. Debug dump or whatever
} else {
// Teardown
}
}
}
This should get you going rather easy. If you need to only "listen" to specific tests
or testsuites
then you can use the parameters of startTest
and startTestSuite
.
Both objects have a getName()
method that gives you the name of the test suite and test case respectively.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With