How to do test driven develoment for Joomla components

Test Driven Development is very important to improve quality and reduces bugs in your code. In this article I will show you how to use TDD in developing Joomla component. First you have to install phpunit, you can find the details at here. In this article we will use Joomla article manager (com_content) component as an experiment, and this article is based on Joomla 3.2.0. Here are the steps:

1. Create a Test folder

Create a new folder called Tests on /joomlapath/administrator/components/com_content folder. This folder will contain all test files.

2. Create phpunit configuration file

Create a new file called phpunit.xml. we will use the following configurations for this experiment: 

3. Create a bootstrap file

Create a new file called bootstrap.php  in our Tests folder, we will use this bootstrap file to load the Joomla libraries so that we can run the component from our unit testing code. This bootstrap file is based on index.php file on administrator folder. We have to modify some codes so that it will work on our Tests folder. 

  • we should define _JEXEC in our bootstrap file so that we can use all php files on our Joomla installation because most Joomla files are protected from direct access using defined(‘_JEXEC’) or die; code
  • we should create fake $_SERVER[‘HTTP_HOST’] array and set the value to localhost because it’s used on /joomlapath/libraries/joomla/application/web.php on function detectRequestUri() and on /joomlapath/libraries/joomla/uri/uri.php on function getInstance()
  • we should define JPATH_COMPONENT because its used on /joomlapath/libraries/legacy/controller/legacy.php on class constructor
  • we should instantiated Joomla administrator application using JFactory::getApplication(‘administrator’) before we can use it on our unit test functions
  • we should include the controller file so that we can use ContentController class in our unit test

4. Test PHPUnit configuration and bootstrap file from command line

Open your command line or terminal and navigate to /joomlapath/administrator/components/com_content/Tests folder and type phpunit . [enter] and you should see this output.

PHPUnit configuration test 

If everything is working you will see phpunit output : No tests executed! since we haven’t created any test function.

5. Create a test file

Create a new file called ArticleTest.php, in this file we will test the functionality of article manager on the Joomla backend. As you can see on /joomlapath/administrator/components/com_content/models folder, Joomla com_content component has a model called articles. So in this experiment we will try to list all articles in your Joomla site. You can see it from testListArticles function below. 

as you can see from the code, first it instantiated the ContentController class and get the model ContentModelArticles using getModel function and then it gets all articles using getItems function. You should see the following output from phpunit.

PHPUnit list all articles test

6. Simulate HTTP request from unit test

You can simulate HTTP request using JInput class, for example we want to test the search functionality of article manager. We can set the value of filter_search property in JInput class using set function. Here is the complete function. 

In the above example we simulate the search article process by setting the value of filter_search property to ‘contact’.

Update January 11, 2014

7. Create, Update, Delete Document Test

Let’s continue to create a test for document saving process. We can see from Article Manager: Add New Article page, there are some fields that need to be filled which are Title and Category and these field name are jform[title] and jform[catid], you can use firebug to see the field name. And then lest create a new test function: testAddDocument :

If you run phpunit you will get this output: ,


Its happen when we try to create a new article without login to Joomla system, so Joomla can’t find a user in the active session. Joomla also checks the token of the posted form using JSession::checkToken(). Let’s add this code to our bootstrap file to register a user in joomla session and by pass JSession::checkToken() validation .

 run phpunit again and you’ll get this error:

Lets fix this by adding this code to our bootstrap file

let’s run phpunit again and you will get all tests passed. Now lets create a test function for update article process: testUpdateArticle. This new function will depends on the previous testAddDocument function, that’s why we need to modify postSaveHook function of ContentControllerArticle class in order to track the last added article.

and our testAddArticle function will become:

Our testUpdateArticle will use article created from testAddArticle function, and modify the title of the article from ‘test document’ to ‘test document 2’. Here is the testUpdateArticle function code:

You need to delete ‘test document’ article created by testAddArticle function before running phpunit. Run phpunit and you should get all tests passed. Now we will create a test function for Trash article process called testTrashArticle, this function will depends on testAddArticle function. Here is the testTrashArticle function:

you should delete ‘test document 2’ article from Article Manager: Articles page before running phpunit again. After you run phpunit you should get all tests passed and the article ‘test document 2’ status changed to Trashed. Now lets create a test function for delete article process called: testDeleteArticle. This function will depends on testTrashArticle function and here is the code:

and as usual you should delete ‘test document 2’ article from Article Manager: Articles page before running phpunit again. After you run phpunit again you should get all tests passed and you won’t find ‘test document 2’ article on Article Manager: Articles page.

Update June 14, 2014

There are some issues if you run these tests using PHP version > 5.3.x, thanks to valekcrow and angelvperez. You will get this error message if you run phpunit . in command line

I think it is because the PHPUnit modify $_GLOBAL variable for each test function, you can read the description in here You can fix this problem by moving the following code from bootstrap.php to setUp function in ArticleTest.php.

You can see the complete code of bootstrap.php and ArticleTest.php file below


 and ArticleTest.php file

You should run this test using phpunit –stderr . to direct phpunit’s output to stderr,

 That’s it. I hope from now on we can use TDD in our joomla component development process.

Leave a Comment

Your email address will not be published. Required fields are marked *