Chapter: Creating unit tests
« Debugging and using jLog | ^ Development helper tools |
− Table of content
See the definition of unit-test on wikipedia: https://en.wikipedia.org/wiki/Unit-testing .
Creating tests with PHPUnit ¶
Using PHPUnit to create tests is the prefered method in jelix 1.3 and higher. See the manual of PHPUnit to know how to use it. You must install PHPUnit, it is not provided in the Jelix package.
Jelix brings some helpers. The createapp
command has created a
tests/runtests.php
in your application (or copy the file
lib/jelix-scripts/templates/tests/runtests.php
). You will launch this file
instead of PHPUnit. It then discover your tests files in all modules. It avoids
to not fill a phpunit.xml
with all your tests stored in your modules.
To do so:
- create your tests in the
tests/
directory of your modules - store them in files with the suffix
.pu.php
(and notTests.php
as usual with PHPUnit) - launch
php runtests.php --all-modules
to run tests in all modules - launch
php runtests.php --module foo
to run tests only in the module foo - you can add the option
--testtype xxxx
and it launches only*.xxxx.pu.php
files. That way, you can separate unit tests, functional tests etc..
You can use all others options of PHPUnit with runtests.php.
Creating tests with Simpletest ¶
Simpletests is the framework used in jelix since the begining. However, it is deprecated since Jelix 1.3, and will be removed in futur version after Jelix 1.6. It is still provided with the Jelix developer edition.
Jelix contains the "junittests" module and a copy of SimpleTest. Other distributions of Jelix require a copy of libs/simpletest and lib/jelix-modules/junittests.
For the test-runner to be avalaible, please add the following to your project's configuration :
enableTests = on
Setting "off" desactivates the online test-runner.
Test files ¶
Test-files are scripts defining your tests and are lying in your module subfolder : "tests"; you should develop classes inherinting from simpletest's UnitTestCase.
This test-files will be used by JUnitTest runner's HTTP interface.
Test-files name label interface's objects :
- s/\./ :/ (dots are replaced by ": "),
- s/_/ / (underscores are replaced by spaces).
Test-file names must append any of these suffixes must be appended :
- *.html.php : runnable with the HTTP interface.
- .cli.php : runnable with the CLI interface (provided by forge's project jphpunit..)
- .html_cli.php : runnable through both interface.
For example, running tests from test-file "jdao.main.api_with_pdo.html.php" is limited to the HTTP interface runner. It's test-case will be labeled "jdao: main api with pdo".
Creating tests ¶
Use SimpleTest overview to write your tests.
Junittests provides a reporter and a test-groupper.
The Jelix test-suite "TestApp" is avalaible for download and can be used as example.
Example : create the test-file "shop/tests/cart.html_cli.php" to test cart.php of the module "shop" :
/*
Class name should be unique from all modules, it's recommanded that it contains
the module name.
*/
class testShopCart extends UnitTestCase {
/*
Tests that new cart method getProductList() returns an empty array.
*/
function testNewCartHasNoProductsInList() {
// Create a new cart
$cart = jClasses::create("shop~cart");
// Test the return value of cart method getProductList()
$return = $cart->getProductList();
$expected = array();
$this->assertIdentical( $return, $expected );
}
}
When this test passes : cart method getProductList() returns the expected value (an empty array) when created by jClasses::create().
You can create other tests and share a fixture accross tests.
class testShopCart extends UnitTestCase {
protected static $cart;
const PRODUCT_NAME_FIXTURE = "Dune";
/**
* Asserts that the cart is empty.
*
* @param object ShopCartClass object.
*/
function assertCartEmpty( ShopCartClass $cart )
{
// Test the return value of cart method getProductList()
$return = $cart->getProductList();
$expected = array();
$this->assertIdentical( $return, $expected );
}
function testNewCartHasNoProductsInList() {
// Create a new cart
self::$cart = jClasses::create("shop~cart");
// Assert that the new cart is empty
$this->assertCartEmpty( self::$cart );
}
function testAddingAFirstCartProduct() {
// Create a product
$product = jClasses::create("shop~product");
$product->label = self::PRODUCT_NAME_FIXTURE;
$product->price = 12.40;
// Add it to the cart
$panier->addProduct($product);
// Test cart's method getProductList() return value
$return = self::$class->getProductList();
// Return value is an array
$this->assertTrue(is_array($return));
$this->assertEquals(count($return), 1);
$this->assertIsA(current($return), 'productClass');
}
function testRemovingTheCartProduct()
{
self::$cart->removeProduct(self::PRODUCT_NAME_FIXTURE);
// Assert that the new cart is empty
$this->assertCartEmpty(self::$cart);
}
}
Web-interface test-runner ¶
Connect to the main junittest module action as with the following URL to the Jelix test-suite : http://testapp.jelix.org/index.php?module=junittests
Setting "enableTests = off" in the project configuration would generate a 404 HTTP page access error response on this url.
Links are provided to run test-cases individually or all a module's tests in the left frame.
Success and failures are counted and reported at the end of the test. Note that your browser could timeout before large tests are done.
Junittests uses it's own HTML responses, and uses it's tests/design.css which should be copied from the "install" directory to your www directory.
Command-line test runner ¶
You can run the test with the tests.php
script in the scripts directory of your jelix application. You can use the testapp application (see in "Test Application") to have a running sample of it.
Here is the list of the different commands available :
Display all the tests ¶
Allows you to display the list of all the tests of your application for each module of it. You have to give the name of the controller here because the "help" keyword gives the general help for Jelix command line.
php tests.php default:help
Run all the tests of the application ¶
Runs the whole set of tests of your Jelix application. No need for a specific parameter here, because running all the tests is the default action.
php tests.php
Run all the tests of a module ¶
Runs the whole set of tests of a specified module. You have to specify here the name of the module as a parameter. Here is an example for the testapp application :
php tests.php module jelix_tests
Run only one test ¶
Runs a specified test. You have here to give the name of the module and the name of the test as parameters. You can help yourself by using the help command specified above to get it.
php tests.php single jelix_tests core.jlocale
When the running of tests ends, the number of unit tests that succeeded and faild is displayed.
If you don't have the tests.php
file in the scripts directory, you can retrieve all the necessary files (the script and the config file) in the install directory of the junittests module.