mirror of
https://github.com/moodle/moodle.git
synced 2025-04-21 16:32:18 +02:00
MDL-35479 debugging support in our phpunit integration
This commit is contained in:
parent
d3dbb5ce6a
commit
ef5b5e051e
@ -76,6 +76,11 @@ abstract class advanced_testcase extends PHPUnit_Framework_TestCase {
|
||||
parent::runBare();
|
||||
// set DB reference in case somebody mocked it in test
|
||||
$DB = phpunit_util::get_global_backup('DB');
|
||||
|
||||
// Deal with any debugging messages.
|
||||
phpunit_util::display_debugging_messages();
|
||||
phpunit_util::reset_debugging();
|
||||
|
||||
} catch (Exception $e) {
|
||||
// cleanup after failed expectation
|
||||
phpunit_util::reset_all_data();
|
||||
@ -234,6 +239,70 @@ abstract class advanced_testcase extends PHPUnit_Framework_TestCase {
|
||||
$this->resetAfterTest = $reset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return debugging messages from the current test.
|
||||
* @return array
|
||||
*/
|
||||
public function getDebuggingMessages() {
|
||||
return phpunit_util::get_debugging_messages();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all previous debugging messages in current test.
|
||||
* @return array
|
||||
*/
|
||||
public function resetDebugging() {
|
||||
return phpunit_util::reset_debugging();
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that exactly debugging was just called once.
|
||||
*
|
||||
* Discards the debugging message if successful.
|
||||
*
|
||||
* @param null|string $debugmessage null means any
|
||||
* @param null|string $debuglevel null means any
|
||||
* @param string $message
|
||||
*/
|
||||
public function assertDebuggingCalled($debugmessage = null, $debuglevel = null, $message = '') {
|
||||
$debugging = phpunit_util::get_debugging_messages();
|
||||
$count = count($debugging);
|
||||
|
||||
if ($count == 0) {
|
||||
if ($message === '') {
|
||||
$message = 'Expectation failed, debugging() not triggered.';
|
||||
}
|
||||
$this->fail($message);
|
||||
}
|
||||
if ($count > 1) {
|
||||
if ($message === '') {
|
||||
$message = 'Expectation failed, debugging() triggered '.$count.' times.';
|
||||
}
|
||||
$this->fail($message);
|
||||
}
|
||||
$this->assertEquals(1, $count);
|
||||
|
||||
$debug = reset($debugging);
|
||||
if ($debugmessage !== null) {
|
||||
$this->assertSame($debugmessage, $debug->message, $message);
|
||||
}
|
||||
if ($debuglevel !== null) {
|
||||
$this->assertSame($debuglevel, $debug->level, $message);
|
||||
}
|
||||
|
||||
phpunit_util::reset_debugging();
|
||||
}
|
||||
|
||||
public function assertDebuggingNotCalled($message = '') {
|
||||
$debugging = phpunit_util::get_debugging_messages();
|
||||
$count = count($debugging);
|
||||
|
||||
if ($message === '') {
|
||||
$message = 'Expectation failed, debugging() was triggered.';
|
||||
}
|
||||
$this->assertEquals(0, $count, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup after all tests are executed.
|
||||
*
|
||||
|
@ -133,4 +133,68 @@ abstract class database_driver_testcase extends PHPUnit_Framework_TestCase {
|
||||
phpunit_util::reset_all_data();
|
||||
parent::tearDownAfterClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return debugging messages from the current test.
|
||||
* @return array
|
||||
*/
|
||||
public function getDebuggingMessages() {
|
||||
return phpunit_util::get_debugging_messages();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all previous debugging messages in current test.
|
||||
* @return array
|
||||
*/
|
||||
public function resetDebugging() {
|
||||
return phpunit_util::reset_debugging();
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that exactly debugging was just called once.
|
||||
*
|
||||
* Discards the debugging message if successful.
|
||||
*
|
||||
* @param null|string $debugmessage null means any
|
||||
* @param null|string $debuglevel null means any
|
||||
* @param string $message
|
||||
*/
|
||||
public function assertDebuggingCalled($debugmessage = null, $debuglevel = null, $message = '') {
|
||||
$debugging = phpunit_util::get_debugging_messages();
|
||||
$count = count($debugging);
|
||||
|
||||
if ($count == 0) {
|
||||
if ($message === '') {
|
||||
$message = 'Expectation failed, debugging() not triggered.';
|
||||
}
|
||||
$this->fail($message);
|
||||
}
|
||||
if ($count > 1) {
|
||||
if ($message === '') {
|
||||
$message = 'Expectation failed, debugging() triggered '.$count.' times.';
|
||||
}
|
||||
$this->fail($message);
|
||||
}
|
||||
$this->assertEquals(1, $count);
|
||||
|
||||
$debug = reset($debugging);
|
||||
if ($debugmessage !== null) {
|
||||
$this->assertSame($debugmessage, $debug->message, $message);
|
||||
}
|
||||
if ($debuglevel !== null) {
|
||||
$this->assertSame($debuglevel, $debug->level, $message);
|
||||
}
|
||||
|
||||
phpunit_util::reset_debugging();
|
||||
}
|
||||
|
||||
public function assertDebuggingNotCalled($message = '') {
|
||||
$debugging = phpunit_util::get_debugging_messages();
|
||||
$count = count($debugging);
|
||||
|
||||
if ($message === '') {
|
||||
$message = 'Expectation failed, debugging() was triggered.';
|
||||
}
|
||||
$this->assertEquals(0, $count, $message);
|
||||
}
|
||||
}
|
||||
|
@ -57,6 +57,9 @@ class phpunit_util {
|
||||
/** @var resource used for prevention of parallel test execution */
|
||||
protected static $lockhandle = null;
|
||||
|
||||
/** @var array list of debugging messages triggered during the last test execution */
|
||||
protected static $debuggings = array();
|
||||
|
||||
/**
|
||||
* Prevent parallel test execution - this can not work in Moodle because we modify database and dataroot.
|
||||
*
|
||||
@ -544,6 +547,10 @@ class phpunit_util {
|
||||
public static function reset_all_data($logchanges = false) {
|
||||
global $DB, $CFG, $USER, $SITE, $COURSE, $PAGE, $OUTPUT, $SESSION, $GROUPLIB_CACHE;
|
||||
|
||||
// Show any unhandled debugging messages, the runbare() could already reset it.
|
||||
self::display_debugging_messages();
|
||||
self::reset_debugging();
|
||||
|
||||
// reset global $DB in case somebody mocked it
|
||||
$DB = self::get_global_backup('DB');
|
||||
|
||||
@ -1160,4 +1167,70 @@ class phpunit_util {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* To be called from debugging() only.
|
||||
* @param string $message
|
||||
* @param int $level
|
||||
* @param string $from
|
||||
*/
|
||||
public static function debugging_triggered($message, $level, $from) {
|
||||
// Store only if debugging triggered from actual test,
|
||||
// we need normal debugging outside of tests to find problems in our phpunit integration.
|
||||
$backtrace = debug_backtrace();
|
||||
|
||||
foreach ($backtrace as $bt) {
|
||||
$intest = false;
|
||||
if (isset($bt['object']) and is_object($bt['object'])) {
|
||||
if ($bt['object'] instanceof PHPUnit_Framework_TestCase) {
|
||||
if (strpos($bt['function'], 'test') === 0) {
|
||||
$intest = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!$intest) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$debug = new stdClass();
|
||||
$debug->message = $message;
|
||||
$debug->level = $level;
|
||||
$debug->from = $from;
|
||||
|
||||
self::$debuggings[] = $debug;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the list of debugging messages.
|
||||
*/
|
||||
public static function reset_debugging() {
|
||||
self::$debuggings = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all debugging messages triggered during test.
|
||||
* @return array with instances having message, level and stacktrace property.
|
||||
*/
|
||||
public static function get_debugging_messages() {
|
||||
return self::$debuggings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints out any debug messages accumulated during test execution.
|
||||
* @return bool false if no debug messages, true if debug triggered
|
||||
*/
|
||||
public static function display_debugging_messages() {
|
||||
if (empty(self::$debuggings)) {
|
||||
return false;
|
||||
}
|
||||
foreach(self::$debuggings as $debug) {
|
||||
echo 'Debugging: ' . $debug->message . "\n" . trim($debug->from) . "\n";
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -36,6 +36,40 @@ defined('MOODLE_INTERNAL') || die();
|
||||
*/
|
||||
class core_phpunit_advanced_testcase extends advanced_testcase {
|
||||
|
||||
public function test_debugging() {
|
||||
global $CFG;
|
||||
$this->resetAfterTest();
|
||||
|
||||
debugging('hokus');
|
||||
$this->assertDebuggingCalled();
|
||||
debugging('pokus');
|
||||
$this->assertDebuggingCalled('pokus');
|
||||
debugging('pokus', DEBUG_MINIMAL);
|
||||
$this->assertDebuggingCalled('pokus', DEBUG_MINIMAL);
|
||||
$this->assertDebuggingNotCalled();
|
||||
|
||||
debugging('a');
|
||||
debugging('b', DEBUG_MINIMAL);
|
||||
debugging('c', DEBUG_DEVELOPER);
|
||||
$debuggings = $this->getDebuggingMessages();
|
||||
$this->assertEquals(3, count($debuggings));
|
||||
$this->assertSame('a', $debuggings[0]->message);
|
||||
$this->assertSame(DEBUG_NORMAL, $debuggings[0]->level);
|
||||
$this->assertSame('b', $debuggings[1]->message);
|
||||
$this->assertSame(DEBUG_MINIMAL, $debuggings[1]->level);
|
||||
$this->assertSame('c', $debuggings[2]->message);
|
||||
$this->assertSame(DEBUG_DEVELOPER, $debuggings[2]->level);
|
||||
|
||||
$this->resetDebugging();
|
||||
$this->assertDebuggingNotCalled();
|
||||
$debuggings = $this->getDebuggingMessages();
|
||||
$this->assertEquals(0, count($debuggings));
|
||||
|
||||
$CFG->debug = DEBUG_NONE;
|
||||
debugging('hokus');
|
||||
$this->assertDebuggingNotCalled();
|
||||
}
|
||||
|
||||
public function test_set_user() {
|
||||
global $USER, $DB;
|
||||
|
||||
|
@ -2853,9 +2853,13 @@ function debugging($message = '', $level = DEBUG_NORMAL, $backtrace = null) {
|
||||
}
|
||||
$from = format_backtrace($backtrace, CLI_SCRIPT);
|
||||
if (PHPUNIT_TEST) {
|
||||
echo 'Debugging: ' . $message . "\n" . $from;
|
||||
if (phpunit_util::debugging_triggered($message, $level, $from)) {
|
||||
// We are inside test, the debug message was logged.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (NO_DEBUG_DISPLAY) {
|
||||
if (NO_DEBUG_DISPLAY) {
|
||||
// script does not want any errors or debugging in output,
|
||||
// we send the info to error log instead
|
||||
error_log('Debugging: ' . $message . $from);
|
||||
|
Loading…
x
Reference in New Issue
Block a user