<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://docs.sandbox.joomla.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Jedbox</id>
	<title>Joomla! Documentation - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://docs.sandbox.joomla.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Jedbox"/>
	<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/Special:Contributions/Jedbox"/>
	<updated>2026-05-15T13:35:30Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.0</generator>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Unit_Test_Tutorial_1&amp;diff=28066</id>
		<title>Unit Test Tutorial 1</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Unit_Test_Tutorial_1&amp;diff=28066"/>
		<updated>2010-05-25T06:04:40Z</updated>

		<summary type="html">&lt;p&gt;Jedbox: /* Link to Tutorial Part 2 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Unit Testing and Joomla! =&lt;br /&gt;
&lt;br /&gt;
As we move forward with Joomla! Development one element that is going to be playing a larger and larger role is unit testing.  My hope with this short series is to provide some basic background on unit testing, to demonstrate how essential unit tests are to stable software and to give practical instruction and examples that illustrate how to write unit tests.&lt;br /&gt;
&lt;br /&gt;
As co-maintainer of the Joomla! Bug Squad, there is a question that repeatedly pops up: &#039;What is this change going to break?&#039;.  There are certain elements of the code base that can be rather fragile and this makes it very difficult to know what things are safe to touch and what things aren&#039;t.  The component routers are a good example of this.  We are very very hesitant to touch this because many people are very particular about their URLs, and past experience has shown that small changes can cause significant, unforeseen problems.&lt;br /&gt;
&lt;br /&gt;
Good unit tests take a great deal of the anxiety out of such changes because you can be confident that the change you are introducing is not going to have nasty, unforeseen consequences.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== What is Unit Testing? ==&lt;br /&gt;
&lt;br /&gt;
In its purest form, unit tests are tests that are designed to ensure that small units of code behave as they are intended.  Pure unit testing means that each method is tested in isolation from all other methods.  That is to say, for example, that if we are writing a test for JApplication, and JApplication happens to use the JDatabase class, we want to try and design our tests such that a bug in the JDatabase class won&#039;t affect our test written for the JApplication class.&lt;br /&gt;
&lt;br /&gt;
In practice, this can be difficult because sometimes class references are hardcoded.  Static methods are very difficult in this regard because you can&#039;t redefine classes and all tests in PHPUnit are executed in the same process.&lt;br /&gt;
&lt;br /&gt;
On the other end of the scale is system testing.  System tests are tests that are written to test a system as a whole.  In these tests, the goal isn&#039;t to isolate particular units of code.  Rather, it is to ensure that all the parts work together in the way they were intended.  For web applications, these tests are often developed using a product called Selenium which allows you to control a web browser in order to simulate a user actually using your web application.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Installing PHPUnit ==&lt;br /&gt;
&lt;br /&gt;
We are slowing building up an extensive suite of unit tests for the Joomla! Framework.  The tests are built on a unit testing framework called PHPUnit.  In order to run the tests, you need to obtain PHPUnit.&lt;br /&gt;
To get PHPUnit, head over to [http://www.phpunit.de/manual/current/en/installation.html PHPUnit Installation] and follow the instructions to install PHPUnit.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Running Tests ==&lt;br /&gt;
&lt;br /&gt;
Unit tests are typically run from the command line.  While this may be daunting for some, once you get the hang of things it is actually quite easy.&lt;br /&gt;
Once you have PHPUnit installed and your path setup correctly, it is as simple as changing to the unit test directory and typing &#039;phpunit&#039;:&lt;br /&gt;
cd /path/to/joomla/tests/unit&lt;br /&gt;
phpunit&lt;br /&gt;
After you run this command, you should see output that looks something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;PHPUnit 3.4.11 by Sebastian Bergmann.&lt;br /&gt;
&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIII...III..IIIIIIIIIIIIIIIIIIIIIIIIIIIIIII   60 / 2207&lt;br /&gt;
III...SIIIIII.IIIIIIIIIIIIII....................F.IIIIIIIIII  120 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  180 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  240 / 2207&lt;br /&gt;
IIIIIIIIIIIIIII.......................I.I...FFFFFEEEEEEEEEE.  300 / 2207&lt;br /&gt;
....FFFFF.EEEIIIIIIIII...IIIFFFFF.....SSSSFSSSSSSFSSSSSSSSSS  360 / 2207&lt;br /&gt;
SSSSSFSS......IIF.SFFFFFFF.......I........I.................  420 / 2207&lt;br /&gt;
.........III.II.IIII.IIII.I.........I.IIIII.IIII..........II  480 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  540 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIII.IIIIIIIIIIIIIII...........................  600 / 2207&lt;br /&gt;
...IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  660 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIII..................................  720 / 2207&lt;br /&gt;
....................................................FFFF....  780 / 2207&lt;br /&gt;
............................................................  840 / 2207&lt;br /&gt;
............................................................  900 / 2207&lt;br /&gt;
............................................................  960 / 2207&lt;br /&gt;
............................................IIIIIIIIIIIIIIII 1020 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1080 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1140 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1200 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1260 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1320 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIII...I.....II.IIIIIIIIIIIIIIIIIIIIIIIIIIII 1380 / 2207&lt;br /&gt;
IIIIIIIIIIIIII.IIIIIIIIIII.........IIIIII.IIIIIIIIIIIIIIIIII 1440 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII..II.............. 1500 / 2207&lt;br /&gt;
.........F.F...........F..FFF................II....I...F..II 1560 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1620 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIII...F........IIIIIIIIIIIIIIIIIIIIIIIIIIIII 1680 / 2207&lt;br /&gt;
IIIIIIIIIIIIII..IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII........... 1740 / 2207&lt;br /&gt;
...F........................................................ 1800 / 2207&lt;br /&gt;
............................................................ 1860 / 2207&lt;br /&gt;
............................................................ 1920 / 2207&lt;br /&gt;
............................................................ 1980 / 2207&lt;br /&gt;
............................................................ 2040 / 2207&lt;br /&gt;
.........................F.................................. 2100 / 2207&lt;br /&gt;
............................F............................... 2160 / 2207&lt;br /&gt;
...............................F..I............&lt;br /&gt;
&lt;br /&gt;
Time: 14 seconds, Memory: 89.50Mb&lt;br /&gt;
&lt;br /&gt;
There were 13 errors:&lt;br /&gt;
&lt;br /&gt;
1) JCacheTest::testSetCaching with data set &amp;quot;simple&amp;quot; (&#039;output&#039;, array())&lt;br /&gt;
Undefined property: JCacheControllerOutput::$_options&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) JCacheTest::testSetCaching with data set &amp;quot;complexOutput&amp;quot; (&#039;output&#039;, array(&#039;&#039;, &#039;/home/ian/www/ut_work/unittest/cache&#039;, 900, &#039;file&#039;))&lt;br /&gt;
Undefined property: JCacheControllerOutput::$_options&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3) JCacheTest::testSetCaching with data set &amp;quot;complexPage&amp;quot; (&#039;page&#039;, array(&#039;&#039;, &#039;/home/ian/www/ut_work/unittest/cache&#039;, 900, &#039;file&#039;))&lt;br /&gt;
Undefined property: JCacheControllerPage::$_options&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
--&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There were 43 failures:&lt;br /&gt;
&lt;br /&gt;
1) JControllerFormTest::testConstructor&lt;br /&gt;
_asset_name has not been defined for structure&lt;br /&gt;
Failed asserting that an array has the key &amp;lt;string:_asset_name&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) JCacheTest::testGetInstance with data set &amp;quot;simple&amp;quot; (&#039;output&#039;, array(), &#039;JCacheOutput&#039;)&lt;br /&gt;
Failed asserting that &amp;lt;JCacheControllerOutput&amp;gt; is an instance of class &amp;quot;JCacheOutput&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3) JCacheTest::testGetInstance with data set &amp;quot;complexOutput&amp;quot; (&#039;output&#039;, array(&#039;&#039;, &#039;/home/ian/www/ut_work/tests/unit/cache&#039;, 900, &#039;file&#039;), &#039;JCacheOutput&#039;)&lt;br /&gt;
Failed asserting that &amp;lt;JCacheControllerOutput&amp;gt; is an instance of class &amp;quot;JCacheOutput&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
4) JCacheTest::testGetInstance with data set &amp;quot;complexPage&amp;quot; (&#039;page&#039;, array(&#039;&#039;, &#039;/home/ian/www/ut_work/tests/unit/cache&#039;, 900, &#039;file&#039;), &#039;JCachePage&#039;)&lt;br /&gt;
Failed asserting that &amp;lt;JCacheControllerPage&amp;gt; is an instance of class &amp;quot;JCachePage&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
FAILURES!&lt;br /&gt;
Tests: 2207, Assertions: 1751, Failures: 43, Errors: 13, Incomplete: 1063, Skipped: 29.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are many situations where you may not want to run the whole test suite.  See the [[Running Unit Tests]] page for details on how to be selective with the tests that you run.&lt;br /&gt;
&lt;br /&gt;
== Anatomy of a Test ==&lt;br /&gt;
&lt;br /&gt;
Unit tests are merely small chunks of PHP code that:&lt;br /&gt;
# Setup certain preconditions for the code to be tested (inputs).&lt;br /&gt;
# Execute the code to be tested.&lt;br /&gt;
# Tests assertions about the results (outputs).&lt;br /&gt;
&lt;br /&gt;
We will see these basic elements in each of the example tests that are provided below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Writing Our First Test ==&lt;br /&gt;
&lt;br /&gt;
The easiest and most simple type of unit test to write is a test for code that is stateless.  That is, a test for which the return value of the method depends solely on the inputs to the method.  Most of the basic PHP functions are examples of stateless functions.  The strtoupper function, for example, takes one parameter – a string – and returns a string value.  You can easily create a set of inputs and corresponding outputs and write a test.&lt;br /&gt;
Examples in the Joomla! Framework include much of the JArrayHelper class.  Most of these methods are static methods and don&#039;t depend on anything except the data passed to the method.  For this example, we will use the JArrayHelper::getColumn method.  This method takes two parameters and returns an array.&lt;br /&gt;
So, following the  three steps outlined above, we break things down into three elements:&lt;br /&gt;
&lt;br /&gt;
=== 1. Setup Preconditions ===&lt;br /&gt;
&lt;br /&gt;
In this case, there are no preconditions because our method does not depend on anything other than the parameters that are passed to it.  Our only preconditions are the parameters that we pass to the method.&lt;br /&gt;
&lt;br /&gt;
=== 2. Execute the code to be tested ===&lt;br /&gt;
&lt;br /&gt;
So, our method in question will take an array of associative arrays or objects and will return an array of the values of the specified index.&lt;br /&gt;
So, to test our method, we first need to create an array of associative arrays:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$test_array = array(&lt;br /&gt;
	array(&lt;br /&gt;
		&#039;sport&#039; =&amp;gt; &#039;football&#039;,&lt;br /&gt;
		&#039;teams&#039; =&amp;gt; &#039;16&#039;,&lt;br /&gt;
		&#039;country&#039; =&amp;gt; &#039;United States&#039;&lt;br /&gt;
	).&lt;br /&gt;
	array(&lt;br /&gt;
		&#039;sport&#039; =&amp;gt; &#039;badminton&#039;,&lt;br /&gt;
		&#039;teams&#039; =&amp;gt; &#039;12&#039;,&lt;br /&gt;
		&#039;country&#039; =&amp;gt; &#039;Germany&#039;&lt;br /&gt;
	),&lt;br /&gt;
	array(&lt;br /&gt;
		&#039;sport&#039; =&amp;gt; &#039;basketball&#039;,&lt;br /&gt;
		&#039;teams&#039; =&amp;gt; &#039;20&#039;,&lt;br /&gt;
		&#039;country&#039; =&amp;gt; &#039;Canada&#039;&lt;br /&gt;
	)&lt;br /&gt;
);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we execute the method and retrieve the results:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$result_array = JArrayHelper::getColumn($test_array, &#039;country&#039;);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We have now executed the method we want to test.  We can now examine the results.&lt;br /&gt;
&lt;br /&gt;
=== 3. Tests assertions about the results (outputs) ===&lt;br /&gt;
&lt;br /&gt;
Since this method is fairly simple, testing the results is also simple.  What we need to do is figure out what we expect to get back from the method.  In this case, we expect to get an array containing an array of the countries.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$this-&amp;gt;assertThat(&lt;br /&gt;
    $result_array,&lt;br /&gt;
    $this-&amp;gt;equalTo(array(&#039;United States&#039;, &#039;Germany&#039;, &#039;Canada&#039;)),&lt;br /&gt;
    &#039;We did not get the proper column data back&#039;&lt;br /&gt;
);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our final test looks like:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
public function testGetColumnTutorial()&lt;br /&gt;
{&lt;br /&gt;
	$test_array = array(&lt;br /&gt;
		array(&lt;br /&gt;
			&#039;sport&#039; =&amp;gt; &#039;football&#039;,&lt;br /&gt;
			&#039;teams&#039; =&amp;gt; &#039;16&#039;,&lt;br /&gt;
			&#039;country&#039; =&amp;gt; &#039;United States&#039;&lt;br /&gt;
		),&lt;br /&gt;
		array(&lt;br /&gt;
			&#039;sport&#039; =&amp;gt; &#039;badminton&#039;,&lt;br /&gt;
			&#039;teams&#039; =&amp;gt; &#039;12&#039;,&lt;br /&gt;
			&#039;country&#039; =&amp;gt; &#039;Germany&#039;&lt;br /&gt;
		),&lt;br /&gt;
		array(&lt;br /&gt;
			&#039;sport&#039; =&amp;gt; &#039;basketball&#039;,&lt;br /&gt;
			&#039;teams&#039; =&amp;gt; &#039;20&#039;,&lt;br /&gt;
			&#039;country&#039; =&amp;gt; &#039;Canada&#039;&lt;br /&gt;
		)&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
	$result_array = JArrayHelper::getColumn($test_array, &#039;country&#039;);&lt;br /&gt;
&lt;br /&gt;
	$this-&amp;gt;assertThat(&lt;br /&gt;
		$result_array,&lt;br /&gt;
		$this-&amp;gt;equalTo(&lt;br /&gt;
			array(&#039;United States&#039;, &#039;Germany&#039;, &#039;Canada&#039;)&lt;br /&gt;
		),&lt;br /&gt;
		&#039;We did not get the proper column data back&#039;&lt;br /&gt;
	);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== How a Unit Test should NOT be written ==&lt;br /&gt;
&lt;br /&gt;
Unexperienced users often tap into pitfalls when writing unit test testcases.&lt;br /&gt;
A good tutorial on how to avoid these pitfalls, sometimes also called anti-patterns, is summarized at [http://exubero.com/junit/antipatterns.html].&lt;br /&gt;
&lt;br /&gt;
= Unit Test Tutorial 2 =&lt;br /&gt;
This article is continued here: [[Unit Test Tutorial 2]]. This includes looking into the derived &#039;PHPUnit_Framework_TestCase&#039; testclass and the minimum requirements for a standalone testclass.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Bug Squad]] [[Category:Development]] [[Category:Testing]] [[Category:Automated Testing]]&lt;/div&gt;</summary>
		<author><name>Jedbox</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Unit_Test_Tutorial_2&amp;diff=28006</id>
		<title>Unit Test Tutorial 2</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Unit_Test_Tutorial_2&amp;diff=28006"/>
		<updated>2010-05-24T02:56:33Z</updated>

		<summary type="html">&lt;p&gt;Jedbox: /* Add Category Testing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Looking at the Unit Test Class ==&lt;br /&gt;
&lt;br /&gt;
In our first unit test, we create a single test.  This test was a part of a presumed preexisting test class.  Although an individual test can be contained in a single method, these methods have to be a part of a test class.&lt;br /&gt;
&lt;br /&gt;
Unit Test classes generally inherit from the class &#039;PHPUnit_Framework_TestCase&#039;.&lt;br /&gt;
&lt;br /&gt;
You can see a basic test class below:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * @version		$Id$&lt;br /&gt;
 * @copyright	Copyright (C) 2005 - 2010 Open Source Matters. All rights reserved.&lt;br /&gt;
 * @license		GNU General Public License version 2 or later; see LICENSE.txt&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
require_once JPATH_BASE.&#039;/libraries/joomla/utilities/arrayhelper.php&#039;;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Test class for JArrayHelper.&lt;br /&gt;
 */&lt;br /&gt;
