Testing Databases, streams and files with PHPT

Writing PHPT tests is pretty easy to learn. Basically, you execute php code, and define what output is expected from the code. That’s fine for testing string manipulating functions or some other basic function, but what do you do if databases or streams need to be tested? What if you need files or directories to execute code upon?

For databases, things can either be a bit difficult or not. Testing MySQL functionality is still a bit difficult, currently this is done mostly by fetching environment variables. You can set variables for MYSQL_TEST_HOST, MYSQL_TEST_PORT, MYSQL_TEST_USER, MYSQL_TEST_PASSWD, MYSQL_TEST_ENGINE, MYSQL_TEST_SOCKET to define connection parameters for your MySQL tests (for PDO_MYSQL they’re named a bit different, but you get the idea). An example of getting the hostname is:

$host = getenv("MYSQL_TEST_HOST") ? getenv("MYSQL_TEST_HOST") : "localhost";

Testing sqlite on the other hand is a whole lot easier. If you know that sqlite supports in-memory databases, you can pretty much get everything tested without a database dependency or files on the filesystem. Just open the database handle like this:

// procedural
$db = sqlite_open(':memory:');
// or OO-style
$db = new SQLiteDatabase(':memory:');

PHP streams are a similar subject when it comes to PHPT testing. If you want to test functions that interact with a stream handler, just use the php://memory built-in stream, like this:

$fp = fopen("php://memory", "r+");
// Now just use it as a regular PHP stream
fwrite($fp, "foobar");

If you do need to create files or directories for testing (for example for testing the SPL DirectoryIterator classes), best is to create them in the directory where the tests are located. Give them a descriptive name, and be sure to clean up after you’re done! This is done with a --CLEAN-- section in a PHPT test. Remember that the --FILE-- and --CLEAN-- parts of a PHPT test are called totally separate, so any variables that live in the --FILE-- part are lost in the --CLEAN-- part. This is an example to make it all a bit more clear:

Test is_file() function: basic functionality