Getting started with Silverstripe unit testing (on ubuntu)

After many years of working with Silverstripe and developing modules, we have finally decided to move properly into unit testing.

This however is not without it's pitfalls. Just getting a project setup to make use of Silverstripes test suite can be a little complex for the newcomer.

This tutorial brings together information from several places, but the 2 most important are:

 

Step 1: PHP Unit

First off, before we can start running any tests we must install PHPUnit. The docs go through this in some detail, I opted to install it globally using PEAR.

In order to install PEAR on Ubuntu I had to run

sudo apt-get install php-pear

Once PEAR was installed, I could then use it to install PHPUnit (as per Silverstripe's docs) using:

sudo pear config-set auto_discover 1
sudo pear install pear.phpunit.de/PHPUnit

Step 2: Install Dependencies

With PHPUnit installed, we are ready to do unit testing, but in order to make the most of Silverstripe unit testing, we really need to install some extra php extensions.

PHP Tidy

On ubuntu this was easy enough to install via

 sudo apt-get install php5-tidy

SQLite

I wanted to use sqlite as my database engine when running tests, as Mysql can end up using A LOT of system resources. Installing it wasn't initially obvious, but I got it installed using the following:

sudo apt-get install sqlite
sudo apt-get install php5-sqlite

sqlite silverstripe module

In order to make use of SQLite, we have to install the silverstripe connector module. You can download this from github or if you are using composer, it is available on packagist:

composer require "silverstripe/sqlite3:*"

step 3: configure Silverstripe

Now we have everything up, we need to make sure we have everything configured to run.

phpunit.xml

This needs to be in your project root. If you do not have a phpunit.xml file, you can download it from the silverstripe-installer on github.

Inside the xml file you can define the modules you want to run tests, using the testsuite element. For example:

<testsuite name="Default">
    <directory>mysite/tests</directory>
    <directory>cms/tests</directory>
    <directory>framework/tests</directory>
    <directory>blog/tests</directory>
</testsuite>

Just add new "directory" elements for each module you want to run tests on.

php memory limit

I needed to increase the allowed memory limit PHP can use. On Ubuntu there are 2 php.ini files (one for apache and one for CLI). These are located at:

/etc/php5/apache2/php.ini
/etc/php5/cli/php.ini

You need to change the memory_limit setting to be higher, otherwise phpunit will fail, I set mine to 256M which seemed to work, but you might need more:

memory_limit = 256M

set sqlite as database in environmental config

Finally, I added a check to my _ss_environment.php file to see if we are trying to run tests (thanks to Jedateach at http://www.burnbright.net/ for this snippet of code).

//change database for testing only & allow forcing mysql via get parameter
if(!isset($_REQUEST['forcemysql']) && !defined('SS_DATABASE_CLASS')){
    $istest =
    (isset($_SERVER['REQUEST_URI']) && strpos($_SERVER['REQUEST_URI'], '/dev/tests') !== false) ||
    (isset($_SERVER['argv']) && isset($_SERVER['argv'][1]) && strpos($_SERVER['argv'][1], 'dev/tests') === 0) ||
    class_exists("PHPUnit_Runner_Version");

    if($istest)
        define('SS_DATABASE_CLASS', 'SQLite3Database');
}

step 4: run some tests!

After all that, you should now be able to run some tests. You can do this either by runing phpunit from the command line:

phpunit
phpunit framework/tests

Or, in the browser via:

http://www.yoursite.com/dev/tests/

 Good Luck!