Yesterday I thought I’d move one project over to using phing (with the end goal of hopefully getting some sort of Continuous Integration setup in place, with graphs and stuff to show the customer).
All went reasonably well – svn update, php documentation generation, php code sniffer tasks etc were all in place. Unfortunately when I got to do the unit tests (simpletest) things failed, and it seemed to be the case that no global variables in use within the code base were available. As my brain finally realised why this is the case this morning, I thought I’d better write a blog post in the hope it may help someone else in the future.
The code base itself is ‘legacy’ – in that it’s been pulled in different directions over the years before we got our hands on it. There’s bits of procedural code (e.g. query(..) which seems to just be the same as calling mysql_query(..)) and object oriented ($db->query(..)). Mixed in with this is a liberal use of global variables (e.g. $db, $database_name, $software_root and so on).
My unit tests, when run via a script on the command line look like :
<?php require_once('common.php'); require_once('simpletest/reporter.php'); require_once('simpletest/unit_tester.php'); $test = new GroupTest('my tests'); $test->addTestFile('WhateverTest.php'); $test->addTestFile('FooTest.php'); exit($test->run(new TextReporter()) ? 0 : 1);
And worked fine.
Within the code base, there is one include file within the application which defines a number of variables, on the assumption it’s at the top level scope – e.g.
$database_name = "blahblah_live"; $db = new Database($database_name, $database_username, $database_password, $database_host);
Which works fine. However, because $db hasn’t been explicitly defined as a global variable, when the tests are run through phing – they run within the scope of a function, and hence the global variables aren’t available (because they’ve not been implicitly registered as globals – the code just makes an assumption that they are).
So, to fix it, I just need to find all the variables defined in the script, and make them explicitly global.
global $db; global $database_name $database_name = "whatever"; $db = new Database(.....);
One step closer; perhaps soon I’ll be posting about getting Xinc or something similar working.