class JArrayHelperTest extends PHPUnit_Framework_TestCase {&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Sets up the fixture, for example, opens a network connection.&lt;br /&gt;
	 * This method is called before a test is executed.&lt;br /&gt;
	 *&lt;br /&gt;
	 * @access protected&lt;br /&gt;
	 */&lt;br /&gt;
	protected function setUp() {&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Tears down the fixture, for example, closes a network connection.&lt;br /&gt;
	 * This method is called after a test is executed.&lt;br /&gt;
	 *&lt;br /&gt;
	 * @access protected&lt;br /&gt;
	 */&lt;br /&gt;
	protected function tearDown() {&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * Simple Test for getColumn method.&lt;br /&gt;
	 */&lt;br /&gt;
	public function testGetColumn()&lt;br /&gt;
	{&lt;br /&gt;
		$test_array = array(&lt;br /&gt;
			array(&lt;br /&gt;
				&#039;sport&#039; =&amp;gt; &#039;football&#039;,&lt;br /&gt;
				&#039;teams&#039; =&amp;gt; &#039;16&#039;,&lt;br /&gt;
				&#039;country&#039; =&amp;gt; &#039;United States&#039;&lt;br /&gt;
			),&lt;br /&gt;
			array(&lt;br /&gt;
				&#039;sport&#039; =&amp;gt; &#039;badminton&#039;,&lt;br /&gt;
				&#039;teams&#039; =&amp;gt; &#039;12&#039;,&lt;br /&gt;
				&#039;country&#039; =&amp;gt; &#039;Germany&#039;&lt;br /&gt;
			),&lt;br /&gt;
			array(&lt;br /&gt;
				&#039;sport&#039; =&amp;gt; &#039;basketball&#039;,&lt;br /&gt;
				&#039;teams&#039; =&amp;gt; &#039;20&#039;,&lt;br /&gt;
				&#039;country&#039; =&amp;gt; &#039;Canada&#039;&lt;br /&gt;
			)&lt;br /&gt;
		);&lt;br /&gt;
&lt;br /&gt;
		$result_array = JArrayHelper::getColumn($test_array, &#039;country&#039;);&lt;br /&gt;
&lt;br /&gt;
		$this-&amp;gt;assertThat(&lt;br /&gt;
			$result_array,&lt;br /&gt;
			$this-&amp;gt;equalTo(&lt;br /&gt;
				array(&#039;United States&#039;, &#039;Germany&#039;, &#039;Canada&#039;)&lt;br /&gt;
			),&lt;br /&gt;
			&#039;We did not get the proper column data back&#039;&lt;br /&gt;
		);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Okay, so some notes:&lt;br /&gt;
&lt;br /&gt;
* As noted, the class extends from PHPUnit_Framework_TestCase&lt;br /&gt;
* Outside of our class, we do a require for the class that we want to test&lt;br /&gt;
* Our class name starts with the name of the class we want to test and has &#039;Test&#039; appended to the end. i.e. we are testing JArrayHelper, so our test class is JArrayHelperTest.&lt;br /&gt;
* We have two methods that are not part of our tests: setUp() and tearDown(). As noted in the comments for these methods, setUp() is called before each test and tearDown() is called after each test. To clarify, if there are 10 tests in a class, they are each called ten times.  There are two other methods available that you can supply: setUpBeforeClass() and tearDownAfterClass(). As the names imply, these are each called before and after all the tests from the class are performed, thus getting executed once each.&lt;br /&gt;
* Test methods start with the word test and generally end with the name of the method that is under test.  We are testing the getColumn() method, therefore, our method is called testGetColumn(). As methods get more complicated, more than one method is required for testing. In this situation, method names that describe the general purpose of the method should be used.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Testing]]&lt;/div&gt;</summary>
		<author><name>Jedbox</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Unit_Test_Tutorial_1&amp;diff=28005</id>
		<title>Unit Test Tutorial 1</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Unit_Test_Tutorial_1&amp;diff=28005"/>
		<updated>2010-05-24T02:53:52Z</updated>

		<summary type="html">&lt;p&gt;Jedbox: /* Add to category Testing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Unit Testing and Joomla! =&lt;br /&gt;
&lt;br /&gt;
As we move forward with Joomla! Development one element that is going to be playing a larger and larger role is unit testing.  My hope with this short series is to provide some basic background on unit testing, to demonstrate how essential unit tests are to stable software and to give practical instruction and examples that illustrate how to write unit tests.&lt;br /&gt;
&lt;br /&gt;
As co-maintainer of the Joomla! Bug Squad, there is a question that repeatedly pops up: &#039;What is this change going to break?&#039;.  There are certain elements of the code base that can be rather fragile and this makes it very difficult to know what things are safe to touch and what things aren&#039;t.  The component routers are a good example of this.  We are very very hesitant to touch this because many people are very particular about their URLs, and past experience has shown that small changes can cause significant, unforeseen problems.&lt;br /&gt;
&lt;br /&gt;
Good unit tests take a great deal of the anxiety out of such changes because you can be confident that the change you are introducing is not going to have nasty, unforeseen consequences.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== What is Unit Testing? ==&lt;br /&gt;
&lt;br /&gt;
In its purest form, unit tests are tests that are designed to ensure that small units of code behave as they are intended.  Pure unit testing means that each method is tested in isolation from all other methods.  That is to say, for example, that if we are writing a test for JApplication, and JApplication happens to use the JDatabase class, we want to try and design our tests such that a bug in the JDatabase class won&#039;t affect our test written for the JApplication class.&lt;br /&gt;
&lt;br /&gt;
In practice, this can be difficult because sometimes class references are hardcoded.  Static methods are very difficult in this regard because you can&#039;t redefine classes and all tests in PHPUnit are executed in the same process.&lt;br /&gt;
&lt;br /&gt;
On the other end of the scale is system testing.  System tests are tests that are written to test a system as a whole.  In these tests, the goal isn&#039;t to isolate particular units of code.  Rather, it is to ensure that all the parts work together in the way they were intended.  For web applications, these tests are often developed using a product called Selenium which allows you to control a web browser in order to simulate a user actually using your web application.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Installing PHPUnit ==&lt;br /&gt;
&lt;br /&gt;
We are slowing building up an extensive suite of unit tests for the Joomla! Framework.  The tests are built on a unit testing framework called PHPUnit.  In order to run the tests, you need to obtain PHPUnit.&lt;br /&gt;
To get PHPUnit, head over to [http://www.phpunit.de/manual/current/en/installation.html PHPUnit Installation] and follow the instructions to install PHPUnit.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Running Tests ==&lt;br /&gt;
&lt;br /&gt;
Unit tests are typically run from the command line.  While this may be daunting for some, once you get the hang of things it is actually quite easy.&lt;br /&gt;
Once you have PHPUnit installed and your path setup correctly, it is as simple as changing to the unit test directory and typing &#039;phpunit&#039;:&lt;br /&gt;
cd /path/to/joomla/tests/unit&lt;br /&gt;
phpunit&lt;br /&gt;
After you run this command, you should see output that looks something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;PHPUnit 3.4.11 by Sebastian Bergmann.&lt;br /&gt;
&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIII...III..IIIIIIIIIIIIIIIIIIIIIIIIIIIIIII   60 / 2207&lt;br /&gt;
III...SIIIIII.IIIIIIIIIIIIII....................F.IIIIIIIIII  120 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  180 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  240 / 2207&lt;br /&gt;
IIIIIIIIIIIIIII.......................I.I...FFFFFEEEEEEEEEE.  300 / 2207&lt;br /&gt;
....FFFFF.EEEIIIIIIIII...IIIFFFFF.....SSSSFSSSSSSFSSSSSSSSSS  360 / 2207&lt;br /&gt;
SSSSSFSS......IIF.SFFFFFFF.......I........I.................  420 / 2207&lt;br /&gt;
.........III.II.IIII.IIII.I.........I.IIIII.IIII..........II  480 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  540 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIII.IIIIIIIIIIIIIII...........................  600 / 2207&lt;br /&gt;
...IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  660 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIII..................................  720 / 2207&lt;br /&gt;
....................................................FFFF....  780 / 2207&lt;br /&gt;
............................................................  840 / 2207&lt;br /&gt;
............................................................  900 / 2207&lt;br /&gt;
............................................................  960 / 2207&lt;br /&gt;
............................................IIIIIIIIIIIIIIII 1020 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1080 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1140 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1200 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1260 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1320 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIII...I.....II.IIIIIIIIIIIIIIIIIIIIIIIIIIII 1380 / 2207&lt;br /&gt;
IIIIIIIIIIIIII.IIIIIIIIIII.........IIIIII.IIIIIIIIIIIIIIIIII 1440 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII..II.............. 1500 / 2207&lt;br /&gt;
.........F.F...........F..FFF................II....I...F..II 1560 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1620 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIII...F........IIIIIIIIIIIIIIIIIIIIIIIIIIIII 1680 / 2207&lt;br /&gt;
IIIIIIIIIIIIII..IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII........... 1740 / 2207&lt;br /&gt;
...F........................................................ 1800 / 2207&lt;br /&gt;
............................................................ 1860 / 2207&lt;br /&gt;
............................................................ 1920 / 2207&lt;br /&gt;
............................................................ 1980 / 2207&lt;br /&gt;
............................................................ 2040 / 2207&lt;br /&gt;
.........................F.................................. 2100 / 2207&lt;br /&gt;
............................F............................... 2160 / 2207&lt;br /&gt;
...............................F..I............&lt;br /&gt;
&lt;br /&gt;
Time: 14 seconds, Memory: 89.50Mb&lt;br /&gt;
&lt;br /&gt;
There were 13 errors:&lt;br /&gt;
&lt;br /&gt;
1) JCacheTest::testSetCaching with data set &amp;quot;simple&amp;quot; (&#039;output&#039;, array())&lt;br /&gt;
Undefined property: JCacheControllerOutput::$_options&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) JCacheTest::testSetCaching with data set &amp;quot;complexOutput&amp;quot; (&#039;output&#039;, array(&#039;&#039;, &#039;/home/ian/www/ut_work/unittest/cache&#039;, 900, &#039;file&#039;))&lt;br /&gt;
Undefined property: JCacheControllerOutput::$_options&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3) JCacheTest::testSetCaching with data set &amp;quot;complexPage&amp;quot; (&#039;page&#039;, array(&#039;&#039;, &#039;/home/ian/www/ut_work/unittest/cache&#039;, 900, &#039;file&#039;))&lt;br /&gt;
Undefined property: JCacheControllerPage::$_options&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
--&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There were 43 failures:&lt;br /&gt;
&lt;br /&gt;
1) JControllerFormTest::testConstructor&lt;br /&gt;
_asset_name has not been defined for structure&lt;br /&gt;
Failed asserting that an array has the key &amp;lt;string:_asset_name&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) JCacheTest::testGetInstance with data set &amp;quot;simple&amp;quot; (&#039;output&#039;, array(), &#039;JCacheOutput&#039;)&lt;br /&gt;
Failed asserting that &amp;lt;JCacheControllerOutput&amp;gt; is an instance of class &amp;quot;JCacheOutput&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3) JCacheTest::testGetInstance with data set &amp;quot;complexOutput&amp;quot; (&#039;output&#039;, array(&#039;&#039;, &#039;/home/ian/www/ut_work/tests/unit/cache&#039;, 900, &#039;file&#039;), &#039;JCacheOutput&#039;)&lt;br /&gt;
Failed asserting that &amp;lt;JCacheControllerOutput&amp;gt; is an instance of class &amp;quot;JCacheOutput&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
4) JCacheTest::testGetInstance with data set &amp;quot;complexPage&amp;quot; (&#039;page&#039;, array(&#039;&#039;, &#039;/home/ian/www/ut_work/tests/unit/cache&#039;, 900, &#039;file&#039;), &#039;JCachePage&#039;)&lt;br /&gt;
Failed asserting that &amp;lt;JCacheControllerPage&amp;gt; is an instance of class &amp;quot;JCachePage&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
FAILURES!&lt;br /&gt;
Tests: 2207, Assertions: 1751, Failures: 43, Errors: 13, Incomplete: 1063, Skipped: 29.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are many situations where you may not want to run the whole test suite.  See the [[Running Unit Tests]] page for details on how to be selective with the tests that you run.&lt;br /&gt;
&lt;br /&gt;
== Anatomy of a Test ==&lt;br /&gt;
&lt;br /&gt;
Unit tests are merely small chunks of PHP code that:&lt;br /&gt;
# Setup certain preconditions for the code to be tested (inputs).&lt;br /&gt;
# Execute the code to be tested.&lt;br /&gt;
# Tests assertions about the results (outputs).&lt;br /&gt;
&lt;br /&gt;
We will see these basic elements in each of the example tests that are provided below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Writing Our First Test ==&lt;br /&gt;
&lt;br /&gt;
The easiest and most simple type of unit test to write is a test for code that is stateless.  That is, a test for which the return value of the method depends solely on the inputs to the method.  Most of the basic PHP functions are examples of stateless functions.  The strtoupper function, for example, takes one parameter – a string – and returns a string value.  You can easily create a set of inputs and corresponding outputs and write a test.&lt;br /&gt;
Examples in the Joomla! Framework include much of the JArrayHelper class.  Most of these methods are static methods and don&#039;t depend on anything except the data passed to the method.  For this example, we will use the JArrayHelper::getColumn method.  This method takes two parameters and returns an array.&lt;br /&gt;
So, following the  three steps outlined above, we break things down into three elements:&lt;br /&gt;
&lt;br /&gt;
=== 1. Setup Preconditions ===&lt;br /&gt;
&lt;br /&gt;
In this case, there are no preconditions because our method does not depend on anything other than the parameters that are passed to it.  Our only preconditions are the parameters that we pass to the method.&lt;br /&gt;
&lt;br /&gt;
=== 2. Execute the code to be tested ===&lt;br /&gt;
&lt;br /&gt;
So, our method in question will take an array of associative arrays or objects and will return an array of the values of the specified index.&lt;br /&gt;
So, to test our method, we first need to create an array of associative arrays:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$test_array = array(&lt;br /&gt;
	array(&lt;br /&gt;
		&#039;sport&#039; =&amp;gt; &#039;football&#039;,&lt;br /&gt;
		&#039;teams&#039; =&amp;gt; &#039;16&#039;,&lt;br /&gt;
		&#039;country&#039; =&amp;gt; &#039;United States&#039;&lt;br /&gt;
	).&lt;br /&gt;
	array(&lt;br /&gt;
		&#039;sport&#039; =&amp;gt; &#039;badminton&#039;,&lt;br /&gt;
		&#039;teams&#039; =&amp;gt; &#039;12&#039;,&lt;br /&gt;
		&#039;country&#039; =&amp;gt; &#039;Germany&#039;&lt;br /&gt;
	),&lt;br /&gt;
	array(&lt;br /&gt;
		&#039;sport&#039; =&amp;gt; &#039;basketball&#039;,&lt;br /&gt;
		&#039;teams&#039; =&amp;gt; &#039;20&#039;,&lt;br /&gt;
		&#039;country&#039; =&amp;gt; &#039;Canada&#039;&lt;br /&gt;
	)&lt;br /&gt;
);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we execute the method and retrieve the results:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$result_array = JArrayHelper::getColumn($test_array, &#039;country&#039;);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We have now executed the method we want to test.  We can now examine the results.&lt;br /&gt;
&lt;br /&gt;
=== 3. Tests assertions about the results (outputs) ===&lt;br /&gt;
&lt;br /&gt;
Since this method is fairly simple, testing the results is also simple.  What we need to do is figure out what we expect to get back from the method.  In this case, we expect to get an array containing an array of the countries.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$this-&amp;gt;assertThat(&lt;br /&gt;
    $result_array,&lt;br /&gt;
    $this-&amp;gt;equalTo(array(&#039;United States&#039;, &#039;Germany&#039;, &#039;Canada&#039;)),&lt;br /&gt;
    &#039;We did not get the proper column data back&#039;&lt;br /&gt;
);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our final test looks like:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
public function testGetColumnTutorial()&lt;br /&gt;
{&lt;br /&gt;
	$test_array = array(&lt;br /&gt;
		array(&lt;br /&gt;
			&#039;sport&#039; =&amp;gt; &#039;football&#039;,&lt;br /&gt;
			&#039;teams&#039; =&amp;gt; &#039;16&#039;,&lt;br /&gt;
			&#039;country&#039; =&amp;gt; &#039;United States&#039;&lt;br /&gt;
		),&lt;br /&gt;
		array(&lt;br /&gt;
			&#039;sport&#039; =&amp;gt; &#039;badminton&#039;,&lt;br /&gt;
			&#039;teams&#039; =&amp;gt; &#039;12&#039;,&lt;br /&gt;
			&#039;country&#039; =&amp;gt; &#039;Germany&#039;&lt;br /&gt;
		),&lt;br /&gt;
		array(&lt;br /&gt;
			&#039;sport&#039; =&amp;gt; &#039;basketball&#039;,&lt;br /&gt;
			&#039;teams&#039; =&amp;gt; &#039;20&#039;,&lt;br /&gt;
			&#039;country&#039; =&amp;gt; &#039;Canada&#039;&lt;br /&gt;
		)&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
	$result_array = JArrayHelper::getColumn($test_array, &#039;country&#039;);&lt;br /&gt;
&lt;br /&gt;
	$this-&amp;gt;assertThat(&lt;br /&gt;
		$result_array,&lt;br /&gt;
		$this-&amp;gt;equalTo(&lt;br /&gt;
			array(&#039;United States&#039;, &#039;Germany&#039;, &#039;Canada&#039;)&lt;br /&gt;
		),&lt;br /&gt;
		&#039;We did not get the proper column data back&#039;&lt;br /&gt;
	);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== How a Unit Test should NOT be written ==&lt;br /&gt;
&lt;br /&gt;
Unexperienced users often tap into pitfalls when writing unit test testcases.&lt;br /&gt;
A good tutorial on how to avoid these pitfalls, sometimes also called anti-patterns, is summarized at [http://exubero.com/junit/antipatterns.html].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Testing]]&lt;/div&gt;</summary>
		<author><name>Jedbox</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Unit_Test_Tutorial_1&amp;diff=28004</id>
		<title>Unit Test Tutorial 1</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Unit_Test_Tutorial_1&amp;diff=28004"/>
		<updated>2010-05-24T02:49:11Z</updated>

		<summary type="html">&lt;p&gt;Jedbox: /* How a Unit Test should NOT be written */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Unit Testing and Joomla! =&lt;br /&gt;
&lt;br /&gt;
As we move forward with Joomla! Development one element that is going to be playing a larger and larger role is unit testing.  My hope with this short series is to provide some basic background on unit testing, to demonstrate how essential unit tests are to stable software and to give practical instruction and examples that illustrate how to write unit tests.&lt;br /&gt;
&lt;br /&gt;
As co-maintainer of the Joomla! Bug Squad, there is a question that repeatedly pops up: &#039;What is this change going to break?&#039;.  There are certain elements of the code base that can be rather fragile and this makes it very difficult to know what things are safe to touch and what things aren&#039;t.  The component routers are a good example of this.  We are very very hesitant to touch this because many people are very particular about their URLs, and past experience has shown that small changes can cause significant, unforeseen problems.&lt;br /&gt;
&lt;br /&gt;
Good unit tests take a great deal of the anxiety out of such changes because you can be confident that the change you are introducing is not going to have nasty, unforeseen consequences.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== What is Unit Testing? ==&lt;br /&gt;
&lt;br /&gt;
In its purest form, unit tests are tests that are designed to ensure that small units of code behave as they are intended.  Pure unit testing means that each method is tested in isolation from all other methods.  That is to say, for example, that if we are writing a test for JApplication, and JApplication happens to use the JDatabase class, we want to try and design our tests such that a bug in the JDatabase class won&#039;t affect our test written for the JApplication class.&lt;br /&gt;
&lt;br /&gt;
In practice, this can be difficult because sometimes class references are hardcoded.  Static methods are very difficult in this regard because you can&#039;t redefine classes and all tests in PHPUnit are executed in the same process.&lt;br /&gt;
&lt;br /&gt;
On the other end of the scale is system testing.  System tests are tests that are written to test a system as a whole.  In these tests, the goal isn&#039;t to isolate particular units of code.  Rather, it is to ensure that all the parts work together in the way they were intended.  For web applications, these tests are often developed using a product called Selenium which allows you to control a web browser in order to simulate a user actually using your web application.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Installing PHPUnit ==&lt;br /&gt;
&lt;br /&gt;
We are slowing building up an extensive suite of unit tests for the Joomla! Framework.  The tests are built on a unit testing framework called PHPUnit.  In order to run the tests, you need to obtain PHPUnit.&lt;br /&gt;
To get PHPUnit, head over to [http://www.phpunit.de/manual/current/en/installation.html PHPUnit Installation] and follow the instructions to install PHPUnit.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Running Tests ==&lt;br /&gt;
&lt;br /&gt;
Unit tests are typically run from the command line.  While this may be daunting for some, once you get the hang of things it is actually quite easy.&lt;br /&gt;
Once you have PHPUnit installed and your path setup correctly, it is as simple as changing to the unit test directory and typing &#039;phpunit&#039;:&lt;br /&gt;
cd /path/to/joomla/tests/unit&lt;br /&gt;
phpunit&lt;br /&gt;
After you run this command, you should see output that looks something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;PHPUnit 3.4.11 by Sebastian Bergmann.&lt;br /&gt;
&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIII...III..IIIIIIIIIIIIIIIIIIIIIIIIIIIIIII   60 / 2207&lt;br /&gt;
III...SIIIIII.IIIIIIIIIIIIII....................F.IIIIIIIIII  120 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  180 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  240 / 2207&lt;br /&gt;
IIIIIIIIIIIIIII.......................I.I...FFFFFEEEEEEEEEE.  300 / 2207&lt;br /&gt;
....FFFFF.EEEIIIIIIIII...IIIFFFFF.....SSSSFSSSSSSFSSSSSSSSSS  360 / 2207&lt;br /&gt;
SSSSSFSS......IIF.SFFFFFFF.......I........I.................  420 / 2207&lt;br /&gt;
.........III.II.IIII.IIII.I.........I.IIIII.IIII..........II  480 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  540 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIII.IIIIIIIIIIIIIII...........................  600 / 2207&lt;br /&gt;
...IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  660 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIII..................................  720 / 2207&lt;br /&gt;
....................................................FFFF....  780 / 2207&lt;br /&gt;
............................................................  840 / 2207&lt;br /&gt;
............................................................  900 / 2207&lt;br /&gt;
............................................................  960 / 2207&lt;br /&gt;
............................................IIIIIIIIIIIIIIII 1020 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1080 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1140 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1200 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1260 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1320 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIII...I.....II.IIIIIIIIIIIIIIIIIIIIIIIIIIII 1380 / 2207&lt;br /&gt;
IIIIIIIIIIIIII.IIIIIIIIIII.........IIIIII.IIIIIIIIIIIIIIIIII 1440 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII..II.............. 1500 / 2207&lt;br /&gt;
.........F.F...........F..FFF................II....I...F..II 1560 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1620 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIII...F........IIIIIIIIIIIIIIIIIIIIIIIIIIIII 1680 / 2207&lt;br /&gt;
IIIIIIIIIIIIII..IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII........... 1740 / 2207&lt;br /&gt;
...F........................................................ 1800 / 2207&lt;br /&gt;
............................................................ 1860 / 2207&lt;br /&gt;
............................................................ 1920 / 2207&lt;br /&gt;
............................................................ 1980 / 2207&lt;br /&gt;
............................................................ 2040 / 2207&lt;br /&gt;
.........................F.................................. 2100 / 2207&lt;br /&gt;
............................F............................... 2160 / 2207&lt;br /&gt;
...............................F..I............&lt;br /&gt;
&lt;br /&gt;
Time: 14 seconds, Memory: 89.50Mb&lt;br /&gt;
&lt;br /&gt;
There were 13 errors:&lt;br /&gt;
&lt;br /&gt;
1) JCacheTest::testSetCaching with data set &amp;quot;simple&amp;quot; (&#039;output&#039;, array())&lt;br /&gt;
Undefined property: JCacheControllerOutput::$_options&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) JCacheTest::testSetCaching with data set &amp;quot;complexOutput&amp;quot; (&#039;output&#039;, array(&#039;&#039;, &#039;/home/ian/www/ut_work/unittest/cache&#039;, 900, &#039;file&#039;))&lt;br /&gt;
Undefined property: JCacheControllerOutput::$_options&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3) JCacheTest::testSetCaching with data set &amp;quot;complexPage&amp;quot; (&#039;page&#039;, array(&#039;&#039;, &#039;/home/ian/www/ut_work/unittest/cache&#039;, 900, &#039;file&#039;))&lt;br /&gt;
Undefined property: JCacheControllerPage::$_options&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
--&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There were 43 failures:&lt;br /&gt;
&lt;br /&gt;
1) JControllerFormTest::testConstructor&lt;br /&gt;
_asset_name has not been defined for structure&lt;br /&gt;
Failed asserting that an array has the key &amp;lt;string:_asset_name&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) JCacheTest::testGetInstance with data set &amp;quot;simple&amp;quot; (&#039;output&#039;, array(), &#039;JCacheOutput&#039;)&lt;br /&gt;
Failed asserting that &amp;lt;JCacheControllerOutput&amp;gt; is an instance of class &amp;quot;JCacheOutput&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3) JCacheTest::testGetInstance with data set &amp;quot;complexOutput&amp;quot; (&#039;output&#039;, array(&#039;&#039;, &#039;/home/ian/www/ut_work/tests/unit/cache&#039;, 900, &#039;file&#039;), &#039;JCacheOutput&#039;)&lt;br /&gt;
Failed asserting that &amp;lt;JCacheControllerOutput&amp;gt; is an instance of class &amp;quot;JCacheOutput&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
4) JCacheTest::testGetInstance with data set &amp;quot;complexPage&amp;quot; (&#039;page&#039;, array(&#039;&#039;, &#039;/home/ian/www/ut_work/tests/unit/cache&#039;, 900, &#039;file&#039;), &#039;JCachePage&#039;)&lt;br /&gt;
Failed asserting that &amp;lt;JCacheControllerPage&amp;gt; is an instance of class &amp;quot;JCachePage&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
FAILURES!&lt;br /&gt;
Tests: 2207, Assertions: 1751, Failures: 43, Errors: 13, Incomplete: 1063, Skipped: 29.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are many situations where you may not want to run the whole test suite.  See the [[Running Unit Tests]] page for details on how to be selective with the tests that you run.&lt;br /&gt;
&lt;br /&gt;
== Anatomy of a Test ==&lt;br /&gt;
&lt;br /&gt;
Unit tests are merely small chunks of PHP code that:&lt;br /&gt;
# Setup certain preconditions for the code to be tested (inputs).&lt;br /&gt;
# Execute the code to be tested.&lt;br /&gt;
# Tests assertions about the results (outputs).&lt;br /&gt;
&lt;br /&gt;
We will see these basic elements in each of the example tests that are provided below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Writing Our First Test ==&lt;br /&gt;
&lt;br /&gt;
The easiest and most simple type of unit test to write is a test for code that is stateless.  That is, a test for which the return value of the method depends solely on the inputs to the method.  Most of the basic PHP functions are examples of stateless functions.  The strtoupper function, for example, takes one parameter – a string – and returns a string value.  You can easily create a set of inputs and corresponding outputs and write a test.&lt;br /&gt;
Examples in the Joomla! Framework include much of the JArrayHelper class.  Most of these methods are static methods and don&#039;t depend on anything except the data passed to the method.  For this example, we will use the JArrayHelper::getColumn method.  This method takes two parameters and returns an array.&lt;br /&gt;
So, following the  three steps outlined above, we break things down into three elements:&lt;br /&gt;
&lt;br /&gt;
=== 1. Setup Preconditions ===&lt;br /&gt;
&lt;br /&gt;
In this case, there are no preconditions because our method does not depend on anything other than the parameters that are passed to it.  Our only preconditions are the parameters that we pass to the method.&lt;br /&gt;
&lt;br /&gt;
=== 2. Execute the code to be tested ===&lt;br /&gt;
&lt;br /&gt;
So, our method in question will take an array of associative arrays or objects and will return an array of the values of the specified index.&lt;br /&gt;
So, to test our method, we first need to create an array of associative arrays:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$test_array = array(&lt;br /&gt;
	array(&lt;br /&gt;
		&#039;sport&#039; =&amp;gt; &#039;football&#039;,&lt;br /&gt;
		&#039;teams&#039; =&amp;gt; &#039;16&#039;,&lt;br /&gt;
		&#039;country&#039; =&amp;gt; &#039;United States&#039;&lt;br /&gt;
	).&lt;br /&gt;
	array(&lt;br /&gt;
		&#039;sport&#039; =&amp;gt; &#039;badminton&#039;,&lt;br /&gt;
		&#039;teams&#039; =&amp;gt; &#039;12&#039;,&lt;br /&gt;
		&#039;country&#039; =&amp;gt; &#039;Germany&#039;&lt;br /&gt;
	),&lt;br /&gt;
	array(&lt;br /&gt;
		&#039;sport&#039; =&amp;gt; &#039;basketball&#039;,&lt;br /&gt;
		&#039;teams&#039; =&amp;gt; &#039;20&#039;,&lt;br /&gt;
		&#039;country&#039; =&amp;gt; &#039;Canada&#039;&lt;br /&gt;
	)&lt;br /&gt;
);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we execute the method and retrieve the results:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$result_array = JArrayHelper::getColumn($test_array, &#039;country&#039;);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We have now executed the method we want to test.  We can now examine the results.&lt;br /&gt;
&lt;br /&gt;
=== 3. Tests assertions about the results (outputs) ===&lt;br /&gt;
&lt;br /&gt;
Since this method is fairly simple, testing the results is also simple.  What we need to do is figure out what we expect to get back from the method.  In this case, we expect to get an array containing an array of the countries.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$this-&amp;gt;assertThat(&lt;br /&gt;
    $result_array,&lt;br /&gt;
    $this-&amp;gt;equalTo(array(&#039;United States&#039;, &#039;Germany&#039;, &#039;Canada&#039;)),&lt;br /&gt;
    &#039;We did not get the proper column data back&#039;&lt;br /&gt;
);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our final test looks like:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
public function testGetColumnTutorial()&lt;br /&gt;
{&lt;br /&gt;
	$test_array = array(&lt;br /&gt;
		array(&lt;br /&gt;
			&#039;sport&#039; =&amp;gt; &#039;football&#039;,&lt;br /&gt;
			&#039;teams&#039; =&amp;gt; &#039;16&#039;,&lt;br /&gt;
			&#039;country&#039; =&amp;gt; &#039;United States&#039;&lt;br /&gt;
		),&lt;br /&gt;
		array(&lt;br /&gt;
			&#039;sport&#039; =&amp;gt; &#039;badminton&#039;,&lt;br /&gt;
			&#039;teams&#039; =&amp;gt; &#039;12&#039;,&lt;br /&gt;
			&#039;country&#039; =&amp;gt; &#039;Germany&#039;&lt;br /&gt;
		),&lt;br /&gt;
		array(&lt;br /&gt;
			&#039;sport&#039; =&amp;gt; &#039;basketball&#039;,&lt;br /&gt;
			&#039;teams&#039; =&amp;gt; &#039;20&#039;,&lt;br /&gt;
			&#039;country&#039; =&amp;gt; &#039;Canada&#039;&lt;br /&gt;
		)&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
	$result_array = JArrayHelper::getColumn($test_array, &#039;country&#039;);&lt;br /&gt;
&lt;br /&gt;
	$this-&amp;gt;assertThat(&lt;br /&gt;
		$result_array,&lt;br /&gt;
		$this-&amp;gt;equalTo(&lt;br /&gt;
			array(&#039;United States&#039;, &#039;Germany&#039;, &#039;Canada&#039;)&lt;br /&gt;
		),&lt;br /&gt;
		&#039;We did not get the proper column data back&#039;&lt;br /&gt;
	);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== How a Unit Test should NOT be written ==&lt;br /&gt;
&lt;br /&gt;
Unexperienced users often tap into pitfalls when writing unit test testcases.&lt;br /&gt;
A good tutorial on how to avoid these pitfalls, sometimes also called anti-patterns, is summarized at [http://exubero.com/junit/antipatterns.html].&lt;/div&gt;</summary>
		<author><name>Jedbox</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Unit_Test_Tutorial_1&amp;diff=28003</id>
		<title>Unit Test Tutorial 1</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Unit_Test_Tutorial_1&amp;diff=28003"/>
		<updated>2010-05-24T02:40:35Z</updated>

		<summary type="html">&lt;p&gt;Jedbox: /* Add new Chapter */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Unit Testing and Joomla! =&lt;br /&gt;
&lt;br /&gt;
As we move forward with Joomla! Development one element that is going to be playing a larger and larger role is unit testing.  My hope with this short series is to provide some basic background on unit testing, to demonstrate how essential unit tests are to stable software and to give practical instruction and examples that illustrate how to write unit tests.&lt;br /&gt;
&lt;br /&gt;
As co-maintainer of the Joomla! Bug Squad, there is a question that repeatedly pops up: &#039;What is this change going to break?&#039;.  There are certain elements of the code base that can be rather fragile and this makes it very difficult to know what things are safe to touch and what things aren&#039;t.  The component routers are a good example of this.  We are very very hesitant to touch this because many people are very particular about their URLs, and past experience has shown that small changes can cause significant, unforeseen problems.&lt;br /&gt;
&lt;br /&gt;
Good unit tests take a great deal of the anxiety out of such changes because you can be confident that the change you are introducing is not going to have nasty, unforeseen consequences.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== What is Unit Testing? ==&lt;br /&gt;
&lt;br /&gt;
In its purest form, unit tests are tests that are designed to ensure that small units of code behave as they are intended.  Pure unit testing means that each method is tested in isolation from all other methods.  That is to say, for example, that if we are writing a test for JApplication, and JApplication happens to use the JDatabase class, we want to try and design our tests such that a bug in the JDatabase class won&#039;t affect our test written for the JApplication class.&lt;br /&gt;
&lt;br /&gt;
In practice, this can be difficult because sometimes class references are hardcoded.  Static methods are very difficult in this regard because you can&#039;t redefine classes and all tests in PHPUnit are executed in the same process.&lt;br /&gt;
&lt;br /&gt;
On the other end of the scale is system testing.  System tests are tests that are written to test a system as a whole.  In these tests, the goal isn&#039;t to isolate particular units of code.  Rather, it is to ensure that all the parts work together in the way they were intended.  For web applications, these tests are often developed using a product called Selenium which allows you to control a web browser in order to simulate a user actually using your web application.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Installing PHPUnit ==&lt;br /&gt;
&lt;br /&gt;
We are slowing building up an extensive suite of unit tests for the Joomla! Framework.  The tests are built on a unit testing framework called PHPUnit.  In order to run the tests, you need to obtain PHPUnit.&lt;br /&gt;
To get PHPUnit, head over to [http://www.phpunit.de/manual/current/en/installation.html PHPUnit Installation] and follow the instructions to install PHPUnit.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Running Tests ==&lt;br /&gt;
&lt;br /&gt;
Unit tests are typically run from the command line.  While this may be daunting for some, once you get the hang of things it is actually quite easy.&lt;br /&gt;
Once you have PHPUnit installed and your path setup correctly, it is as simple as changing to the unit test directory and typing &#039;phpunit&#039;:&lt;br /&gt;
cd /path/to/joomla/tests/unit&lt;br /&gt;
phpunit&lt;br /&gt;
After you run this command, you should see output that looks something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;PHPUnit 3.4.11 by Sebastian Bergmann.&lt;br /&gt;
&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIII...III..IIIIIIIIIIIIIIIIIIIIIIIIIIIIIII   60 / 2207&lt;br /&gt;
III...SIIIIII.IIIIIIIIIIIIII....................F.IIIIIIIIII  120 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  180 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  240 / 2207&lt;br /&gt;
IIIIIIIIIIIIIII.......................I.I...FFFFFEEEEEEEEEE.  300 / 2207&lt;br /&gt;
....FFFFF.EEEIIIIIIIII...IIIFFFFF.....SSSSFSSSSSSFSSSSSSSSSS  360 / 2207&lt;br /&gt;
SSSSSFSS......IIF.SFFFFFFF.......I........I.................  420 / 2207&lt;br /&gt;
.........III.II.IIII.IIII.I.........I.IIIII.IIII..........II  480 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  540 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIII.IIIIIIIIIIIIIII...........................  600 / 2207&lt;br /&gt;
...IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII  660 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIII..................................  720 / 2207&lt;br /&gt;
....................................................FFFF....  780 / 2207&lt;br /&gt;
............................................................  840 / 2207&lt;br /&gt;
............................................................  900 / 2207&lt;br /&gt;
............................................................  960 / 2207&lt;br /&gt;
............................................IIIIIIIIIIIIIIII 1020 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1080 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1140 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1200 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1260 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1320 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIII...I.....II.IIIIIIIIIIIIIIIIIIIIIIIIIIII 1380 / 2207&lt;br /&gt;
IIIIIIIIIIIIII.IIIIIIIIIII.........IIIIII.IIIIIIIIIIIIIIIIII 1440 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII..II.............. 1500 / 2207&lt;br /&gt;
.........F.F...........F..FFF................II....I...F..II 1560 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII 1620 / 2207&lt;br /&gt;
IIIIIIIIIIIIIIIIIII...F........IIIIIIIIIIIIIIIIIIIIIIIIIIIII 1680 / 2207&lt;br /&gt;
IIIIIIIIIIIIII..IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII........... 1740 / 2207&lt;br /&gt;
...F........................................................ 1800 / 2207&lt;br /&gt;
............................................................ 1860 / 2207&lt;br /&gt;
............................................................ 1920 / 2207&lt;br /&gt;
............................................................ 1980 / 2207&lt;br /&gt;
............................................................ 2040 / 2207&lt;br /&gt;
.........................F.................................. 2100 / 2207&lt;br /&gt;
............................F............................... 2160 / 2207&lt;br /&gt;
...............................F..I............&lt;br /&gt;
&lt;br /&gt;
Time: 14 seconds, Memory: 89.50Mb&lt;br /&gt;
&lt;br /&gt;
There were 13 errors:&lt;br /&gt;
&lt;br /&gt;
1) JCacheTest::testSetCaching with data set &amp;quot;simple&amp;quot; (&#039;output&#039;, array())&lt;br /&gt;
Undefined property: JCacheControllerOutput::$_options&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) JCacheTest::testSetCaching with data set &amp;quot;complexOutput&amp;quot; (&#039;output&#039;, array(&#039;&#039;, &#039;/home/ian/www/ut_work/unittest/cache&#039;, 900, &#039;file&#039;))&lt;br /&gt;
Undefined property: JCacheControllerOutput::$_options&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3) JCacheTest::testSetCaching with data set &amp;quot;complexPage&amp;quot; (&#039;page&#039;, array(&#039;&#039;, &#039;/home/ian/www/ut_work/unittest/cache&#039;, 900, &#039;file&#039;))&lt;br /&gt;
Undefined property: JCacheControllerPage::$_options&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
--&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There were 43 failures:&lt;br /&gt;
&lt;br /&gt;
1) JControllerFormTest::testConstructor&lt;br /&gt;
_asset_name has not been defined for structure&lt;br /&gt;
Failed asserting that an array has the key &amp;lt;string:_asset_name&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
2) JCacheTest::testGetInstance with data set &amp;quot;simple&amp;quot; (&#039;output&#039;, array(), &#039;JCacheOutput&#039;)&lt;br /&gt;
Failed asserting that &amp;lt;JCacheControllerOutput&amp;gt; is an instance of class &amp;quot;JCacheOutput&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
3) JCacheTest::testGetInstance with data set &amp;quot;complexOutput&amp;quot; (&#039;output&#039;, array(&#039;&#039;, &#039;/home/ian/www/ut_work/tests/unit/cache&#039;, 900, &#039;file&#039;), &#039;JCacheOutput&#039;)&lt;br /&gt;
Failed asserting that &amp;lt;JCacheControllerOutput&amp;gt; is an instance of class &amp;quot;JCacheOutput&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
4) JCacheTest::testGetInstance with data set &amp;quot;complexPage&amp;quot; (&#039;page&#039;, array(&#039;&#039;, &#039;/home/ian/www/ut_work/tests/unit/cache&#039;, 900, &#039;file&#039;), &#039;JCachePage&#039;)&lt;br /&gt;
Failed asserting that &amp;lt;JCacheControllerPage&amp;gt; is an instance of class &amp;quot;JCachePage&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
FAILURES!&lt;br /&gt;
Tests: 2207, Assertions: 1751, Failures: 43, Errors: 13, Incomplete: 1063, Skipped: 29.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are many situations where you may not want to run the whole test suite.  See the [[Running Unit Tests]] page for details on how to be selective with the tests that you run.&lt;br /&gt;
&lt;br /&gt;
== Anatomy of a Test ==&lt;br /&gt;
&lt;br /&gt;
Unit tests are merely small chunks of PHP code that:&lt;br /&gt;
# Setup certain preconditions for the code to be tested (inputs).&lt;br /&gt;
# Execute the code to be tested.&lt;br /&gt;
# Tests assertions about the results (outputs).&lt;br /&gt;
&lt;br /&gt;
We will see these basic elements in each of the example tests that are provided below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Writing Our First Test ==&lt;br /&gt;
&lt;br /&gt;
The easiest and most simple type of unit test to write is a test for code that is stateless.  That is, a test for which the return value of the method depends solely on the inputs to the method.  Most of the basic PHP functions are examples of stateless functions.  The strtoupper function, for example, takes one parameter – a string – and returns a string value.  You can easily create a set of inputs and corresponding outputs and write a test.&lt;br /&gt;
Examples in the Joomla! Framework include much of the JArrayHelper class.  Most of these methods are static methods and don&#039;t depend on anything except the data passed to the method.  For this example, we will use the JArrayHelper::getColumn method.  This method takes two parameters and returns an array.&lt;br /&gt;
So, following the  three steps outlined above, we break things down into three elements:&lt;br /&gt;
&lt;br /&gt;
=== 1. Setup Preconditions ===&lt;br /&gt;
&lt;br /&gt;
In this case, there are no preconditions because our method does not depend on anything other than the parameters that are passed to it.  Our only preconditions are the parameters that we pass to the method.&lt;br /&gt;
&lt;br /&gt;
=== 2. Execute the code to be tested ===&lt;br /&gt;
&lt;br /&gt;
So, our method in question will take an array of associative arrays or objects and will return an array of the values of the specified index.&lt;br /&gt;
So, to test our method, we first need to create an array of associative arrays:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$test_array = array(&lt;br /&gt;
	array(&lt;br /&gt;
		&#039;sport&#039; =&amp;gt; &#039;football&#039;,&lt;br /&gt;
		&#039;teams&#039; =&amp;gt; &#039;16&#039;,&lt;br /&gt;
		&#039;country&#039; =&amp;gt; &#039;United States&#039;&lt;br /&gt;
	).&lt;br /&gt;
	array(&lt;br /&gt;
		&#039;sport&#039; =&amp;gt; &#039;badminton&#039;,&lt;br /&gt;
		&#039;teams&#039; =&amp;gt; &#039;12&#039;,&lt;br /&gt;
		&#039;country&#039; =&amp;gt; &#039;Germany&#039;&lt;br /&gt;
	),&lt;br /&gt;
	array(&lt;br /&gt;
		&#039;sport&#039; =&amp;gt; &#039;basketball&#039;,&lt;br /&gt;
		&#039;teams&#039; =&amp;gt; &#039;20&#039;,&lt;br /&gt;
		&#039;country&#039; =&amp;gt; &#039;Canada&#039;&lt;br /&gt;
	)&lt;br /&gt;
);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we execute the method and retrieve the results:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$result_array = JArrayHelper::getColumn($test_array, &#039;country&#039;);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We have now executed the method we want to test.  We can now examine the results.&lt;br /&gt;
&lt;br /&gt;
=== 3. Tests assertions about the results (outputs) ===&lt;br /&gt;
&lt;br /&gt;
Since this method is fairly simple, testing the results is also simple.  What we need to do is figure out what we expect to get back from the method.  In this case, we expect to get an array containing an array of the countries.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$this-&amp;gt;assertThat(&lt;br /&gt;
    $result_array,&lt;br /&gt;
    $this-&amp;gt;equalTo(array(&#039;United States&#039;, &#039;Germany&#039;, &#039;Canada&#039;)),&lt;br /&gt;
    &#039;We did not get the proper column data back&#039;&lt;br /&gt;
);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Our final test looks like:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
public function testGetColumnTutorial()&lt;br /&gt;
{&lt;br /&gt;
	$test_array = array(&lt;br /&gt;
		array(&lt;br /&gt;
			&#039;sport&#039; =&amp;gt; &#039;football&#039;,&lt;br /&gt;
			&#039;teams&#039; =&amp;gt; &#039;16&#039;,&lt;br /&gt;
			&#039;country&#039; =&amp;gt; &#039;United States&#039;&lt;br /&gt;
		),&lt;br /&gt;
		array(&lt;br /&gt;
			&#039;sport&#039; =&amp;gt; &#039;badminton&#039;,&lt;br /&gt;
			&#039;teams&#039; =&amp;gt; &#039;12&#039;,&lt;br /&gt;
			&#039;country&#039; =&amp;gt; &#039;Germany&#039;&lt;br /&gt;
		),&lt;br /&gt;
		array(&lt;br /&gt;
			&#039;sport&#039; =&amp;gt; &#039;basketball&#039;,&lt;br /&gt;
			&#039;teams&#039; =&amp;gt; &#039;20&#039;,&lt;br /&gt;
			&#039;country&#039; =&amp;gt; &#039;Canada&#039;&lt;br /&gt;
		)&lt;br /&gt;
	);&lt;br /&gt;
&lt;br /&gt;
	$result_array = JArrayHelper::getColumn($test_array, &#039;country&#039;);&lt;br /&gt;
&lt;br /&gt;
	$this-&amp;gt;assertThat(&lt;br /&gt;
		$result_array,&lt;br /&gt;
		$this-&amp;gt;equalTo(&lt;br /&gt;
			array(&#039;United States&#039;, &#039;Germany&#039;, &#039;Canada&#039;)&lt;br /&gt;
		),&lt;br /&gt;
		&#039;We did not get the proper column data back&#039;&lt;br /&gt;
	);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== How a Unit Test should NOT be written ==&lt;/div&gt;</summary>
		<author><name>Jedbox</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=How_to_add_CSRF_anti-spoofing_to_forms&amp;diff=21351</id>
		<title>How to add CSRF anti-spoofing to forms</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=How_to_add_CSRF_anti-spoofing_to_forms&amp;diff=21351"/>
		<updated>2010-01-23T06:30:34Z</updated>

		<summary type="html">&lt;p&gt;Jedbox: /* Protecting Against CSRF Attakcs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== What is a CSRF Attack? ==&lt;br /&gt;
&lt;br /&gt;
A Cross Site Request Forgery ([[Wikipedia:Cross-site_request_forgery WikiPedia|CSRF]]) attack  relies on the trust a website has for a user to execute unauthorized requests and or transactions.  For example, say a user is logged into their Joomla! websites&#039; administrator interface in one tab and is browsing a compromised site in another tab.  A simple CSRF attack can be launched simply by tampering with IMG elements in some browsers so that they point to something like&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;http://some/joomla/site/administrator/index2.php?option=com_users&amp;amp;task=delete...&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
When the user browses the compromised site, that image will be requested and because the user is currently logged in to the administrator interface of her Joomla! site, the forged request will be positively authenticated and executed.  To prevent simple CSRF attacks like the one above, request tokens have been added to all forms in the front-end and back-end Joomla! interfaces.  The tokens are randomized strings that are used to authenticate that the request being made is coming from a valid form and a valid session.  This simple measure is very effective at preventing a large percentage of potential CSRF attacks, however, due to the nature of CSRF they are extremely difficult, if not impossible, to secure against completely.&lt;br /&gt;
&lt;br /&gt;
== Protecting Against CSRF Attacks ==&lt;br /&gt;
&lt;br /&gt;
Joomla! attempts to protect againt CSRF by inserting a random string called a token into each POST form and each GET query string that is able to modify something in the Joomla! system.  This random string provides protection because not only does the compromised site need to know the URL of the target site and a valid request format for the target site, it also must know the random string which changes for each session and each user.&lt;br /&gt;
&lt;br /&gt;
The {{jf}} makes it easy for you to include such protection in your components as well.  This is simple to implement in both POST and GET requests.&lt;br /&gt;
&lt;br /&gt;
=== POST Request ===&lt;br /&gt;
&lt;br /&gt;
POST requests are submitted in HTML using forms.  In order to add the token to your form, add the following line inside your form:&lt;br /&gt;
 &amp;lt;?php echo JHTML::_( &#039;form.token&#039; ); ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will output something like the following:&lt;br /&gt;
 &amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;1234567890abcdef1234567890abcdef&amp;quot; value=&amp;quot;1&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== GET Request ===&lt;br /&gt;
&lt;br /&gt;
GET requests are submitted in HTML using query strings.  In order to add the token to your query string, use a URL like:&lt;br /&gt;
 &amp;lt;?php &lt;br /&gt;
 echo JRoute::_( &#039;index.php?option=com_example&amp;amp;controller=object1&amp;amp;task=save&amp;amp;&#039;. JUtility::getToken() .&#039;=1&#039; ); &lt;br /&gt;
 ?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will generate a URL with the token in the query string.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Checking the Token ===&lt;br /&gt;
&lt;br /&gt;
Once you have included the token in your form or in your query string, you must check the token &#039;&#039;&#039;before your script carries out the request&#039;&#039;&#039;.  This is done with the following line:&lt;br /&gt;
 JRequest::checkToken() or die( &#039;Invalid Token&#039; );&lt;br /&gt;
&lt;br /&gt;
If the request is coming from the query string, you must specify this.  The code then becomes:&lt;br /&gt;
 JRequest::checkToken( &#039;get&#039; ) or die( &#039;Invalid Token&#039; );&lt;br /&gt;
&lt;br /&gt;
== Recommended Security Procedures ==&lt;br /&gt;
&lt;br /&gt;
While these methods help to prevent against these types of attacks, it is important to realize that as a system administrator, there are good security practices to follow which will prevent a site from being compromised.&lt;br /&gt;
&lt;br /&gt;
# Don&#039;t browse other sites in the same browser while you are logged into your site.&lt;br /&gt;
# Log out from your site after you are done.&lt;br /&gt;
# Don&#039;t stay logged into your site while you are not doing anything.&lt;br /&gt;
# Ensure that the address in the browser bar matches the address of your site.&lt;br /&gt;
&lt;br /&gt;
By practicing these safe surfing habits you will eliminate most threats to your web site.&lt;br /&gt;
&lt;br /&gt;
[[Category:FAQ]]&lt;br /&gt;
[[Category:Security_FAQ]]&lt;br /&gt;
[[Category:Security]]&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Jedbox</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=J1.5:How_to_create_a_language_pack&amp;diff=21031</id>
		<title>J1.5:How to create a language pack</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=J1.5:How_to_create_a_language_pack&amp;diff=21031"/>
		<updated>2010-01-02T09:56:17Z</updated>

		<summary type="html">&lt;p&gt;Jedbox: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{review}}&lt;br /&gt;
&lt;br /&gt;
Joomla! uses three language packages, one for the front end, one for the administrator and one for installation. Ideally you will create all three.&lt;br /&gt;
&lt;br /&gt;
A translation pack consists of an xml file, a blank index file and a set of *.ini files containing the language strings for your language. The easiest way to understand  this structure is to look at the files in the language/en-GB folder of your Joomla! installation. &lt;br /&gt;
&lt;br /&gt;
This is an excerpt from en-GB.mod_login.ini&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 BUTTON_LOGIN=Login&lt;br /&gt;
 BUTTON_LOGOUT=Logout&lt;br /&gt;
 DESCLOGINFORM=This Module displays a username and password Login form. It also displays a link to retrieve a forgotten password.  If User registration is enabled, (refer to the Global Configuration settings), then another link will be shown to invite Users to   self-register.&lt;br /&gt;
 ENCRYPT LOGIN FORM=Encrypt Login Form&lt;br /&gt;
 FORGOT_YOUR_PASSWORD=Forgot your password?&lt;br /&gt;
 FORGOT_YOUR_USERNAME=Forgot your username?&lt;br /&gt;
 GREETING=Greeting&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To create a package for your language you change the strings to the right of the =.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Many people find it helpful to use the [http://extensions.joomla.org/component/option,com_mtree/task,viewlink/link_id,1776/Itemid,35/  translation manager extension]. This helps by automating the creation of the files.&lt;br /&gt;
&lt;br /&gt;
Language naming convention in Joomla are &lt;br /&gt;
language and ISO code. Use 2 letters when available. [http://www.loc.gov/standards/iso639-2/php/code_list.php The list is available here.]&lt;br /&gt;
&lt;br /&gt;
[http://www.iso.org/iso/country_codes/iso_3166_code_lists/english_country_names_and_code_elements.htm  This reference concerns country codes]&lt;br /&gt;
&lt;br /&gt;
Because language strings may change it is best to create your packages using either [http://developer.joomla.org/code.html  the nightly build or subversion].&lt;br /&gt;
&lt;br /&gt;
Name of package should be: xx-XX //using your language&#039;s ISO code.&lt;br /&gt;
&lt;br /&gt;
Locale:&lt;br /&gt;
[http://forum.joomla.org/viewtopic.php?t=25077  Information on available locales may be found here.]&lt;br /&gt;
&lt;br /&gt;
If, for any reason, ini or xml  language files are edited manually with a text editor, they have to be saved with the encoding UTF8 NO BOM.&lt;br /&gt;
&lt;br /&gt;
For practical information on the way to make core Translation files for Joomla 1.0, please see forum: http://forum.joomla.org/viewtopic.php?f=11&amp;amp;t=254709.&lt;br /&gt;
&lt;br /&gt;
And for Joomla 1.5 see the forum:&lt;br /&gt;
[http://forum.joomla.org/viewtopic.php?f=11&amp;amp;t=88326&amp;amp;start=0 Building Extension&#039;s Language Pack for J1.5]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Languages]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jedbox</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=J1.5:How_to_create_a_language_pack&amp;diff=21030</id>
		<title>J1.5:How to create a language pack</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=J1.5:How_to_create_a_language_pack&amp;diff=21030"/>
		<updated>2010-01-02T09:54:57Z</updated>

		<summary type="html">&lt;p&gt;Jedbox: add ref to J1.5 Language pack forum&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{review}}&lt;br /&gt;
&lt;br /&gt;
Joomla! uses three language packages, one for the front end, one for the administrator and one for installation. Ideally you will create all three.&lt;br /&gt;
&lt;br /&gt;
A translation pack consists of an xml file, a blank index file and a set of *.ini files containing the language strings for your language. The easiest way to understand  this structure is to look at the files in the language/en-GB folder of your Joomla! installation. &lt;br /&gt;
&lt;br /&gt;
This is an excerpt from en-GB.mod_login.ini&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 BUTTON_LOGIN=Login&lt;br /&gt;
 BUTTON_LOGOUT=Logout&lt;br /&gt;
 DESCLOGINFORM=This Module displays a username and password Login form. It also displays a link to retrieve a forgotten password.  If User registration is enabled, (refer to the Global Configuration settings), then another link will be shown to invite Users to   self-register.&lt;br /&gt;
 ENCRYPT LOGIN FORM=Encrypt Login Form&lt;br /&gt;
 FORGOT_YOUR_PASSWORD=Forgot your password?&lt;br /&gt;
 FORGOT_YOUR_USERNAME=Forgot your username?&lt;br /&gt;
 GREETING=Greeting&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To create a package for your language you change the strings to the right of the =.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Many people find it helpful to use the [http://extensions.joomla.org/component/option,com_mtree/task,viewlink/link_id,1776/Itemid,35/  translation manager extension]. This helps by automating the creation of the files.&lt;br /&gt;
&lt;br /&gt;
Language naming convention in Joomla are &lt;br /&gt;
language and ISO code. Use 2 letters when available. [http://www.loc.gov/standards/iso639-2/php/code_list.php The list is available here.]&lt;br /&gt;
&lt;br /&gt;
[http://www.iso.org/iso/country_codes/iso_3166_code_lists/english_country_names_and_code_elements.htm  This reference concerns country codes]&lt;br /&gt;
&lt;br /&gt;
Because language strings may change it is best to create your packages using either [http://developer.joomla.org/code.html  the nightly build or subversion].&lt;br /&gt;
&lt;br /&gt;
Name of package should be: xx-XX //using your language&#039;s ISO code.&lt;br /&gt;
&lt;br /&gt;
Locale:&lt;br /&gt;
[http://forum.joomla.org/viewtopic.php?t=25077  Information on available locales may be found here.]&lt;br /&gt;
&lt;br /&gt;
If, for any reason, ini or xml  language files are edited manually with a text editor, they have to be saved with the encoding UTF8 NO BOM.&lt;br /&gt;
&lt;br /&gt;
For practical information on the way to make core Translation files for Joomla 1.0, please see forum: http://forum.joomla.org/viewtopic.php?f=11&amp;amp;t=254709.&lt;br /&gt;
&lt;br /&gt;
And for Jommla 1.5 see:&lt;br /&gt;
[http://forum.joomla.org/viewtopic.php?f=11&amp;amp;t=88326&amp;amp;start=0 Building Extension&#039;s Language Pack for J1.5]&lt;br /&gt;
&amp;lt;noinclude&amp;gt;[[Category:Languages]]&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jedbox</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Joomla_Translation_Program&amp;diff=21029</id>
		<title>Joomla Translation Program</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Joomla_Translation_Program&amp;diff=21029"/>
		<updated>2010-01-02T09:49:39Z</updated>

		<summary type="html">&lt;p&gt;Jedbox: add Languages Category&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;&#039;&#039;&amp;quot;...providing support for the international community is a core value of Joomla!...&amp;quot;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
[[Image:Workgroups_translation.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
The purpose of the Translation Team within the Production Working Group is to be a liaison between the Joomla! Translation Teams, the International Community and the other Joomla! Teams on user and technical matters relating to the translation of the Joomla! application.&lt;br /&gt;
&lt;br /&gt;
The Translation Working Group carries out its work according to the [http://community.joomla.org/translations/translation-policy.html Joomla! Translation and Localization Policy]. &lt;br /&gt;
&lt;br /&gt;
The Translation Working Group is also called the Joomla! Translation Coordination Team. It is composed of members of the Joomla! Translation Teams.&lt;br /&gt;
See a list of [http://forum.joomla.org/memberlist.php?mode=group&amp;amp;g=47 current members here].&lt;br /&gt;
&lt;br /&gt;
We have more than 50 local language coordinators representing their local teams.&lt;br /&gt;
See a list of [http://forum.joomla.org/memberlist.php?mode=group&amp;amp;g=13 current members here].&lt;br /&gt;
These Teams are also listed on a per language basis: [http://community.joomla.org/translations.html current languages here]&lt;br /&gt;
&lt;br /&gt;
The resources provided by these teams are available on a common repository on joomlacode: [http://joomlacode.org/gf/project/jtranslation/frs/ 1.5 language packs]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== How can you help? ==&lt;br /&gt;
&lt;br /&gt;
Joomla! Project wish to see the Joomla! CMS made available in any language.&lt;br /&gt;
&lt;br /&gt;
For that to become possible we need the help from talented native speakers who wish to contribute by translating Joomla! 1.5 language packages into their native language.&lt;br /&gt;
&lt;br /&gt;
To create a translation you must create a [http://docs.joomla.org/How_to_create_a_language_pack Joomla! language pack]. [[Technical Guidelines for Translation]]&lt;br /&gt;
&lt;br /&gt;
In case your language is not currently available at this list [http://joomlacode.org/gf/project/jtranslation/frs/ at joomlacode] and you have already created a local translation then please follow these steps:&lt;br /&gt;
&lt;br /&gt;
1. Create a user and a new project at [http://joomlacode.org/gf/ joomlacode]&lt;br /&gt;
&lt;br /&gt;
2. When project approved and you have uploaded your language files then please post in the Translation forum&lt;br /&gt;
&lt;br /&gt;
Should your language already be listed and you wish to contribute then please start by contacting [http://community.joomla.org/translations.html the local Translation Coordinator] .&lt;br /&gt;
&lt;br /&gt;
If your language is not listed and you want to join the Joomla! Translation Teams, please contact [http://forum.joomla.org/memberlist.php?mode=group&amp;amp;g=47 a member of the Coordination].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Do you have language and/or translation questions? ==&lt;br /&gt;
&lt;br /&gt;
For questions about language please visit language forums at:&lt;br /&gt;
&lt;br /&gt;
[[jforum:309|Joomla! 1.0.x language forum]]&lt;br /&gt;
&lt;br /&gt;
[[jforum:485|Joomla! 1.5.x language forum]]&lt;br /&gt;
&lt;br /&gt;
For questions about translation please visit translation forum at:&lt;br /&gt;
&lt;br /&gt;
[[jforum:11|Translations]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Thanks.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Translations Working Group]]&lt;br /&gt;
[[Category:Languages]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jedbox</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Intermediate_Selenium_Example&amp;diff=20857</id>
		<title>Intermediate Selenium Example</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Intermediate_Selenium_Example&amp;diff=20857"/>
		<updated>2009-12-21T19:13:32Z</updated>

		<summary type="html">&lt;p&gt;Jedbox: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Writing a More Advanced Selenium Test ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now that you have created your first simple test, let&#039;s try something a little more advanced.&lt;br /&gt;
&lt;br /&gt;
Let&#039;s write a test that verifies the functionality of creating and deleting a user.&lt;br /&gt;
&lt;br /&gt;
We will start by browsing to the login screen of the administrator panel of our Joomla site.&lt;br /&gt;
&lt;br /&gt;
Then, we will open up [http://docs.joomla.org/Functional_Testing Selenium] IDE.&lt;br /&gt;
&lt;br /&gt;
You should notice that the record button is highlighted, which means we are recording.&lt;br /&gt;
&lt;br /&gt;
Go back to the main browser window and enter the username and password for a Super Administrator user.&lt;br /&gt;
&lt;br /&gt;
* Click Site, and select User Manager&lt;br /&gt;
* Click New&lt;br /&gt;
* Enter some details, such as:&lt;br /&gt;
** Name: My Test User&lt;br /&gt;
** Username: TestUser&lt;br /&gt;
** E-mail: test@example.com&lt;br /&gt;
** Password: password&lt;br /&gt;
** Group: Registered&lt;br /&gt;
* Click Save&lt;br /&gt;
* Highlight the text &#039;Successfully saved User: My Test User&#039;&lt;br /&gt;
* Right Click and Select &#039;assertTextPresent Successfully saved User: My Test User&#039;&lt;br /&gt;
* Enter TestUser into the Filter text box and click Go&lt;br /&gt;
* Highlight the username TestUser, right click and Select &#039;AssertText&#039;&lt;br /&gt;
* Right click on the User link and select &#039;AssertText&#039;&lt;br /&gt;
* Browse to the frontend of your site&lt;br /&gt;
* Go to the Login form and enter your credentials, and click Login&lt;br /&gt;
* Highlight the text &#039;Hi TestUser&#039;, right click and select &#039;AssertTextPresent &#039;Hi TestUser&#039;&lt;br /&gt;
* Click Logout&lt;br /&gt;
* Browse to the admin panel of your site&lt;br /&gt;
* Go the user manager&lt;br /&gt;
* Select the Checkbox for &#039;My Test User&#039;&lt;br /&gt;
* Click Delete&lt;br /&gt;
* Click Logout&lt;br /&gt;
&lt;br /&gt;
And we&#039;re done recording.&lt;br /&gt;
&lt;br /&gt;
Now, due to some quirks in Selenium, there are some things that we need to fix.  There are two main quirks that we need to look at:&lt;br /&gt;
1. For some reason, entering the password in the administrator does not get recorded.  We have to add a manual command for this.&lt;br /&gt;
2. Selenium often misses the step of going to a new URL via the browser address bar.  We have to add these manually.&lt;br /&gt;
&lt;br /&gt;
To fix the first problem, we do the following&lt;br /&gt;
* Click on the first &#039;ClickAndWait&#039; (with Target link=Login).&lt;br /&gt;
* Right Click and select &#039;Insert New Command&#039;&lt;br /&gt;
* The command should be Type, the Target should be modlgn_passwd and the Value should be the password for your admin user.&lt;br /&gt;
&lt;br /&gt;
To fix the second problem:&lt;br /&gt;
* scroll down through your command list until you find the second type - modlgn_username.  click on this command.&lt;br /&gt;
* Right Click and select &#039;Insert New Command&#039;&lt;br /&gt;
* The command should be open, and the Target should be the path to your Joomla frontend.&lt;br /&gt;
* scroll down through your command list until you find clickAndWait - link=User Manager&lt;br /&gt;
* Enter a new command there also - the command should be open, and the Target should be the path to your Joomla Administrator panel.&lt;br /&gt;
&lt;br /&gt;
Your test should then be ready to go.&lt;br /&gt;
&lt;br /&gt;
[[Category:Testing]]&lt;/div&gt;</summary>
		<author><name>Jedbox</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=System_Testing&amp;diff=20759</id>
		<title>System Testing</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=System_Testing&amp;diff=20759"/>
		<updated>2009-12-13T20:37:08Z</updated>

		<summary type="html">&lt;p&gt;Jedbox: /* Running Functional Tests */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== News and Updates ==&lt;br /&gt;
2009 07 27 Document created.&lt;br /&gt;
&lt;br /&gt;
== Functional Testing ==&lt;br /&gt;
Functional (or system) testing is an essential part of a good Quality Control program.&lt;br /&gt;
For a good general discussion of functional testing, visit the [http://en.wikipedia.org/wiki/Functional_Testing Wikipedia article].&lt;br /&gt;
&lt;br /&gt;
=== Functional Testing in Open Source ===&lt;br /&gt;
Web applications have been notoriously difficult to do functional testing with. It has traditionally required a great deal of time and effort. This can be a special challenge for open source projects because testing is often not very popular and designing tests that can be executed in a systematic way even less so. For a complicated application like Joomla!, this means that although we might do testing, we very seldom are able to perform extensive testing on each release that covers even a fraction of the elements in the CMS.&lt;br /&gt;
&lt;br /&gt;
Relatively recently, a project called Selenium has arrived on the scene.  This project makes performing automated functional testing of web applications possible. This means that it is possible to devise a test and have it performed in an automated way without the requirement of somebody sitting in front of a browser and being a click monkey.&lt;br /&gt;
&lt;br /&gt;
The benefits of functional testing are:&lt;br /&gt;
* Functional tests help highlight cases where changes in one element of the system might cause breakage in other, unexpected areas.&lt;br /&gt;
* Functional tests help clearly specify how the application should behave.&lt;br /&gt;
&lt;br /&gt;
=== Functional Testing versus Unit Testing ===&lt;br /&gt;
In order to fully test an application, both functional and unit testing are essential. Each approach has their benefits and weaknesses. Unit testing is very good for isolating small chunks of code and ensuring that they are behaving as expected. Functional testing, on the other hand, is geared towards looking at the system as a whole and ensuring that the units are behaving together in a way that achieves the desired effect.&lt;br /&gt;
&lt;br /&gt;
The advantages of functional testing is that functional tests are easier to understand and conceptualize by people who are unfamiliar with the underlying code. With Selenium, tests can be designed by people who are not overly familiar with PHP - they only need to understand the application and what results should be expected.&lt;br /&gt;
&lt;br /&gt;
The downside of functional testing is that it will only tell you that something broke. It isn&#039;t as obvious with functional testing exactly what went wrong or where the problem is.&lt;br /&gt;
&lt;br /&gt;
==== Test Objects ====&lt;br /&gt;
If the purpose of unit tests is to isolate a module of code, then the purpose of functional tests is to evaluate the entire system. This is much easier for those unfamiliar with what happens under the hood of Joomla! because one is not required to understand what happens during a Joomla! page request. A functional test might evaluate, for example, if unpublishing an article works properly. Therefore, to design the test, it is only necessary to figure out how to change an article from Published to Unpublished, and how to verify that the article was actually unpublished.&lt;br /&gt;
&lt;br /&gt;
=== Functional Testing in Joomla! ===&lt;br /&gt;
I have recently been building a functional testing architecture that will make it possible to write tests once, and to execute those tests on a variety of platforms and clients. I currently have infrastructure in place that makes it possible to run one command and execute functional tests in one browser on one host system. I have designed the host system in such a way that it will run on 6 different PHP versions (stock Ubuntu PHP 5 and self-compiled PHP 4.3, 4.4, 5.0, 5.1 and 5.2) and 2 different web servers (Apache and Lighttpd).  These are all currently serving from the same database.&lt;br /&gt;
&lt;br /&gt;
The future steps will be to make it possible to run on multiple host systems (the requirement for this is to generalize the code that resets the database state after the tests are run) and to make it possible to use different clients (i.e. different systems with different web browsers). These steps should be fairly trivial, but I have not yet had time to focus on them.&lt;br /&gt;
&lt;br /&gt;
This will eventually make it possible to run the designed tests on every major browser and on multiple server platforms (various PHP versions, various configurations, various operating systems and various web servers).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Writing Functional Tests ====&lt;br /&gt;
Selenium IDE makes it fairly easy to write functional tests. It is a Firefox extension that operates as an Integrated Development Environment for creating functional tests. In essence, it records your clicks as you navigate in your browser and encodes them into a series of commands that can control the browser.&lt;br /&gt;
&lt;br /&gt;
===== Getting Selenium IDE =====&lt;br /&gt;
At the time of writing, the latest version of Selenium IDE is 1.0.2.  You can get it at http://seleniumhq.org/download/. Click on the download link and install like you would any Firefox plugin.&lt;br /&gt;
&lt;br /&gt;
===== Preparing your Environment =====&lt;br /&gt;
To get started, create a vanilla install of Joomla! with the standard sample data.&lt;br /&gt;
&lt;br /&gt;
===== Creating a Basic Test =====&lt;br /&gt;
To start, open Firefox and browse to the home page of your Joomla! install.  I setup my install on my localhost, and so the URL is http://127.0.0.1/selsampledata.&lt;br /&gt;
&lt;br /&gt;
Then, click on Tools -&amp;gt; Selenium IDE. You will notice that on the right of the window that appears near the top, that there is a red circle that is highlighted. This is the start/stop recording button. When you start Selenium IDE, recording starts right away.&lt;br /&gt;
&lt;br /&gt;
For our first test, all we will do is load up the home page and check to make sure that all the items in the Main Menu are present.&lt;br /&gt;
&lt;br /&gt;
The commands that we use to check that items are present are called assertions. Basically, you perform your actions and make assertions about the results.&lt;br /&gt;
&lt;br /&gt;
In our case, we are going to use the command assertText. This command will read the text of a specified element and ensure it matches a particular value.&lt;br /&gt;
&lt;br /&gt;
So, first ensure that the Base URL displayed in the Selenium IDE window is the home page of your Joomla! install.&lt;br /&gt;
&lt;br /&gt;
Then, switch to the window that has your Joomla install open.&lt;br /&gt;
&lt;br /&gt;
In that window, right click on each menu item and select &#039;Assert Text&#039;.&lt;br /&gt;
&lt;br /&gt;
Then, switch to your Selenium IDE window and click the Red Button to stop recording.&lt;br /&gt;
&lt;br /&gt;
You should see two tabs in your Selenium IDE window - one labeled Table, and one labeled Source. You don&#039;t really need to look at the Source window.&lt;br /&gt;
&lt;br /&gt;
So, now our first test is done.&lt;br /&gt;
&lt;br /&gt;
To run your test, you use the icons on the bar between the Base URL address bar and the Table and Source tabs. The two important buttons are the buttons with the Green Triangle with Three Solid rectangles and the one with the Green Triangle and One Solid Rectangle. The first one will execute the entire test suite and the second one will run the currently selected test case. Since we currently have only one test case, both of these currently do the same thing.&lt;br /&gt;
&lt;br /&gt;
To run your test, press one of these buttons.&lt;br /&gt;
&lt;br /&gt;
As you watch the Selenium IDE, you will see a yellow bar move down your list of steps. Once a step is completed, a successfully executed action (i.e. a button was successfully located and clicked) should show up in light green and a successful assertion should show up in darker green. Failed actions show up in light red and failed assertions show up in darker red.&lt;br /&gt;
&lt;br /&gt;
Click on the Window Expander on the left to unhide the Test Case browser.&lt;br /&gt;
&lt;br /&gt;
If your test completed successfully, you should see Runs: 1, Failures: 0 at the bottom of the Test Case browser.&lt;br /&gt;
&lt;br /&gt;
==== Running Functional Tests ====&lt;br /&gt;
&lt;br /&gt;
=== Joomla Core Selenium testcases ===&lt;br /&gt;
The testing repository for the Selenium test suite can be found here:&lt;br /&gt;
&lt;br /&gt;
* [http://joomlacode.org/svn/joomla/testing/trunk/1.5/functionaltest/selenium/ http://joomlacode.org/svn/joomla/testing/trunk/1.5/functionaltest/selenium/]&lt;br /&gt;
* [http://joomlacode.org/svn/joomla/testing/trunk/1.6/functionaltest/selenium/ http://joomlacode.org/svn/joomla/testing/trunk/1.6/functionaltest/selenium/]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Note: If a login mask comes up, use &amp;lt;/br&amp;gt;&lt;br /&gt;
:User: anonymous &amp;lt;/br&amp;gt;&lt;br /&gt;
:Password: &amp;lt;empty&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== How to Get it Running ==&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Frequently Asked Questions ==&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
For writing a more advanced Selenium testcase see [http://docs.joomla.org/Intermediate_Selenium_Example here].&lt;br /&gt;
&lt;br /&gt;
[http://seleniumhq.org/docs/ Selenium documentation].&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;br /&gt;
[[Category:Testing]]&lt;br /&gt;
[[Category:Bug Squad]]&lt;/div&gt;</summary>
		<author><name>Jedbox</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Unit_Testing&amp;diff=20756</id>
		<title>Unit Testing</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Unit_Testing&amp;diff=20756"/>
		<updated>2009-12-13T20:22:29Z</updated>

		<summary type="html">&lt;p&gt;Jedbox: /* See also */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{cookiejar}}&lt;br /&gt;
== News and Updates ==&lt;br /&gt;
2009 10 06: Tests now depend on the SVN version of PHPUnit 3.4.1.&lt;br /&gt;
&lt;br /&gt;
2008 06 24: Update to reflect move of PHPUnit code from branch to trunk (former trunk now in /branches/old_simpletest).&lt;br /&gt;
&lt;br /&gt;
2008 06 22: Add information on limiting tests by version.&lt;br /&gt;
&lt;br /&gt;
2008 06 21: Added --class-exclude, --sequence-exclude, and --test-exclude options.&lt;br /&gt;
&lt;br /&gt;
2008 06 21: PHPUnit has been updated to version 3.2.21 with SVN rev 10436. Please update.&lt;br /&gt;
&lt;br /&gt;
== Unit Testing ==&lt;br /&gt;
Unit testing is an essential part of a good Quality Control program.&lt;br /&gt;
For a good general discussion of unit testing, visit the [http://en.wikipedia.org/wiki/Unit_test Wikipedia article].&lt;br /&gt;
&lt;br /&gt;
=== Unit Testing in Open Source ===&lt;br /&gt;
Open source projects, with multiple developers working in parallel around the world, can greatly benefit from unit testing. The main benefits are:&lt;br /&gt;
* Unit tests help highlight cases where seemingly minor changes cause unexpected breakage.&lt;br /&gt;
* Unit tests help clearly specify how a class should behave.&lt;br /&gt;
* Unit tests can expose design flaws very early in development.&lt;br /&gt;
* Unit tests make great examples. They are a great place for developers to learn how to use the code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Testing Hierarchy: Unit, Subsystem, Integrated ===&lt;br /&gt;
Software testing systems usually run through a spectrum from &amp;quot;pure&amp;quot; unit tests through to fully integrated systems tests. We&#039;ve described low level unit tests above. Integrated testing typically involves some sort of script that simulates user actions and then verifies that the result matches what&#039;s expected. This sort of &amp;quot;end to end&amp;quot; test verifies that all parts of the system are working correctly.&lt;br /&gt;
&lt;br /&gt;
It&#039;s unfortunate that there is no clear nomenclature to describe all the intermediate stages of testing. The next stage beyond testing a single unit of code is subsystem testing. A subsystem test verifies that two or more units of code are interacting correctly to produce the desired result. In the simplest case, a subsystem test can be created simply by replacing mock objects with real objects and running unit tests on the top level module. In practise, this tends to not work as well as expected, because the original unit test data wasn&#039;t designed for a subsystem test, or because the nature of the test cases needs to be changed in order to fully test the subsystem. After all there is little point in simply repeating the unit test cases; the objective of a subsystem test should be to test boundary conditions and special cases that would be difficult to duplicate in unit tests.&lt;br /&gt;
&lt;br /&gt;
Once a subsystem has been tested, it can be integrated into a larger system, which is still a subset of the whole product. Tests can be written for larger and larger subsystems, but at each stage the complexity of the tests increases. At some point, the effort required to hand craft tests exceeds the benefits of running them. This is where integrated testing comes in.&lt;br /&gt;
&lt;br /&gt;
Integrated testing involves recording a user&#039;s interaction with the system into a script that can be replayed. The testing framework then compares the system&#039;s response with the expected response and passes or fails the test. The PHPUnit testing framework that we use has the ability to work with [http://seleniumhq.org/ Selenium], a browser based test automation tool. Writing a functional test using Selenium is documented [http://docs.joomla.org/Functional_Testing#Writing_Functional_Tests here].&lt;br /&gt;
&lt;br /&gt;
==== Test Objects ====&lt;br /&gt;
The purpose of unit tests is to isolate a module of code. A test that tests only one thing provides better information than a test that involves several object interactions. But how do we isolate an object from its dependencies? By writing stub classes. [http://xunitpatterns.com/Mocks,%20Fakes,%20Stubs%20and%20Dummies.html xUnit Patterns] defines a the hierarchy of dummy classes, ranging from simple to complex:&lt;br /&gt;
* Dummy - Defines attributes and methods of a dummy class (not particularly useful in PHP).&lt;br /&gt;
* Fake - Provides canned responses to method calls and fixed attribute values. Good for speed.&lt;br /&gt;
* Stub - Allows the test to define responses to method calls (return values, exceptions) to simulate the dependent object.&lt;br /&gt;
* Spy - A Fake or Stub that records method calls and parameters for later analysis.&lt;br /&gt;
* Mock - A Fake or Stub with a set of expectations -- method calls and parameters -- that are automatically verified for correctness.&lt;br /&gt;
&lt;br /&gt;
=== Unit Testing in Joomla! ===&lt;br /&gt;
Unit testing capabilities in Joomla are still at an early stage. The intention is to define more standards for developing tests, and then to expand the scope of available tests.&lt;br /&gt;
&lt;br /&gt;
For an overview of unit testing status in Joomla visit the [[Unit_Testing_Status]] page.&lt;br /&gt;
&lt;br /&gt;
The SVN repository contains code under the /testing path. /testing/trunk used to contain code based on the SimpleTest framework. In early December 2007, the development team elected to move to the [http://www.phpunit.de PHPUnit] framework.&lt;br /&gt;
&lt;br /&gt;
The PHPUnit tests are available from &#039;&#039;&#039;/testing/trunk&#039;&#039;&#039;. Some new tests have been added, any remaining tests from the SimpleTest days are completely broken. See /testing/branches/old-simpletest if you need to run something from that suite.&lt;br /&gt;
&lt;br /&gt;
The unit tests are located in two places:&lt;br /&gt;
* /testing/trunk/1.5/unittest - these are tests for Joomla! 1.5 (/development/releases/1.5)&lt;br /&gt;
* /testing/trunk/1.6/unittest - there are tests for Joomla! 1.6 (/development/trunk)&lt;br /&gt;
&lt;br /&gt;
At this point, PHPUnit based tests only run in a command line environment.&lt;br /&gt;
&lt;br /&gt;
==== The Unit Test Team ====&lt;br /&gt;
If you can commit to the Joomla code base, then you should consider yourself part of the unit test team!&lt;br /&gt;
&lt;br /&gt;
Writing tests concurrently with code (or even before) is a good way to not only save development time, but a great tool for defending against regressions. Writing tests early in the development cycle also helps identify and resolve design issues sooner, which reduces refactoring.&lt;br /&gt;
&lt;br /&gt;
If you want to get started on unit testing, get in touch with Alan Langford (instance) or Ray Tsai (mihu). Either of us will be happy to help out.&lt;br /&gt;
&lt;br /&gt;
==== Current Work ====&lt;br /&gt;
* There is no longer any need to patch the main code to enable unit tests.&lt;br /&gt;
* Basic techniques for mock objects are defined.&lt;br /&gt;
* Strategies for dealing with local configuration is not yet complete, but there is a plan.&lt;br /&gt;
* Files of the form class-sequence-type-Test.php, for example JObject-0000-class-Test.php use PHPUnit.&lt;br /&gt;
* The JDate tests present a good example of a data-driven test, but they won&#039;t run on the current 1.5 code base (there are some proposed API changes as a result of unit test development).&lt;br /&gt;
* Previously functional tests, such as JFTP, haven&#039;t been moved to the PHPUnit environment yet.&lt;br /&gt;
* The custom test runner is no longer needed. The current tests will run with the latest SVN version of PHPUnit 3.4. This code will eventually become PHPUnit 3.4.1.  Thanks to Sebastian Bergmann for his excellent work on an excellent project!&lt;br /&gt;
&lt;br /&gt;
==== Writing Unit Tests ====&lt;br /&gt;
At risk of stating the obvious, in the &amp;quot;purest&amp;quot; case the purpose of a unit test is to &#039;&#039;isolate a unit of code from its environment and to test the operation of that code&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
This isolation is usually achieved by writing dummy classes that emulate the code unit&#039;s environment. These dummy objects can be passive, by simply simulating the environment, or they can be more active, keeping track of how they are being used by the test unit and reporting any variations from the expected behaviour. See [[Unit_Testing_Mock_Objects|Mock Objects in Joomla]] for a detailed example.&lt;br /&gt;
&lt;br /&gt;
An interesting aspect of writing tests is that they become &#039;&#039;de facto&#039;&#039; detailed technical specifications of the interfaces between units of code. The fact that these specifications can be verified in an automated way makes them a superb resource when refactoring code.&lt;br /&gt;
&lt;br /&gt;
The test code has a few templates designed to kick-start a test. They are:&lt;br /&gt;
&lt;br /&gt;
/unittest/sample-datatest-php.txt&lt;br /&gt;
/unittest/sample-simpletest.php.txt&lt;br /&gt;
&lt;br /&gt;
Here are some example tests: [[Unit_Testing_--_a_Simple_Example|Simple Example]], [[Unit_Testing_--_Data_Driven_Example|Data Driven Example]], [[Unit_Testing_--_Plugin_Example|Plugin Example]], [[Unit_Testing_--_UI_Example|UI Example]].&lt;br /&gt;
&lt;br /&gt;
==== Running Unit Tests ====&lt;br /&gt;
Test files follow the form class-sequence-type-Test.php, for example JObject-0000-class-Test.php. For tests that are not class based, the first element refers to the object being tested. An example of this is the e-mail cloaking plugin test, which is called emailcloak-0000-mode1-Test.php.&lt;br /&gt;
&lt;br /&gt;
Joomla unit tests use the standard PHPUnit test runner.  See http://www.phpunit.de for documentation.&lt;br /&gt;
&lt;br /&gt;
== How to Get it Running ==&lt;br /&gt;
&lt;br /&gt;
Before you start make sure you have installed PHPUnit and of course PHP (5!) properly...&lt;br /&gt;
&lt;br /&gt;
To get the unit tests to run on your Joomla! installation, perform the following steps:&lt;br /&gt;
* Create an instance of your Joomla! installation. Since you will be using SVN to check out the testing project, you don&#039;t want to check out the Joomla! with SVN. Instead, simply unpack a normal Joomla! archive. If you are using Eclipse, you can create a folder in your Eclipse workspace for the Joomla! installation, but don&#039;t create an Eclipse project yet.&lt;br /&gt;
* In the root checkout (or export) the latest version of the unit test code from SVN &#039;&#039;&amp;quot;/testing/trunk/1.5/unittest&amp;quot;&#039;&#039; or &#039;&#039;&amp;quot;/testing/trunk/1.6/unittest&amp;quot;&#039;&#039; to your installation base. This will create a &#039;&#039;&amp;quot;/unittest&amp;quot;&#039;&#039; sub-folder under your joomla installation. If you are using Eclipse, Import the project from the SVN and use the same folder in your Eclipse workspace you used above.&lt;br /&gt;
* From the command line, change to the unittest directory.&lt;br /&gt;
* Run the unit test from the command prompt using the following command: &amp;lt;code&amp;gt;phpunit tests&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The unit test will the run, and the results are rendered. You will see a series of dots for each passed test and other letters for failed tests. &lt;br /&gt;
&lt;br /&gt;
See http://www.phpunit.de/manual/current/en/textui.html for help using the --filter switch to run only certain tests.  There are also many other command line switches you can use to get results in various formats.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
The provided configurations should work out of the box. We have seen problems with it (currently the cause is unknown). If you get an error like below, the solution is pretty easy.&lt;br /&gt;
&lt;br /&gt;
 file=/var/www/unittest/runtests.php&lt;br /&gt;
 posn=17&lt;br /&gt;
 base=runtests.php&lt;br /&gt;
 /var/www&lt;br /&gt;
  JPATH_BASE does not point to a valid Joomla! installation:&lt;br /&gt;
 JPATH_BASE = /var/www&lt;br /&gt;
  Please modify your copy of &amp;quot;TestConfiguration.php&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Modify the &#039;&#039;&amp;quot;TestConfiguration.php&amp;quot;&#039;&#039; file and change the definition of the JPATH_BASE so it points to the path of you Joomla! installation, in the example below the Joomla! installation is installed at &amp;quot;&#039;&#039;/var/www/update&#039;&#039;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 define(&#039;JPATH_BASE&#039;, &#039;/var/www/update&#039;);&lt;br /&gt;
&lt;br /&gt;
== Frequently Asked Questions ==&lt;br /&gt;
&#039;&#039;&#039;Why can&#039;t I use &amp;quot;phpunit &#039;&#039;testname.php&#039;&#039;&amp;quot; to run my tests?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The test facility has to do some work to be able to load the &amp;quot;Joomla!&amp;quot; framework and to be able to inject mock classes. It&#039;s difficult to do this from the PHPUnit test runner, so we built our own. Also, the Joomla test runner has specific options designed to make it easy to select specific tests. Over time we will add more functionality to the test runner so it has many of the capabilities of the phpunit command.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
[http://www.phpunit.de/manual/current/en/ PHPUnit Manual]&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;br /&gt;
[[Category:Testing]]&lt;/div&gt;</summary>
		<author><name>Jedbox</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Intermediate_Selenium_Example&amp;diff=20755</id>
		<title>Intermediate Selenium Example</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Intermediate_Selenium_Example&amp;diff=20755"/>
		<updated>2009-12-13T20:21:17Z</updated>

		<summary type="html">&lt;p&gt;Jedbox: /* Writing a More Advanced Test */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Writing a More Advanced Selenium Test ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now that you have created your first simple test, let&#039;s try something a little more advanced.&lt;br /&gt;
&lt;br /&gt;
Let&#039;s write a test that verifies the functionality of creating and deleting a user.&lt;br /&gt;
&lt;br /&gt;
We will start by browsing to the login screen of the administrator panel of our Joomla site.&lt;br /&gt;
&lt;br /&gt;
Then, we will open up Selenium IDE.&lt;br /&gt;
&lt;br /&gt;
You should notice that the record button is highlighted, which means we are recording.&lt;br /&gt;
&lt;br /&gt;
Go back to the main browser window and enter the username and password for a Super Administrator user.&lt;br /&gt;
&lt;br /&gt;
* Click Site, and select User Manager&lt;br /&gt;
* Click New&lt;br /&gt;
* Enter some details, such as:&lt;br /&gt;
** Name: My Test User&lt;br /&gt;
** Username: TestUser&lt;br /&gt;
** E-mail: test@example.com&lt;br /&gt;
** Password: password&lt;br /&gt;
** Group: Registered&lt;br /&gt;
* Click Save&lt;br /&gt;
* Highlight the text &#039;Successfully saved User: My Test User&#039;&lt;br /&gt;
* Right Click and Select &#039;assertTextPresent Successfully saved User: My Test User&#039;&lt;br /&gt;
* Enter TestUser into the Filter text box and click Go&lt;br /&gt;
* Highlight the username TestUser, right click and Select &#039;AssertText&#039;&lt;br /&gt;
* Right click on the User link and select &#039;AssertText&#039;&lt;br /&gt;
* Browse to the frontend of your site&lt;br /&gt;
* Go to the Login form and enter your credentials, and click Login&lt;br /&gt;
* Highlight the text &#039;Hi TestUser&#039;, right click and select &#039;AssertTextPresent &#039;Hi TestUser&#039;&lt;br /&gt;
* Click Logout&lt;br /&gt;
* Browse to the admin panel of your site&lt;br /&gt;
* Go the user manager&lt;br /&gt;
* Select the Checkbox for &#039;My Test User&#039;&lt;br /&gt;
* Click Delete&lt;br /&gt;
* Click Logout&lt;br /&gt;
&lt;br /&gt;
And we&#039;re done recording.&lt;br /&gt;
&lt;br /&gt;
Now, due to some quirks in Selenium, there are some things that we need to fix.  There are two main quirks that we need to look at:&lt;br /&gt;
1. For some reason, entering the password in the administrator does not get recorded.  We have to add a manual command for this.&lt;br /&gt;
2. Selenium often misses the step of going to a new URL via the browser address bar.  We have to add these manually.&lt;br /&gt;
&lt;br /&gt;
To fix the first problem, we do the following&lt;br /&gt;
* Click on the first &#039;ClickAndWait&#039; (with Target link=Login).&lt;br /&gt;
* Right Click and select &#039;Insert New Command&#039;&lt;br /&gt;
* The command should be Type, the Target should be modlgn_passwd and the Value should be the password for your admin user.&lt;br /&gt;
&lt;br /&gt;
To fix the second problem:&lt;br /&gt;
* scroll down through your command list until you find the second type - modlgn_username.  click on this command.&lt;br /&gt;
* Right Click and select &#039;Insert New Command&#039;&lt;br /&gt;
* The command should be open, and the Target should be the path to your Joomla frontend.&lt;br /&gt;
* scroll down through your command list until you find clickAndWait - link=User Manager&lt;br /&gt;
* Enter a new command there also - the command should be open, and the Target should be the path to your Joomla Administrator panel.&lt;br /&gt;
&lt;br /&gt;
Your test should then be ready to go.&lt;br /&gt;
&lt;br /&gt;
[[Category:Testing]]&lt;/div&gt;</summary>
		<author><name>Jedbox</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=System_Testing&amp;diff=20754</id>
		<title>System Testing</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=System_Testing&amp;diff=20754"/>
		<updated>2009-12-13T20:20:25Z</updated>

		<summary type="html">&lt;p&gt;Jedbox: /* See also */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== News and Updates ==&lt;br /&gt;
2009 07 27 Document created.&lt;br /&gt;
&lt;br /&gt;
== Functional Testing ==&lt;br /&gt;
Functional (or system) testing is an essential part of a good Quality Control program.&lt;br /&gt;
For a good general discussion of functional testing, visit the [http://en.wikipedia.org/wiki/Functional_Testing Wikipedia article].&lt;br /&gt;
&lt;br /&gt;
=== Functional Testing in Open Source ===&lt;br /&gt;
Web applications have been notoriously difficult to do functional testing with. It has traditionally required a great deal of time and effort. This can be a special challenge for open source projects because testing is often not very popular and designing tests that can be executed in a systematic way even less so. For a complicated application like Joomla!, this means that although we might do testing, we very seldom are able to perform extensive testing on each release that covers even a fraction of the elements in the CMS.&lt;br /&gt;
&lt;br /&gt;
Relatively recently, a project called Selenium has arrived on the scene.  This project makes performing automated functional testing of web applications possible. This means that it is possible to devise a test and have it performed in an automated way without the requirement of somebody sitting in front of a browser and being a click monkey.&lt;br /&gt;
&lt;br /&gt;
The benefits of functional testing are:&lt;br /&gt;
* Functional tests help highlight cases where changes in one element of the system might cause breakage in other, unexpected areas.&lt;br /&gt;
* Functional tests help clearly specify how the application should behave.&lt;br /&gt;
&lt;br /&gt;
=== Functional Testing versus Unit Testing ===&lt;br /&gt;
In order to fully test an application, both functional and unit testing are essential. Each approach has their benefits and weaknesses. Unit testing is very good for isolating small chunks of code and ensuring that they are behaving as expected. Functional testing, on the other hand, is geared towards looking at the system as a whole and ensuring that the units are behaving together in a way that achieves the desired effect.&lt;br /&gt;
&lt;br /&gt;
The advantages of functional testing is that functional tests are easier to understand and conceptualize by people who are unfamiliar with the underlying code. With Selenium, tests can be designed by people who are not overly familiar with PHP - they only need to understand the application and what results should be expected.&lt;br /&gt;
&lt;br /&gt;
The downside of functional testing is that it will only tell you that something broke. It isn&#039;t as obvious with functional testing exactly what went wrong or where the problem is.&lt;br /&gt;
&lt;br /&gt;
==== Test Objects ====&lt;br /&gt;
If the purpose of unit tests is to isolate a module of code, then the purpose of functional tests is to evaluate the entire system. This is much easier for those unfamiliar with what happens under the hood of Joomla! because one is not required to understand what happens during a Joomla! page request. A functional test might evaluate, for example, if unpublishing an article works properly. Therefore, to design the test, it is only necessary to figure out how to change an article from Published to Unpublished, and how to verify that the article was actually unpublished.&lt;br /&gt;
&lt;br /&gt;
=== Functional Testing in Joomla! ===&lt;br /&gt;
I have recently been building a functional testing architecture that will make it possible to write tests once, and to execute those tests on a variety of platforms and clients. I currently have infrastructure in place that makes it possible to run one command and execute functional tests in one browser on one host system. I have designed the host system in such a way that it will run on 6 different PHP versions (stock Ubuntu PHP 5 and self-compiled PHP 4.3, 4.4, 5.0, 5.1 and 5.2) and 2 different web servers (Apache and Lighttpd).  These are all currently serving from the same database.&lt;br /&gt;
&lt;br /&gt;
The future steps will be to make it possible to run on multiple host systems (the requirement for this is to generalize the code that resets the database state after the tests are run) and to make it possible to use different clients (i.e. different systems with different web browsers). These steps should be fairly trivial, but I have not yet had time to focus on them.&lt;br /&gt;
&lt;br /&gt;
This will eventually make it possible to run the designed tests on every major browser and on multiple server platforms (various PHP versions, various configurations, various operating systems and various web servers).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Writing Functional Tests ====&lt;br /&gt;
Selenium IDE makes it fairly easy to write functional tests. It is a Firefox extension that operates as an Integrated Development Environment for creating functional tests. In essence, it records your clicks as you navigate in your browser and encodes them into a series of commands that can control the browser.&lt;br /&gt;
&lt;br /&gt;
===== Getting Selenium IDE =====&lt;br /&gt;
At the time of writing, the latest version of Selenium IDE is 1.0.2.  You can get it at http://seleniumhq.org/download/. Click on the download link and install like you would any Firefox plugin.&lt;br /&gt;
&lt;br /&gt;
===== Preparing your Environment =====&lt;br /&gt;
To get started, create a vanilla install of Joomla! with the standard sample data.&lt;br /&gt;
&lt;br /&gt;
===== Creating a Basic Test =====&lt;br /&gt;
To start, open Firefox and browse to the home page of your Joomla! install.  I setup my install on my localhost, and so the URL is http://127.0.0.1/selsampledata.&lt;br /&gt;
&lt;br /&gt;
Then, click on Tools -&amp;gt; Selenium IDE. You will notice that on the right of the window that appears near the top, that there is a red circle that is highlighted. This is the start/stop recording button. When you start Selenium IDE, recording starts right away.&lt;br /&gt;
&lt;br /&gt;
For our first test, all we will do is load up the home page and check to make sure that all the items in the Main Menu are present.&lt;br /&gt;
&lt;br /&gt;
The commands that we use to check that items are present are called assertions. Basically, you perform your actions and make assertions about the results.&lt;br /&gt;
&lt;br /&gt;
In our case, we are going to use the command assertText. This command will read the text of a specified element and ensure it matches a particular value.&lt;br /&gt;
&lt;br /&gt;
So, first ensure that the Base URL displayed in the Selenium IDE window is the home page of your Joomla! install.&lt;br /&gt;
&lt;br /&gt;
Then, switch to the window that has your Joomla install open.&lt;br /&gt;
&lt;br /&gt;
In that window, right click on each menu item and select &#039;Assert Text&#039;.&lt;br /&gt;
&lt;br /&gt;
Then, switch to your Selenium IDE window and click the Red Button to stop recording.&lt;br /&gt;
&lt;br /&gt;
You should see two tabs in your Selenium IDE window - one labeled Table, and one labeled Source. You don&#039;t really need to look at the Source window.&lt;br /&gt;
&lt;br /&gt;
So, now our first test is done.&lt;br /&gt;
&lt;br /&gt;
To run your test, you use the icons on the bar between the Base URL address bar and the Table and Source tabs. The two important buttons are the buttons with the Green Triangle with Three Solid rectangles and the one with the Green Triangle and One Solid Rectangle. The first one will execute the entire test suite and the second one will run the currently selected test case. Since we currently have only one test case, both of these currently do the same thing.&lt;br /&gt;
&lt;br /&gt;
To run your test, press one of these buttons.&lt;br /&gt;
&lt;br /&gt;
As you watch the Selenium IDE, you will see a yellow bar move down your list of steps. Once a step is completed, a successfully executed action (i.e. a button was successfully located and clicked) should show up in light green and a successful assertion should show up in darker green. Failed actions show up in light red and failed assertions show up in darker red.&lt;br /&gt;
&lt;br /&gt;
Click on the Window Expander on the left to unhide the Test Case browser.&lt;br /&gt;
&lt;br /&gt;
If your test completed successfully, you should see Runs: 1, Failures: 0 at the bottom of the Test Case browser.&lt;br /&gt;
&lt;br /&gt;
==== Running Functional Tests ====&lt;br /&gt;
&lt;br /&gt;
== How to Get it Running ==&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Frequently Asked Questions ==&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
For writing a more advanced Selenium testcase see [http://docs.joomla.org/Intermediate_Selenium_Example here].&lt;br /&gt;
&lt;br /&gt;
[http://seleniumhq.org/docs/ Selenium documentation].&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;br /&gt;
[[Category:Testing]]&lt;br /&gt;
[[Category:Bug Squad]]&lt;/div&gt;</summary>
		<author><name>Jedbox</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=System_Testing&amp;diff=20753</id>
		<title>System Testing</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=System_Testing&amp;diff=20753"/>
		<updated>2009-12-13T20:16:10Z</updated>

		<summary type="html">&lt;p&gt;Jedbox: /* See also */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== News and Updates ==&lt;br /&gt;
2009 07 27 Document created.&lt;br /&gt;
&lt;br /&gt;
== Functional Testing ==&lt;br /&gt;
Functional (or system) testing is an essential part of a good Quality Control program.&lt;br /&gt;
For a good general discussion of functional testing, visit the [http://en.wikipedia.org/wiki/Functional_Testing Wikipedia article].&lt;br /&gt;
&lt;br /&gt;
=== Functional Testing in Open Source ===&lt;br /&gt;
Web applications have been notoriously difficult to do functional testing with. It has traditionally required a great deal of time and effort. This can be a special challenge for open source projects because testing is often not very popular and designing tests that can be executed in a systematic way even less so. For a complicated application like Joomla!, this means that although we might do testing, we very seldom are able to perform extensive testing on each release that covers even a fraction of the elements in the CMS.&lt;br /&gt;
&lt;br /&gt;
Relatively recently, a project called Selenium has arrived on the scene.  This project makes performing automated functional testing of web applications possible. This means that it is possible to devise a test and have it performed in an automated way without the requirement of somebody sitting in front of a browser and being a click monkey.&lt;br /&gt;
&lt;br /&gt;
The benefits of functional testing are:&lt;br /&gt;
* Functional tests help highlight cases where changes in one element of the system might cause breakage in other, unexpected areas.&lt;br /&gt;
* Functional tests help clearly specify how the application should behave.&lt;br /&gt;
&lt;br /&gt;
=== Functional Testing versus Unit Testing ===&lt;br /&gt;
In order to fully test an application, both functional and unit testing are essential. Each approach has their benefits and weaknesses. Unit testing is very good for isolating small chunks of code and ensuring that they are behaving as expected. Functional testing, on the other hand, is geared towards looking at the system as a whole and ensuring that the units are behaving together in a way that achieves the desired effect.&lt;br /&gt;
&lt;br /&gt;
The advantages of functional testing is that functional tests are easier to understand and conceptualize by people who are unfamiliar with the underlying code. With Selenium, tests can be designed by people who are not overly familiar with PHP - they only need to understand the application and what results should be expected.&lt;br /&gt;
&lt;br /&gt;
The downside of functional testing is that it will only tell you that something broke. It isn&#039;t as obvious with functional testing exactly what went wrong or where the problem is.&lt;br /&gt;
&lt;br /&gt;
==== Test Objects ====&lt;br /&gt;
If the purpose of unit tests is to isolate a module of code, then the purpose of functional tests is to evaluate the entire system. This is much easier for those unfamiliar with what happens under the hood of Joomla! because one is not required to understand what happens during a Joomla! page request. A functional test might evaluate, for example, if unpublishing an article works properly. Therefore, to design the test, it is only necessary to figure out how to change an article from Published to Unpublished, and how to verify that the article was actually unpublished.&lt;br /&gt;
&lt;br /&gt;
=== Functional Testing in Joomla! ===&lt;br /&gt;
I have recently been building a functional testing architecture that will make it possible to write tests once, and to execute those tests on a variety of platforms and clients. I currently have infrastructure in place that makes it possible to run one command and execute functional tests in one browser on one host system. I have designed the host system in such a way that it will run on 6 different PHP versions (stock Ubuntu PHP 5 and self-compiled PHP 4.3, 4.4, 5.0, 5.1 and 5.2) and 2 different web servers (Apache and Lighttpd).  These are all currently serving from the same database.&lt;br /&gt;
&lt;br /&gt;
The future steps will be to make it possible to run on multiple host systems (the requirement for this is to generalize the code that resets the database state after the tests are run) and to make it possible to use different clients (i.e. different systems with different web browsers). These steps should be fairly trivial, but I have not yet had time to focus on them.&lt;br /&gt;
&lt;br /&gt;
This will eventually make it possible to run the designed tests on every major browser and on multiple server platforms (various PHP versions, various configurations, various operating systems and various web servers).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Writing Functional Tests ====&lt;br /&gt;
Selenium IDE makes it fairly easy to write functional tests. It is a Firefox extension that operates as an Integrated Development Environment for creating functional tests. In essence, it records your clicks as you navigate in your browser and encodes them into a series of commands that can control the browser.&lt;br /&gt;
&lt;br /&gt;
===== Getting Selenium IDE =====&lt;br /&gt;
At the time of writing, the latest version of Selenium IDE is 1.0.2.  You can get it at http://seleniumhq.org/download/. Click on the download link and install like you would any Firefox plugin.&lt;br /&gt;
&lt;br /&gt;
===== Preparing your Environment =====&lt;br /&gt;
To get started, create a vanilla install of Joomla! with the standard sample data.&lt;br /&gt;
&lt;br /&gt;
===== Creating a Basic Test =====&lt;br /&gt;
To start, open Firefox and browse to the home page of your Joomla! install.  I setup my install on my localhost, and so the URL is http://127.0.0.1/selsampledata.&lt;br /&gt;
&lt;br /&gt;
Then, click on Tools -&amp;gt; Selenium IDE. You will notice that on the right of the window that appears near the top, that there is a red circle that is highlighted. This is the start/stop recording button. When you start Selenium IDE, recording starts right away.&lt;br /&gt;
&lt;br /&gt;
For our first test, all we will do is load up the home page and check to make sure that all the items in the Main Menu are present.&lt;br /&gt;
&lt;br /&gt;
The commands that we use to check that items are present are called assertions. Basically, you perform your actions and make assertions about the results.&lt;br /&gt;
&lt;br /&gt;
In our case, we are going to use the command assertText. This command will read the text of a specified element and ensure it matches a particular value.&lt;br /&gt;
&lt;br /&gt;
So, first ensure that the Base URL displayed in the Selenium IDE window is the home page of your Joomla! install.&lt;br /&gt;
&lt;br /&gt;
Then, switch to the window that has your Joomla install open.&lt;br /&gt;
&lt;br /&gt;
In that window, right click on each menu item and select &#039;Assert Text&#039;.&lt;br /&gt;
&lt;br /&gt;
Then, switch to your Selenium IDE window and click the Red Button to stop recording.&lt;br /&gt;
&lt;br /&gt;
You should see two tabs in your Selenium IDE window - one labeled Table, and one labeled Source. You don&#039;t really need to look at the Source window.&lt;br /&gt;
&lt;br /&gt;
So, now our first test is done.&lt;br /&gt;
&lt;br /&gt;
To run your test, you use the icons on the bar between the Base URL address bar and the Table and Source tabs. The two important buttons are the buttons with the Green Triangle with Three Solid rectangles and the one with the Green Triangle and One Solid Rectangle. The first one will execute the entire test suite and the second one will run the currently selected test case. Since we currently have only one test case, both of these currently do the same thing.&lt;br /&gt;
&lt;br /&gt;
To run your test, press one of these buttons.&lt;br /&gt;
&lt;br /&gt;
As you watch the Selenium IDE, you will see a yellow bar move down your list of steps. Once a step is completed, a successfully executed action (i.e. a button was successfully located and clicked) should show up in light green and a successful assertion should show up in darker green. Failed actions show up in light red and failed assertions show up in darker red.&lt;br /&gt;
&lt;br /&gt;
Click on the Window Expander on the left to unhide the Test Case browser.&lt;br /&gt;
&lt;br /&gt;
If your test completed successfully, you should see Runs: 1, Failures: 0 at the bottom of the Test Case browser.&lt;br /&gt;
&lt;br /&gt;
==== Running Functional Tests ====&lt;br /&gt;
&lt;br /&gt;
== How to Get it Running ==&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Frequently Asked Questions ==&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
For writing a more advanced Selenium testcase see [http://docs.joomla.org/Intermediate_Selenium_Example here].&lt;br /&gt;
&lt;br /&gt;
[http://seleniumhq.org/docs/ Selenium documentation].&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;br /&gt;
[[Category:Bug Squad]]&lt;/div&gt;</summary>
		<author><name>Jedbox</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=System_Testing&amp;diff=20752</id>
		<title>System Testing</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=System_Testing&amp;diff=20752"/>
		<updated>2009-12-13T20:12:04Z</updated>

		<summary type="html">&lt;p&gt;Jedbox: /* See also */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== News and Updates ==&lt;br /&gt;
2009 07 27 Document created.&lt;br /&gt;
&lt;br /&gt;
== Functional Testing ==&lt;br /&gt;
Functional (or system) testing is an essential part of a good Quality Control program.&lt;br /&gt;
For a good general discussion of functional testing, visit the [http://en.wikipedia.org/wiki/Functional_Testing Wikipedia article].&lt;br /&gt;
&lt;br /&gt;
=== Functional Testing in Open Source ===&lt;br /&gt;
Web applications have been notoriously difficult to do functional testing with. It has traditionally required a great deal of time and effort. This can be a special challenge for open source projects because testing is often not very popular and designing tests that can be executed in a systematic way even less so. For a complicated application like Joomla!, this means that although we might do testing, we very seldom are able to perform extensive testing on each release that covers even a fraction of the elements in the CMS.&lt;br /&gt;
&lt;br /&gt;
Relatively recently, a project called Selenium has arrived on the scene.  This project makes performing automated functional testing of web applications possible. This means that it is possible to devise a test and have it performed in an automated way without the requirement of somebody sitting in front of a browser and being a click monkey.&lt;br /&gt;
&lt;br /&gt;
The benefits of functional testing are:&lt;br /&gt;
* Functional tests help highlight cases where changes in one element of the system might cause breakage in other, unexpected areas.&lt;br /&gt;
* Functional tests help clearly specify how the application should behave.&lt;br /&gt;
&lt;br /&gt;
=== Functional Testing versus Unit Testing ===&lt;br /&gt;
In order to fully test an application, both functional and unit testing are essential. Each approach has their benefits and weaknesses. Unit testing is very good for isolating small chunks of code and ensuring that they are behaving as expected. Functional testing, on the other hand, is geared towards looking at the system as a whole and ensuring that the units are behaving together in a way that achieves the desired effect.&lt;br /&gt;
&lt;br /&gt;
The advantages of functional testing is that functional tests are easier to understand and conceptualize by people who are unfamiliar with the underlying code. With Selenium, tests can be designed by people who are not overly familiar with PHP - they only need to understand the application and what results should be expected.&lt;br /&gt;
&lt;br /&gt;
The downside of functional testing is that it will only tell you that something broke. It isn&#039;t as obvious with functional testing exactly what went wrong or where the problem is.&lt;br /&gt;
&lt;br /&gt;
==== Test Objects ====&lt;br /&gt;
If the purpose of unit tests is to isolate a module of code, then the purpose of functional tests is to evaluate the entire system. This is much easier for those unfamiliar with what happens under the hood of Joomla! because one is not required to understand what happens during a Joomla! page request. A functional test might evaluate, for example, if unpublishing an article works properly. Therefore, to design the test, it is only necessary to figure out how to change an article from Published to Unpublished, and how to verify that the article was actually unpublished.&lt;br /&gt;
&lt;br /&gt;
=== Functional Testing in Joomla! ===&lt;br /&gt;
I have recently been building a functional testing architecture that will make it possible to write tests once, and to execute those tests on a variety of platforms and clients. I currently have infrastructure in place that makes it possible to run one command and execute functional tests in one browser on one host system. I have designed the host system in such a way that it will run on 6 different PHP versions (stock Ubuntu PHP 5 and self-compiled PHP 4.3, 4.4, 5.0, 5.1 and 5.2) and 2 different web servers (Apache and Lighttpd).  These are all currently serving from the same database.&lt;br /&gt;
&lt;br /&gt;
The future steps will be to make it possible to run on multiple host systems (the requirement for this is to generalize the code that resets the database state after the tests are run) and to make it possible to use different clients (i.e. different systems with different web browsers). These steps should be fairly trivial, but I have not yet had time to focus on them.&lt;br /&gt;
&lt;br /&gt;
This will eventually make it possible to run the designed tests on every major browser and on multiple server platforms (various PHP versions, various configurations, various operating systems and various web servers).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Writing Functional Tests ====&lt;br /&gt;
Selenium IDE makes it fairly easy to write functional tests. It is a Firefox extension that operates as an Integrated Development Environment for creating functional tests. In essence, it records your clicks as you navigate in your browser and encodes them into a series of commands that can control the browser.&lt;br /&gt;
&lt;br /&gt;
===== Getting Selenium IDE =====&lt;br /&gt;
At the time of writing, the latest version of Selenium IDE is 1.0.2.  You can get it at http://seleniumhq.org/download/. Click on the download link and install like you would any Firefox plugin.&lt;br /&gt;
&lt;br /&gt;
===== Preparing your Environment =====&lt;br /&gt;
To get started, create a vanilla install of Joomla! with the standard sample data.&lt;br /&gt;
&lt;br /&gt;
===== Creating a Basic Test =====&lt;br /&gt;
To start, open Firefox and browse to the home page of your Joomla! install.  I setup my install on my localhost, and so the URL is http://127.0.0.1/selsampledata.&lt;br /&gt;
&lt;br /&gt;
Then, click on Tools -&amp;gt; Selenium IDE. You will notice that on the right of the window that appears near the top, that there is a red circle that is highlighted. This is the start/stop recording button. When you start Selenium IDE, recording starts right away.&lt;br /&gt;
&lt;br /&gt;
For our first test, all we will do is load up the home page and check to make sure that all the items in the Main Menu are present.&lt;br /&gt;
&lt;br /&gt;
The commands that we use to check that items are present are called assertions. Basically, you perform your actions and make assertions about the results.&lt;br /&gt;
&lt;br /&gt;
In our case, we are going to use the command assertText. This command will read the text of a specified element and ensure it matches a particular value.&lt;br /&gt;
&lt;br /&gt;
So, first ensure that the Base URL displayed in the Selenium IDE window is the home page of your Joomla! install.&lt;br /&gt;
&lt;br /&gt;
Then, switch to the window that has your Joomla install open.&lt;br /&gt;
&lt;br /&gt;
In that window, right click on each menu item and select &#039;Assert Text&#039;.&lt;br /&gt;
&lt;br /&gt;
Then, switch to your Selenium IDE window and click the Red Button to stop recording.&lt;br /&gt;
&lt;br /&gt;
You should see two tabs in your Selenium IDE window - one labeled Table, and one labeled Source. You don&#039;t really need to look at the Source window.&lt;br /&gt;
&lt;br /&gt;
So, now our first test is done.&lt;br /&gt;
&lt;br /&gt;
To run your test, you use the icons on the bar between the Base URL address bar and the Table and Source tabs. The two important buttons are the buttons with the Green Triangle with Three Solid rectangles and the one with the Green Triangle and One Solid Rectangle. The first one will execute the entire test suite and the second one will run the currently selected test case. Since we currently have only one test case, both of these currently do the same thing.&lt;br /&gt;
&lt;br /&gt;
To run your test, press one of these buttons.&lt;br /&gt;
&lt;br /&gt;
As you watch the Selenium IDE, you will see a yellow bar move down your list of steps. Once a step is completed, a successfully executed action (i.e. a button was successfully located and clicked) should show up in light green and a successful assertion should show up in darker green. Failed actions show up in light red and failed assertions show up in darker red.&lt;br /&gt;
&lt;br /&gt;
Click on the Window Expander on the left to unhide the Test Case browser.&lt;br /&gt;
&lt;br /&gt;
If your test completed successfully, you should see Runs: 1, Failures: 0 at the bottom of the Test Case browser.&lt;br /&gt;
&lt;br /&gt;
==== Running Functional Tests ====&lt;br /&gt;
&lt;br /&gt;
== How to Get it Running ==&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Frequently Asked Questions ==&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
For writing a more advanced Selenium testcase see [http://docs.joomla.org/Intermediate_Selenium_Example here].&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;br /&gt;
[[Category:Bug Squad]]&lt;/div&gt;</summary>
		<author><name>Jedbox</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Unit_Testing&amp;diff=20751</id>
		<title>Unit Testing</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Unit_Testing&amp;diff=20751"/>
		<updated>2009-12-13T20:07:23Z</updated>

		<summary type="html">&lt;p&gt;Jedbox: /* The Testing Hierarchy: Unit, Subsystem, Integrated */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{cookiejar}}&lt;br /&gt;
== News and Updates ==&lt;br /&gt;
2009 10 06: Tests now depend on the SVN version of PHPUnit 3.4.1.&lt;br /&gt;
&lt;br /&gt;
2008 06 24: Update to reflect move of PHPUnit code from branch to trunk (former trunk now in /branches/old_simpletest).&lt;br /&gt;
&lt;br /&gt;
2008 06 22: Add information on limiting tests by version.&lt;br /&gt;
&lt;br /&gt;
2008 06 21: Added --class-exclude, --sequence-exclude, and --test-exclude options.&lt;br /&gt;
&lt;br /&gt;
2008 06 21: PHPUnit has been updated to version 3.2.21 with SVN rev 10436. Please update.&lt;br /&gt;
&lt;br /&gt;
== Unit Testing ==&lt;br /&gt;
Unit testing is an essential part of a good Quality Control program.&lt;br /&gt;
For a good general discussion of unit testing, visit the [http://en.wikipedia.org/wiki/Unit_test Wikipedia article].&lt;br /&gt;
&lt;br /&gt;
=== Unit Testing in Open Source ===&lt;br /&gt;
Open source projects, with multiple developers working in parallel around the world, can greatly benefit from unit testing. The main benefits are:&lt;br /&gt;
* Unit tests help highlight cases where seemingly minor changes cause unexpected breakage.&lt;br /&gt;
* Unit tests help clearly specify how a class should behave.&lt;br /&gt;
* Unit tests can expose design flaws very early in development.&lt;br /&gt;
* Unit tests make great examples. They are a great place for developers to learn how to use the code.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== The Testing Hierarchy: Unit, Subsystem, Integrated ===&lt;br /&gt;
Software testing systems usually run through a spectrum from &amp;quot;pure&amp;quot; unit tests through to fully integrated systems tests. We&#039;ve described low level unit tests above. Integrated testing typically involves some sort of script that simulates user actions and then verifies that the result matches what&#039;s expected. This sort of &amp;quot;end to end&amp;quot; test verifies that all parts of the system are working correctly.&lt;br /&gt;
&lt;br /&gt;
It&#039;s unfortunate that there is no clear nomenclature to describe all the intermediate stages of testing. The next stage beyond testing a single unit of code is subsystem testing. A subsystem test verifies that two or more units of code are interacting correctly to produce the desired result. In the simplest case, a subsystem test can be created simply by replacing mock objects with real objects and running unit tests on the top level module. In practise, this tends to not work as well as expected, because the original unit test data wasn&#039;t designed for a subsystem test, or because the nature of the test cases needs to be changed in order to fully test the subsystem. After all there is little point in simply repeating the unit test cases; the objective of a subsystem test should be to test boundary conditions and special cases that would be difficult to duplicate in unit tests.&lt;br /&gt;
&lt;br /&gt;
Once a subsystem has been tested, it can be integrated into a larger system, which is still a subset of the whole product. Tests can be written for larger and larger subsystems, but at each stage the complexity of the tests increases. At some point, the effort required to hand craft tests exceeds the benefits of running them. This is where integrated testing comes in.&lt;br /&gt;
&lt;br /&gt;
Integrated testing involves recording a user&#039;s interaction with the system into a script that can be replayed. The testing framework then compares the system&#039;s response with the expected response and passes or fails the test. The PHPUnit testing framework that we use has the ability to work with [http://seleniumhq.org/ Selenium], a browser based test automation tool. Writing a functional test using Selenium is documented [http://docs.joomla.org/Functional_Testing#Writing_Functional_Tests here].&lt;br /&gt;
&lt;br /&gt;
==== Test Objects ====&lt;br /&gt;
The purpose of unit tests is to isolate a module of code. A test that tests only one thing provides better information than a test that involves several object interactions. But how do we isolate an object from its dependencies? By writing stub classes. [http://xunitpatterns.com/Mocks,%20Fakes,%20Stubs%20and%20Dummies.html xUnit Patterns] defines a the hierarchy of dummy classes, ranging from simple to complex:&lt;br /&gt;
* Dummy - Defines attributes and methods of a dummy class (not particularly useful in PHP).&lt;br /&gt;
* Fake - Provides canned responses to method calls and fixed attribute values. Good for speed.&lt;br /&gt;
* Stub - Allows the test to define responses to method calls (return values, exceptions) to simulate the dependent object.&lt;br /&gt;
* Spy - A Fake or Stub that records method calls and parameters for later analysis.&lt;br /&gt;
* Mock - A Fake or Stub with a set of expectations -- method calls and parameters -- that are automatically verified for correctness.&lt;br /&gt;
&lt;br /&gt;
=== Unit Testing in Joomla! ===&lt;br /&gt;
Unit testing capabilities in Joomla are still at an early stage. The intention is to define more standards for developing tests, and then to expand the scope of available tests.&lt;br /&gt;
&lt;br /&gt;
For an overview of unit testing status in Joomla visit the [[Unit_Testing_Status]] page.&lt;br /&gt;
&lt;br /&gt;
The SVN repository contains code under the /testing path. /testing/trunk used to contain code based on the SimpleTest framework. In early December 2007, the development team elected to move to the [http://www.phpunit.de PHPUnit] framework.&lt;br /&gt;
&lt;br /&gt;
The PHPUnit tests are available from &#039;&#039;&#039;/testing/trunk&#039;&#039;&#039;. Some new tests have been added, any remaining tests from the SimpleTest days are completely broken. See /testing/branches/old-simpletest if you need to run something from that suite.&lt;br /&gt;
&lt;br /&gt;
The unit tests are located in two places:&lt;br /&gt;
* /testing/trunk/1.5/unittest - these are tests for Joomla! 1.5 (/development/releases/1.5)&lt;br /&gt;
* /testing/trunk/1.6/unittest - there are tests for Joomla! 1.6 (/development/trunk)&lt;br /&gt;
&lt;br /&gt;
At this point, PHPUnit based tests only run in a command line environment.&lt;br /&gt;
&lt;br /&gt;
==== The Unit Test Team ====&lt;br /&gt;
If you can commit to the Joomla code base, then you should consider yourself part of the unit test team!&lt;br /&gt;
&lt;br /&gt;
Writing tests concurrently with code (or even before) is a good way to not only save development time, but a great tool for defending against regressions. Writing tests early in the development cycle also helps identify and resolve design issues sooner, which reduces refactoring.&lt;br /&gt;
&lt;br /&gt;
If you want to get started on unit testing, get in touch with Alan Langford (instance) or Ray Tsai (mihu). Either of us will be happy to help out.&lt;br /&gt;
&lt;br /&gt;
==== Current Work ====&lt;br /&gt;
* There is no longer any need to patch the main code to enable unit tests.&lt;br /&gt;
* Basic techniques for mock objects are defined.&lt;br /&gt;
* Strategies for dealing with local configuration is not yet complete, but there is a plan.&lt;br /&gt;
* Files of the form class-sequence-type-Test.php, for example JObject-0000-class-Test.php use PHPUnit.&lt;br /&gt;
* The JDate tests present a good example of a data-driven test, but they won&#039;t run on the current 1.5 code base (there are some proposed API changes as a result of unit test development).&lt;br /&gt;
* Previously functional tests, such as JFTP, haven&#039;t been moved to the PHPUnit environment yet.&lt;br /&gt;
* The custom test runner is no longer needed. The current tests will run with the latest SVN version of PHPUnit 3.4. This code will eventually become PHPUnit 3.4.1.  Thanks to Sebastian Bergmann for his excellent work on an excellent project!&lt;br /&gt;
&lt;br /&gt;
==== Writing Unit Tests ====&lt;br /&gt;
At risk of stating the obvious, in the &amp;quot;purest&amp;quot; case the purpose of a unit test is to &#039;&#039;isolate a unit of code from its environment and to test the operation of that code&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
This isolation is usually achieved by writing dummy classes that emulate the code unit&#039;s environment. These dummy objects can be passive, by simply simulating the environment, or they can be more active, keeping track of how they are being used by the test unit and reporting any variations from the expected behaviour. See [[Unit_Testing_Mock_Objects|Mock Objects in Joomla]] for a detailed example.&lt;br /&gt;
&lt;br /&gt;
An interesting aspect of writing tests is that they become &#039;&#039;de facto&#039;&#039; detailed technical specifications of the interfaces between units of code. The fact that these specifications can be verified in an automated way makes them a superb resource when refactoring code.&lt;br /&gt;
&lt;br /&gt;
The test code has a few templates designed to kick-start a test. They are:&lt;br /&gt;
&lt;br /&gt;
/unittest/sample-datatest-php.txt&lt;br /&gt;
/unittest/sample-simpletest.php.txt&lt;br /&gt;
&lt;br /&gt;
Here are some example tests: [[Unit_Testing_--_a_Simple_Example|Simple Example]], [[Unit_Testing_--_Data_Driven_Example|Data Driven Example]], [[Unit_Testing_--_Plugin_Example|Plugin Example]], [[Unit_Testing_--_UI_Example|UI Example]].&lt;br /&gt;
&lt;br /&gt;
==== Running Unit Tests ====&lt;br /&gt;
Test files follow the form class-sequence-type-Test.php, for example JObject-0000-class-Test.php. For tests that are not class based, the first element refers to the object being tested. An example of this is the e-mail cloaking plugin test, which is called emailcloak-0000-mode1-Test.php.&lt;br /&gt;
&lt;br /&gt;
Joomla unit tests use the standard PHPUnit test runner.  See http://www.phpunit.de for documentation.&lt;br /&gt;
&lt;br /&gt;
== How to Get it Running ==&lt;br /&gt;
&lt;br /&gt;
Before you start make sure you have installed PHPUnit and of course PHP (5!) properly...&lt;br /&gt;
&lt;br /&gt;
To get the unit tests to run on your Joomla! installation, perform the following steps:&lt;br /&gt;
* Create an instance of your Joomla! installation. Since you will be using SVN to check out the testing project, you don&#039;t want to check out the Joomla! with SVN. Instead, simply unpack a normal Joomla! archive. If you are using Eclipse, you can create a folder in your Eclipse workspace for the Joomla! installation, but don&#039;t create an Eclipse project yet.&lt;br /&gt;
* In the root checkout (or export) the latest version of the unit test code from SVN &#039;&#039;&amp;quot;/testing/trunk/1.5/unittest&amp;quot;&#039;&#039; or &#039;&#039;&amp;quot;/testing/trunk/1.6/unittest&amp;quot;&#039;&#039; to your installation base. This will create a &#039;&#039;&amp;quot;/unittest&amp;quot;&#039;&#039; sub-folder under your joomla installation. If you are using Eclipse, Import the project from the SVN and use the same folder in your Eclipse workspace you used above.&lt;br /&gt;
* From the command line, change to the unittest directory.&lt;br /&gt;
* Run the unit test from the command prompt using the following command: &amp;lt;code&amp;gt;phpunit tests&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The unit test will the run, and the results are rendered. You will see a series of dots for each passed test and other letters for failed tests. &lt;br /&gt;
&lt;br /&gt;
See http://www.phpunit.de/manual/current/en/textui.html for help using the --filter switch to run only certain tests.  There are also many other command line switches you can use to get results in various formats.&lt;br /&gt;
&lt;br /&gt;
== Troubleshooting ==&lt;br /&gt;
&lt;br /&gt;
The provided configurations should work out of the box. We have seen problems with it (currently the cause is unknown). If you get an error like below, the solution is pretty easy.&lt;br /&gt;
&lt;br /&gt;
 file=/var/www/unittest/runtests.php&lt;br /&gt;
 posn=17&lt;br /&gt;
 base=runtests.php&lt;br /&gt;
 /var/www&lt;br /&gt;
  JPATH_BASE does not point to a valid Joomla! installation:&lt;br /&gt;
 JPATH_BASE = /var/www&lt;br /&gt;
  Please modify your copy of &amp;quot;TestConfiguration.php&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Modify the &#039;&#039;&amp;quot;TestConfiguration.php&amp;quot;&#039;&#039; file and change the definition of the JPATH_BASE so it points to the path of you Joomla! installation, in the example below the Joomla! installation is installed at &amp;quot;&#039;&#039;/var/www/update&#039;&#039;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
 define(&#039;JPATH_BASE&#039;, &#039;/var/www/update&#039;);&lt;br /&gt;
&lt;br /&gt;
== Frequently Asked Questions ==&lt;br /&gt;
&#039;&#039;&#039;Why can&#039;t I use &amp;quot;phpunit &#039;&#039;testname.php&#039;&#039;&amp;quot; to run my tests?&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The test facility has to do some work to be able to load the &amp;quot;Joomla!&amp;quot; framework and to be able to inject mock classes. It&#039;s difficult to do this from the PHPUnit test runner, so we built our own. Also, the Joomla test runner has specific options designed to make it easy to select specific tests. Over time we will add more functionality to the test runner so it has many of the capabilities of the phpunit command.&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
[http://www.phpunit.de/manual/current/en/ PHPUnit Manual]&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Jedbox</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Accessing_the_database_using_JDatabase&amp;diff=13901</id>
		<title>Accessing the database using JDatabase</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Accessing_the_database_using_JDatabase&amp;diff=13901"/>
		<updated>2009-04-14T18:20:55Z</updated>

		<summary type="html">&lt;p&gt;Jedbox: /* getNumRows() */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Joomla provides a sopisticated database abstraction layer to simplify the usage for 3PD. This guide should help you using this layer.&lt;br /&gt;
&lt;br /&gt;
==Why should I use the Joomla database class?==&lt;br /&gt;
Joomla is build to be able to use several different kinds of SQL-database-systems and to run in a variety of environments with different table-prefixes. In addition to these functions, the class automatically creates the database connection. Besides instantiating the object, you only need 2 lines of code to get a result from the database and that in a variety of formats. Using the Joomla database layer ensures a maximum of compatibility and flexibility for your extension.&lt;br /&gt;
&lt;br /&gt;
==Preparing the query==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Get a database object&lt;br /&gt;
$db =&amp;amp; JFactory::getDBO();&lt;br /&gt;
&lt;br /&gt;
$query = &amp;quot;SELECT * FROM #__example_table WHERE id = 999999;&amp;quot;;&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
First we instantiate the database object, then we prepare the query. You can use the normal SQL-syntax, the only thing you have to change is the table-prefix. To make this as flexible as possible, Joomla uses a placeholder for the prefix, the &amp;amp;ldquo;#__&amp;amp;rdquo;. In the next step, the $db-&amp;gt;setQuery(), this string is replaced with the correct prefix.&lt;br /&gt;
&lt;br /&gt;
Now, if we don&#039;t want to get information from the database, but insert a row into it, we need one more function. Every string-value in the SQL-syntax should be quoted. For example, MySQL uses backticks &amp;amp;#096;&amp;amp;#096; for names and single quotes &amp;amp;lsquo;&amp;amp;lsquo; for values. Joomla has some functions to do this for us and to ensure code compatibility between different databases. We can pass the names to the function $db-&amp;gt;nameQuote($name) and the values to the function $db-&amp;gt;Quote($value). &lt;br /&gt;
&lt;br /&gt;
A fully quoted query example is:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$query = &amp;quot;&lt;br /&gt;
  SELECT * &lt;br /&gt;
    FROM &amp;quot;.$db-&amp;gt;nameQuote(&#039;#__example_table&#039;).&amp;quot;  &lt;br /&gt;
    WHERE &amp;quot;.$db-&amp;gt;nameQuote(&#039;id&#039;).&amp;quot; = &amp;quot;.$db-&amp;gt;quote(&#039;999999&#039;).&amp;quot;;&lt;br /&gt;
  &amp;quot;;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Whatever we want to do, we have to set the query with the $db-&amp;gt;setQuery() function. Although you could write the query directly as a parameter for $db-&amp;gt;setQuery(), it&#039;s commonly done by first saving it in a variable, normally $query, and then handing this variable over. This helps writing clean, readable code.&lt;br /&gt;
&lt;br /&gt;
==== setQuery($query) ====&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;setQuery($query)&#039;&#039; method sets up a database query for later execution either by the query() method or one of the Load result methods.  &amp;lt;pre&amp;gt;$db =&amp;amp; JFactory::getDBO();&lt;br /&gt;
$query = &amp;quot;/* some valid sql string */&amp;quot;;&lt;br /&gt;
$db-&amp;gt;setQuery($query);&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
The parameter $query must be a valid sql string, it can either be added as a string parameter or as a variable; generally a variable is preferred as it leads to more legible code and can help in debugging.&lt;br /&gt;
&lt;br /&gt;
setQuery() also takes three other parameters: $offset, $limit - both used in list pagination; and $prefix - an alternative table prefix. All three of these variables have default values set and can usually be ignored. &lt;br /&gt;
&lt;br /&gt;
==Executing the Query==&lt;br /&gt;
To execute the query, Joomla provides several functions, which differ in their return value.&lt;br /&gt;
&lt;br /&gt;
=== Basic Query Execution ===&lt;br /&gt;
&lt;br /&gt;
==== query() ====&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;query()&#039;&#039; method is the the basic tool for executing sql queries on a database. In Joomla it is most often used for updating or administering the database simple because the various load methods detail on this page have the query step built in to them.&lt;br /&gt;
&lt;br /&gt;
The syntax is very straightforward:&amp;lt;pre&amp;gt;$db =&amp;amp; JFactory::getDBO();&lt;br /&gt;
$query = &amp;quot;/* some valid sql string */&amp;quot;;&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$result = $db-&amp;gt;query();&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: $query() returns an appropriate database resource if successful, or FALSE if not&lt;br /&gt;
&lt;br /&gt;
=== Query Execution Information ===&lt;br /&gt;
* getAffectedRows()&lt;br /&gt;
* explain()&lt;br /&gt;
* insertid()&lt;br /&gt;
&lt;br /&gt;
=== Insert Query Execution ===&lt;br /&gt;
* insertObject()&lt;br /&gt;
&lt;br /&gt;
==Query Results ==&lt;br /&gt;
The database class contains many methods for working with a query&#039;s result set.&lt;br /&gt;
&lt;br /&gt;
=== Single Value Result ===&lt;br /&gt;
&lt;br /&gt;
==== loadResult() ====&lt;br /&gt;
&lt;br /&gt;
Use &#039;&#039;&#039;loadResult()&#039;&#039;&#039; when you expect just a single value back from your database query. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! id !! name !! email !! username&lt;br /&gt;
|- &lt;br /&gt;
| 1 || style=&amp;quot;background:yellow&amp;quot; | John Smith || johnsmith@example.com || johnsmith&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Magda Hellman || magda_h@example.com || magdah&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Yvonne de Gaulle || ydg@example.com || ydegaulle&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This is often the result of a &#039;count&#039; query to get a number of records:&lt;br /&gt;
&amp;lt;source lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
$db =&amp;amp; JFactory::getDBO();&lt;br /&gt;
$query = &amp;quot;&lt;br /&gt;
  SELECT COUNT(*)&lt;br /&gt;
    FROM &amp;quot;.$db-&amp;gt;nameQuote(&#039;#__my_table&#039;).&amp;quot;&lt;br /&gt;
    WHERE &amp;quot;.$db-&amp;gt;nameQuote(&#039;name&#039;).&amp;quot; = &amp;quot;.$db-&amp;gt;quote($value).&amp;quot;;&lt;br /&gt;
  &amp;quot;;&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$count = $db-&amp;gt;loadResult();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
or where you are just looking for a single field from a single row of the table (or possibly a single field from the first row returned).&lt;br /&gt;
&amp;lt;source lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
$db =&amp;amp; JFactory::getDBO();&lt;br /&gt;
$query = &amp;quot;&lt;br /&gt;
  SELECT &amp;quot;.$db-&amp;gt;nameQuote(&#039;field_name&#039;).&amp;quot;&lt;br /&gt;
    FROM &amp;quot;.$db-&amp;gt;nameQuote(&#039;#__my_table&#039;).&amp;quot;&lt;br /&gt;
    WHERE &amp;quot;.$db-&amp;gt;nameQuote(&#039;some_name&#039;).&amp;quot; = &amp;quot;.$db-&amp;gt;quote($some_value).&amp;quot;;&lt;br /&gt;
  &amp;quot;;&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$result = $db-&amp;gt;loadResult();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Single Row Results ===&lt;br /&gt;
&lt;br /&gt;
Each of these results functions will return a single record from the database even though there may be several records that meet the criteria that you have set. To get more records you need to call the function again.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! id !! name !! email !! username&lt;br /&gt;
|- style=&amp;quot;background:yellow&amp;quot;&lt;br /&gt;
| 1 || John Smith || johnsmith@example.com || johnsmith&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Magda Hellman || magda_h@example.com || magdah&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Yvonne de Gaulle || ydg@example.com || ydegaulle&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== loadRow() ====&lt;br /&gt;
&lt;br /&gt;
loadRow() returns an indexed array from a single record in the table: &lt;br /&gt;
&amp;lt;source lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
. . .&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$row = $db-&amp;gt;loadRow();&lt;br /&gt;
print_r($row);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
will give:&lt;br /&gt;
&amp;lt;pre&amp;gt;Array ( [0] =&amp;gt; 1 [1] =&amp;gt; John Smith [2] =&amp;gt; johnsmith@example.com [3] =&amp;gt; johnsmith ) &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can access the individual values by using:&amp;lt;pre&amp;gt;$row[&#039;index&#039;] // e.g. $row[&#039;2&#039;]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
# The array indices are numeric starting from zero.&lt;br /&gt;
# Whilst you can repeat the call to get further rows, one of the functions that returns multiple rows might be more useful&lt;br /&gt;
&lt;br /&gt;
==== loadAssoc() ====&lt;br /&gt;
&lt;br /&gt;
loadAssoc() returns an associated array from a single record in the table: &lt;br /&gt;
&amp;lt;source lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
. . .&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$row = $db-&amp;gt;loadRow();&lt;br /&gt;
print_r($row);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
will give:&lt;br /&gt;
&amp;lt;pre&amp;gt;Array ( [id] =&amp;gt; 1 [name] =&amp;gt; John Smith [email] =&amp;gt; johnsmith@example.com [username] =&amp;gt; johnsmith )&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can access the individual values by using:&amp;lt;pre&amp;gt;$row[&#039;name&#039;] // e.g. $row[&#039;name&#039;]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
# Whilst you can repeat the call to get further rows, one of the functions that returns multiple rows might be more useful&lt;br /&gt;
&lt;br /&gt;
==== loadObject() ====&lt;br /&gt;
&lt;br /&gt;
loadObject returns a PHP object from a single record in the table: &lt;br /&gt;
&amp;lt;source lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
. . .&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$result = $db-&amp;gt;loadObject();&lt;br /&gt;
print_r($result);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
will give:&lt;br /&gt;
&amp;lt;pre&amp;gt;stdClass Object ( [id] =&amp;gt; 1 [name] =&amp;gt; John Smith [email] =&amp;gt; johnsmith@example.com [username] =&amp;gt; johnsmith )&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can access the individual values by using:&amp;lt;pre&amp;gt;$row-&amp;gt;index // e.g. $row-&amp;gt;email&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
# Whilst you can repeat the call to get further rows, one of the functions that returns multiple rows might be more useful&lt;br /&gt;
&lt;br /&gt;
===Single Column Results ===&lt;br /&gt;
&lt;br /&gt;
Each of these results functions will return a single column from the database. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! id !! name !! email !! username&lt;br /&gt;
|- &lt;br /&gt;
| 1 || style=&amp;quot;background:yellow&amp;quot; | John Smith || johnsmith@example.com || johnsmith&lt;br /&gt;
|-&lt;br /&gt;
| 2 || style=&amp;quot;background:yellow&amp;quot; | Magda Hellman || magda_h@example.com || magdah&lt;br /&gt;
|-&lt;br /&gt;
| 3 || style=&amp;quot;background:yellow&amp;quot; | Yvonne de Gaulle || ydg@example.com || ydegaulle&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== loadResultArray() ====&lt;br /&gt;
&lt;br /&gt;
loadResultArray() returns an indexed array from a single column in the table: &lt;br /&gt;
&amp;lt;source lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
$query = &amp;quot;&lt;br /&gt;
  SELECT name, email, username&lt;br /&gt;
    FROM . . . &amp;quot;;&lt;br /&gt;
. . .&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$column= $db-&amp;gt;loadResultArray();&lt;br /&gt;
print_r($column);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
will give:&lt;br /&gt;
&amp;lt;pre&amp;gt;Array ( [0] =&amp;gt; John Smith [1] =&amp;gt; Magda Hellman [2] =&amp;gt; Yvonne de Gaulle )&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can access the individual values by using:&amp;lt;pre&amp;gt;$column[&#039;index&#039;] // e.g. $column[&#039;2&#039;]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
# The array indices are numeric starting from zero.&lt;br /&gt;
# loadResultArray() is equivalent to loadResultArray(0)&lt;br /&gt;
&lt;br /&gt;
==== loadResultArray($index) ====&lt;br /&gt;
&lt;br /&gt;
loadResultArray($index) returns an indexed array from a single column in the table: &lt;br /&gt;
&amp;lt;source lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
$query = &amp;quot;&lt;br /&gt;
  SELECT name, email, username&lt;br /&gt;
    FROM . . . &amp;quot;;&lt;br /&gt;
. . .&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$column= $db-&amp;gt;loadResultArray(2);&lt;br /&gt;
print_r($column);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
will give:&lt;br /&gt;
&amp;lt;pre&amp;gt;Array ( [0] =&amp;gt; johnsmith@example.com [1] =&amp;gt; magda_h@example.com [2] =&amp;gt; ydg@example.com )&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can access the individual values by using:&amp;lt;pre&amp;gt;$column[&#039;index&#039;] // e.g. $column[&#039;2&#039;]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
loadResultArray($index) allows you to iterate through a series of columns in the results&lt;br /&gt;
&amp;lt;source lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
. . .&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
for ( $i = 0; $i &amp;lt;= 2; $i++ ) {&lt;br /&gt;
  $column= $db-&amp;gt;loadResultArray($i);&lt;br /&gt;
  print_r($column);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
will give:&lt;br /&gt;
&amp;lt;pre&amp;gt;Array ( [0] =&amp;gt; John Smith [1] =&amp;gt; Magda Hellman [2] =&amp;gt; Yvonne de Gaulle )&lt;br /&gt;
Array ( [0] =&amp;gt; johnsmith@example.com [1] =&amp;gt; magda_h@example.com [2] =&amp;gt; ydg@example.com )&lt;br /&gt;
Array ( [0] =&amp;gt; johnsmith [1] =&amp;gt; magdah [2] =&amp;gt; ydegaulle )&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
# The array indices are numeric starting from zero.&lt;br /&gt;
&lt;br /&gt;
=== Multi-Row Results ===&lt;br /&gt;
&lt;br /&gt;
Each of these results functions will return multiple records from the database. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! id !! name !! email !! username&lt;br /&gt;
|- style=&amp;quot;background:yellow&amp;quot;&lt;br /&gt;
| 1 || John Smith || johnsmith@example.com || johnsmith&lt;br /&gt;
|- style=&amp;quot;background:yellow&amp;quot;&lt;br /&gt;
| 2 || Magda Hellman || magda_h@example.com || magdah&lt;br /&gt;
|- style=&amp;quot;background:yellow&amp;quot;&lt;br /&gt;
| 3 || Yvonne de Gaulle || ydg@example.com || ydegaulle&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== loadRowList() ====&lt;br /&gt;
&lt;br /&gt;
loadRowList() returns an indexed array of indexed arrays from the table records returned by the query: &lt;br /&gt;
&amp;lt;source lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
. . .&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$row = $db-&amp;gt;loadRowList();&lt;br /&gt;
print_r($row);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
will give (with line breaks added for clarity):&lt;br /&gt;
&amp;lt;pre&amp;gt;Array ( &lt;br /&gt;
[0] =&amp;gt; Array ( [0] =&amp;gt; 1 [1] =&amp;gt; John Smith [2] =&amp;gt; johnsmith@example.com [3] =&amp;gt; johnsmith ) &lt;br /&gt;
[1] =&amp;gt; Array ( [0] =&amp;gt; 2 [1] =&amp;gt; Magda Hellman [2] =&amp;gt; magda_h@example.com [3] =&amp;gt; magdah ) &lt;br /&gt;
[2] =&amp;gt; Array ( [0] =&amp;gt; 3 [1] =&amp;gt; Yvonne de Gaulle [2] =&amp;gt; ydg@example.com [3] =&amp;gt; ydegaulle ) &lt;br /&gt;
)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can access the individual rows by using:&amp;lt;pre&amp;gt;$row[&#039;index&#039;] // e.g. $row[&#039;2&#039;]&amp;lt;/pre&amp;gt;&lt;br /&gt;
and you can access the individual values by using:&amp;lt;pre&amp;gt;$row[&#039;index&#039;][&#039;index&#039;] // e.g. $row[&#039;2&#039;][&#039;3&#039;]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
# The array indices are numeric starting from zero.&lt;br /&gt;
&lt;br /&gt;
==== loadAssocList() ====&lt;br /&gt;
&lt;br /&gt;
loadAssocList() returns an indexed array of associated arrays from the table records returned by the query: &lt;br /&gt;
&amp;lt;source lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
. . .&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$row = $db-&amp;gt;loadAssocList();&lt;br /&gt;
print_r($row);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
will give (with line breaks added for clarity):&lt;br /&gt;
&amp;lt;pre&amp;gt;Array ( &lt;br /&gt;
[0] =&amp;gt; Array ( [id] =&amp;gt; 1 [name] =&amp;gt; John Smith [email] =&amp;gt; johnsmith@example.com [username] =&amp;gt; johnsmith ) &lt;br /&gt;
[1] =&amp;gt; Array ( [id] =&amp;gt; 2 [name] =&amp;gt; Magda Hellman [email] =&amp;gt; magda_h@example.com [username] =&amp;gt; magdah ) &lt;br /&gt;
[2] =&amp;gt; Array ( [id] =&amp;gt; 3 [name] =&amp;gt; Yvonne de Gaulle [email] =&amp;gt; ydg@example.com [username] =&amp;gt; ydegaulle ) &lt;br /&gt;
) &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can access the individual rows by using:&amp;lt;pre&amp;gt;$row[&#039;index&#039;] // e.g. $row[&#039;2&#039;]&amp;lt;/pre&amp;gt;&lt;br /&gt;
and you can access the individual values by using:&amp;lt;pre&amp;gt;$row[&#039;index&#039;][&#039;column_name&#039;] // e.g. $row[&#039;2&#039;][&#039;email&#039;]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== loadAssocList($key) ====&lt;br /&gt;
&lt;br /&gt;
loadAssocList(&#039;key&#039;) returns an associated array - indexed on &#039;key&#039; - of associated arrays from the table records returned by the query: &lt;br /&gt;
&amp;lt;source lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
. . .&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$row = $db-&amp;gt;loadAssocList(&#039;username&#039;);&lt;br /&gt;
print_r($row);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
will give (with line breaks added for clarity):&lt;br /&gt;
&amp;lt;pre&amp;gt;Array ( &lt;br /&gt;
[johnsmith] =&amp;gt; Array ( [id] =&amp;gt; 1 [name] =&amp;gt; John Smith [email] =&amp;gt; johnsmith@example.com [username] =&amp;gt; johnsmith ) &lt;br /&gt;
[magdah] =&amp;gt; Array ( [id] =&amp;gt; 2 [name] =&amp;gt; Magda Hellman [email] =&amp;gt; magda_h@example.com [username] =&amp;gt; magdah ) &lt;br /&gt;
[ydegaulle] =&amp;gt; Array ( [id] =&amp;gt; 3 [name] =&amp;gt; Yvonne de Gaulle [email] =&amp;gt; ydg@example.com [username] =&amp;gt; ydegaulle ) &lt;br /&gt;
)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can access the individual rows by using:&amp;lt;pre&amp;gt;$row[&#039;key_value&#039;] // e.g. $row[&#039;johnsmith&#039;]&amp;lt;/pre&amp;gt;&lt;br /&gt;
and you can access the individual values by using:&amp;lt;pre&amp;gt;$row[&#039;key_value&#039;][&#039;column_name&#039;] // e.g. $row[&#039;johnsmith&#039;][&#039;email&#039;]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: Key must be a valid column name from the table; it does not have to be an Index or a Primary Key. But if it does not have a unique value you may not be able to retrieve results reliably.&lt;br /&gt;
&lt;br /&gt;
==== loadObjectList() ====&lt;br /&gt;
&lt;br /&gt;
loadObjectList() returns an indexed array of PHP objects from the table records returned by the query: &lt;br /&gt;
&amp;lt;source lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
. . .&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$result = $db-&amp;gt;loadObjectList();&lt;br /&gt;
print_r($result);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
will give (with line breaks added for clarity):&lt;br /&gt;
&amp;lt;pre&amp;gt;Array ( &lt;br /&gt;
[0] =&amp;gt; stdClass Object ( [id] =&amp;gt; 1 [name] =&amp;gt; John Smith &lt;br /&gt;
    [email] =&amp;gt; johnsmith@example.com [username] =&amp;gt; johnsmith ) &lt;br /&gt;
[1] =&amp;gt; stdClass Object ( [id] =&amp;gt; 2 [name] =&amp;gt; Magda Hellman &lt;br /&gt;
    [email] =&amp;gt; magda_h@example.com [username] =&amp;gt; magdah ) &lt;br /&gt;
[2] =&amp;gt; stdClass Object ( [id] =&amp;gt; 3 [name] =&amp;gt; Yvonne de Gaulle &lt;br /&gt;
    [email] =&amp;gt; ydg@example.com [username] =&amp;gt; ydegaulle ) &lt;br /&gt;
)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can access the individual rows by using:&amp;lt;pre&amp;gt;$row[&#039;index&#039;] // e.g. $row[&#039;2&#039;]&amp;lt;/pre&amp;gt;&lt;br /&gt;
and you can access the individual values by using:&amp;lt;pre&amp;gt;$row[&#039;index&#039;]-&amp;gt;name // e.g. $row[&#039;2&#039;]-&amp;gt;email&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== loadObjectList(&#039;key&#039;) ====&lt;br /&gt;
&lt;br /&gt;
loadObjectList($key) returns an associated array - indexed on &#039;key&#039; - of objects from the table records returned by the query: &lt;br /&gt;
&amp;lt;source lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
. . .&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$row = $db-&amp;gt;loadObjectList(&#039;username&#039;);&lt;br /&gt;
print_r($row);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
will give (with line breaks added for clarity):&lt;br /&gt;
&amp;lt;pre&amp;gt;Array ( &lt;br /&gt;
[johnsmith] =&amp;gt; stdClass Object ( [id] =&amp;gt; 1 [name] =&amp;gt; John Smith &lt;br /&gt;
    [email] =&amp;gt; johnsmith@example.com [username] =&amp;gt; johnsmith ) &lt;br /&gt;
[magdah] =&amp;gt; stdClass Object ( [id] =&amp;gt; 2 [name] =&amp;gt; Magda Hellman &lt;br /&gt;
    [email] =&amp;gt; magda_h@example.com [username] =&amp;gt; magdah ) &lt;br /&gt;
[ydegaulle] =&amp;gt; stdClass Object ( [id] =&amp;gt; 3 [name] =&amp;gt; Yvonne de Gaulle &lt;br /&gt;
    [email] =&amp;gt; ydg@example.com [username] =&amp;gt; ydegaulle ) &lt;br /&gt;
)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can access the individual rows by using:&amp;lt;pre&amp;gt;$row[&#039;key_value&#039;] // e.g. $row[&#039;johnsmith&#039;]&amp;lt;/pre&amp;gt;&lt;br /&gt;
and you can access the individual values by using:&amp;lt;pre&amp;gt;$row[&#039;key_value&#039;]-&amp;gt;column_name // e.g. $row[&#039;johnsmith&#039;]-&amp;gt;email&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: Key must be a valid column name from the table; it does not have to be an Index or a Primary Key. But if it does not have a unique value you may not be able to retrieve results reliably.&lt;br /&gt;
&lt;br /&gt;
=== Misc Result Set Methods ===&lt;br /&gt;
&lt;br /&gt;
==== getNumRows() ====&lt;br /&gt;
&lt;br /&gt;
getNumRows() will return the number of result rows found by the last query and waiting to be read. To get a result from getNumRows() you have to run it &#039;&#039;&#039;after&#039;&#039;&#039; the query and &#039;&#039;&#039;before&#039;&#039;&#039; you have retrieved any results.  &lt;br /&gt;
&amp;lt;source lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
. . .&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$db-&amp;gt;query();&lt;br /&gt;
$num_rows = $db-&amp;gt;getNumRows();&lt;br /&gt;
print_r($num_rows);&lt;br /&gt;
$result = $db-&amp;gt;loadResultList();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
will return &amp;lt;pre&amp;gt;3&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: if you run getNumRows() after loadResultList() - or any other retrieval method - you may get a PHP Warning:&lt;br /&gt;
&amp;lt;pre&amp;gt;Warning: mysql_num_rows(): 80 is not a valid MySQL result resource &lt;br /&gt;
in D:\xampp\htdocs\joomla1.5a\libraries\joomla\database\database\mysql.php on line 344&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Tips, Tricks &amp;amp; FAQ==&lt;br /&gt;
We had a few people lately using sub-queries like these:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;SQL&amp;quot;&amp;gt;&lt;br /&gt;
SELECT * FROM #__example WHERE id IN (SELECT * FROM #__example2);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
These kind of queries are only possible in MySQL 4.1 and above. Another way to achieve this, is splitting the query into two:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$query = &amp;quot;SELECT * FROM #__example2&amp;quot;;&lt;br /&gt;
$database-&amp;gt;setQuery($query);&lt;br /&gt;
$query = &amp;quot;SELECT * FROM #__example WHERE id IN (&amp;quot;. implode(&amp;quot;,&amp;quot;, $database-&amp;gt;loadArray()) .&amp;quot;)&amp;quot;;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;noinclude&amp;gt;[[Category:Development]][[Category:Database]]&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jedbox</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=J1.5:Manifest_files&amp;diff=13797</id>
		<title>J1.5:Manifest files</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=J1.5:Manifest_files&amp;diff=13797"/>
		<updated>2009-03-29T19:00:05Z</updated>

		<summary type="html">&lt;p&gt;Jedbox: /* Packaging */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{review}}&lt;br /&gt;
{{joomla version category|1.5}}&lt;br /&gt;
[[Category:Development]]&lt;br /&gt;
&lt;br /&gt;
== Packaging ==&lt;br /&gt;
The script needs to be extended for sorting your files into folders within the archive, which are needed for the Joomla! extension installer API. See the recommended file locations below:&lt;br /&gt;
&lt;br /&gt;
{| border=1 cellspacing=0 cellpadding=2&lt;br /&gt;
|-&lt;br /&gt;
! Development file&lt;br /&gt;
! Archive folder&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;/components/com_&amp;lt;component name&amp;gt;/**&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;/site/**&amp;lt;/tt&amp;gt; (mimic folder structure)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;/administrator/components/com_&amp;lt;component name&amp;gt;/**&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;/admin/**&amp;lt;/tt&amp;gt; (mimic folder structure)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;/language/en-GB/en-GB.com_&amp;lt;component name&amp;gt;.ini&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;/language/site&amp;lt;/tt&amp;gt; (flatten structure: discard language code subfolders)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;administrator/language/en-GB/en-GB.com_&amp;lt;component name&amp;gt;.ini&amp;lt;/tt&amp;gt;&lt;br /&gt;
| &amp;lt;tt&amp;gt;/language/admin&amp;lt;/tt&amp;gt; (flatten structure: discard language code subfolders)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;install.&amp;lt;component name&amp;gt;.php&amp;lt;/tt&amp;gt;&lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;uninstall.&amp;lt;component name&amp;gt;.php&amp;lt;/tt&amp;gt;&lt;br /&gt;
| /&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;install.&amp;lt;component name&amp;gt;.sql&amp;lt;/tt&amp;gt;&lt;br /&gt;
| /admin&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;uninstall.&amp;lt;component name&amp;gt;.sql&amp;lt;/tt&amp;gt;&lt;br /&gt;
| /admin&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;tt&amp;gt;&amp;lt;component name&amp;gt;.xml&amp;lt;/tt&amp;gt; &#039;&#039;&#039;The manifest file&#039;&#039;&#039;&lt;br /&gt;
| /&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== The Component Manifest File ==&lt;br /&gt;
&lt;br /&gt;
Your component needs an xml-file declaring meta data (author, license, etc.), which files are included and indicates some special files to the installer API, like the included languages and SQL-scripts for (un)installing.&lt;br /&gt;
&lt;br /&gt;
The most important xml-elements are explained below.  There is a [http://dev.joomla.org/xml/1.5/component-install.dtd manifest DTD for Joomla! 1.5 components] which can be used as a guide to the syntax, but it cannot be used to validate the manifest due to a problem with the 1.5 component installer.  This should be corrected for Joomla! 1.6 onwards.&lt;br /&gt;
&lt;br /&gt;
=== The root element ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;install type=&amp;quot;&#039;&#039;component|module|...&#039;&#039;&amp;quot; method=&amp;quot;&#039;&#039;upgrade&#039;&#039;&amp;quot;&amp;gt;&lt;br /&gt;
     &amp;lt;name&amp;gt;&#039;&#039;component name&#039;&#039;&amp;lt;/name&amp;gt;&lt;br /&gt;
     &amp;lt;version&amp;gt;&#039;&#039;x.y&#039;&#039;&amp;lt;/version&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
Enter the &#039;&#039;&#039;type&#039;&#039;&#039; of your extension, and indicate whether the installer shall be able to overwrite existing files. If the &#039;&#039;&#039;method&#039;&#039;&#039; attribute is not given, the installer will quit gracefully when encountering any existing file on the webspace.&lt;br /&gt;
&lt;br /&gt;
=== The file list ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;install&amp;gt;&lt;br /&gt;
     &amp;lt;files folder=&amp;quot;site&amp;quot;&amp;gt;&lt;br /&gt;
         &amp;lt;folder&amp;gt;&#039;&#039;views&#039;&#039;&amp;lt;/folder&amp;gt;&lt;br /&gt;
         ...&lt;br /&gt;
         &amp;lt;filename&amp;gt;&#039;&#039;component-name.php&#039;&#039;&amp;lt;/file&amp;gt;&lt;br /&gt;
         ...&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;administration&amp;gt;&lt;br /&gt;
         &amp;lt;files folder=&amp;quot;admin&amp;quot;&amp;gt;&lt;br /&gt;
             ...&lt;br /&gt;
&lt;br /&gt;
List all files which make up the code of your component, which will later go to the &amp;lt;tt&amp;gt;component&amp;lt;/tt&amp;gt; subfolder of the site. Same for the administration part.&lt;br /&gt;
&lt;br /&gt;
=== The language files ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;install&amp;gt;&lt;br /&gt;
     &amp;lt;languages folder=&amp;quot;lang/site&amp;quot;&amp;gt;&lt;br /&gt;
         &amp;lt;language tag=&amp;quot;&#039;&#039;en-GB&#039;&#039;&amp;quot;&amp;gt;en-GB.com_&#039;&#039;&amp;lt;component name&amp;gt;&#039;&#039;.ini&amp;lt;/language&amp;gt;&lt;br /&gt;
         ...&lt;br /&gt;
 &lt;br /&gt;
     &amp;lt;administration&amp;gt;&lt;br /&gt;
         &amp;lt;languages folder=&amp;quot;lang/admin&amp;quot;&amp;gt;&lt;br /&gt;
             &amp;lt;language ...&lt;br /&gt;
&lt;br /&gt;
The language files for the front-end will be copied to the respective language code subfolders. Same for the administration part.&lt;br /&gt;
&lt;br /&gt;
=== SQL scripts ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;install&amp;gt;&lt;br /&gt;
     &amp;lt;install&amp;gt;&lt;br /&gt;
         &amp;lt;sql&amp;gt;&lt;br /&gt;
             &amp;lt;file driver=&amp;quot;&#039;&#039;mysql&#039;&#039;&amp;quot;&amp;gt;&#039;&#039;install.component.sql&#039;&#039;&amp;lt;/file&amp;gt;&lt;br /&gt;
         &amp;lt;/sql&amp;gt;&lt;br /&gt;
     &amp;lt;/install&amp;gt;&lt;br /&gt;
     &amp;lt;uninstall&amp;gt;&lt;br /&gt;
         &amp;lt;sql&amp;gt;&lt;br /&gt;
             &amp;lt;file driver=&amp;quot;&#039;&#039;mysql&#039;&#039;&amp;quot;&amp;gt;&#039;&#039;uninstall.component.sql&#039;&#039;&amp;lt;/file&amp;gt;&lt;br /&gt;
         &amp;lt;/sql&amp;gt;&lt;br /&gt;
     &amp;lt;/uninstall&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you need tables added or altered for your component, put the statements into an sql script. The sql statements will be executed by the installer after copying of the files. Do not forget to indicate &#039;&#039;&#039;the way back&#039;&#039;&#039; and develop a script for cleaning up when the components shall be uninstalled.&lt;br /&gt;
&lt;br /&gt;
=== Custom install code ===&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;install&amp;gt;&lt;br /&gt;
     &amp;lt;installfile&amp;gt;install.component.php&amp;lt;/installfile&amp;gt;&lt;br /&gt;
     &amp;lt;uninstallfile&amp;gt;uninstall.component.php&amp;lt;/uninstallfile&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The code in these files will be executed by the installer upon install/uninstall. See API description below.&lt;br /&gt;
&lt;br /&gt;
== Custom Installer Code API ==&lt;br /&gt;
&lt;br /&gt;
If you need more to be done to the live site upon (un)installation than deploying the files, languages, and executing SQL statements, the installer files are your way. For example, you might need to update existing data entries in the tables during an upgrade installation. Indicate the scripts in the manifest file (see above), and the code will be executed after deployment.&lt;br /&gt;
&lt;br /&gt;
The install script should define exactly one function:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=php&amp;gt;&lt;br /&gt;
function com_install()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The uninstall script, respectively, should also define exactly one function:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=php&amp;gt;&lt;br /&gt;
function com_uninstall()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jedbox</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Incorrect_Install_File&amp;diff=13793</id>
		<title>Incorrect Install File</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Incorrect_Install_File&amp;diff=13793"/>
		<updated>2009-03-29T11:47:27Z</updated>

		<summary type="html">&lt;p&gt;Jedbox: /* Putting the installfile in a different directory */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This error will occur when the &amp;lt;installfile&amp;gt; tag in the XML install file for a component is incorrectly specified. Commonly this occurs when an extension developer specifies the files in their administrator files section in addition to specifying an install file. Typically this doesn&#039;t cause an issue because the installer would silently ignore the error and continue working, however due to a change in 1.5.10 to fix an issue when the tag is used properly this may cause issues with extensions that use &#039;method=&amp;quot;upgrade&amp;quot;&#039; for the extension install files.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;installfile&amp;gt; tag itself will handle copying the file denoted by that location from the root of the installation package (where the XML install file is) to the administrator section of the component. &lt;br /&gt;
&lt;br /&gt;
Everything that is stated about the installfile is the same as the uninstallfile.&lt;br /&gt;
&lt;br /&gt;
== Putting the installfile in a different directory ==&lt;br /&gt;
Say for example you didn&#039;t want the install files to live in the root of your extension but wanted to put them in a subfolder in your administrator section. You may already be doing this for pre-1.5.10 in an incorrect way. &lt;br /&gt;
&lt;br /&gt;
If you create in the root of your install package a folder matching your preferred target folder (e.g. &amp;quot;install&amp;quot;) and then locate the install and uninstall files in that directory then you can specify the following:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;installfile&amp;gt;install/install.php&amp;lt;/installfile&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Doing this alone will cause your installation to still fail because in the administrator directory there still won&#039;t be an &#039;install&#039; folder created. To solve this, create an &#039;install&#039; folder in your administrator folder of the package and also place an &#039;index.html&#039; file into this folder. Then in the files section for the administrator put the following line:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;folder&amp;gt;install&amp;lt;/folder&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This will automatically create the install folder for you and copy the index.html file across. Then when the installer comes to copy the install file across both the source and destination files will exist properly.&lt;br /&gt;
[[Category:Version 1.5.10 FAQ]]&lt;/div&gt;</summary>
		<author><name>Jedbox</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Joomla_Translation_Program&amp;diff=12144</id>
		<title>Joomla Translation Program</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Joomla_Translation_Program&amp;diff=12144"/>
		<updated>2008-12-13T10:46:01Z</updated>

		<summary type="html">&lt;p&gt;Jedbox: /* How can you help? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;&#039;&#039;&amp;quot;...providing support for the international community is a core value of Joomla!...&amp;quot;&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
[[Image:Workgroups_translation.jpg|right]]&lt;br /&gt;
&lt;br /&gt;
The purpose of the Translation Working Group is to be a liaison between the international community and the other Joomla! Teams on user and technical matters relating to the translation of the Joomla! application.&lt;br /&gt;
&lt;br /&gt;
We have more than 50 local language coordinators representing their local teams in Translation Working Group.&lt;br /&gt;
&lt;br /&gt;
See a list of [http://forum.joomla.org/memberlist.php?mode=group&amp;amp;g=13 current members here].&lt;br /&gt;
&lt;br /&gt;
[http://forum.joomla.org/memberlist.php?mode=viewprofile&amp;amp;u=178 Group Leader]&lt;br /&gt;
&lt;br /&gt;
== How can you help? ==&lt;br /&gt;
&lt;br /&gt;
Joomla! Project wish to see the Joomla! CMS made available in any language.&lt;br /&gt;
&lt;br /&gt;
For that to become possible we need the help from talented native speakers who wish to contribute by translating Joomla! 1.5 language packages into their native language.&lt;br /&gt;
&lt;br /&gt;
To create a translation you must create a [http://docs.joomla.org/How_to_create_a_language_pack Joomla! language pack]. [[Technical Guidelines for Translation]]&lt;br /&gt;
&lt;br /&gt;
In case your language is not currently available at this list [http://joomlacode.org/gf/project/jtranslation/frs/ at joomlacode] and you have already created a local translation then please follow these steps:&lt;br /&gt;
&lt;br /&gt;
1. Create a user and a new project at [http://joomlacode.org/gf/ joomlacode]&lt;br /&gt;
&lt;br /&gt;
2. When project approved and you have uploaded your language files then please contact [http://forum.joomla.org/memberlist.php?mode=viewprofile&amp;amp;u=178 Joomla! Translation Coordinator]&lt;br /&gt;
&lt;br /&gt;
Should your language already be listed and you wish to contribute then please start by contacting local Translation Coordinator.&lt;br /&gt;
&lt;br /&gt;
== Do you have language and/or translation questions? ==&lt;br /&gt;
&lt;br /&gt;
For questions about language please visit language forums at:&lt;br /&gt;
&lt;br /&gt;
[[jforum:309|Joomla! 1.0.x language forum]]&lt;br /&gt;
&lt;br /&gt;
[[jforum:485|Joomla! 1.5.x language forum]]&lt;br /&gt;
&lt;br /&gt;
For questions about translation please visit translation forum at:&lt;br /&gt;
&lt;br /&gt;
[[jforum:11|Translations]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Thanks.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Translations Working Group]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Jedbox</name></author>
	</entry>
</feed>