Unit Testing Packages

As you develop splint packages, you'll likely need to run tests to make sure your package will run as expected in a given environment, especially when you follow the TDD approach.

Splint offers you a way to use the in-built unit testing library provided by Code Igniter. All you need to do is create and write test classes in a folder named tests in your package root directory and then run the below from a Controller which you want to run the tests. (Assuming your package is being developed within a Code Igniter distribution and nested exactly as it would be if installed. This is the recommended way to develop a Splint package).

$this->load->test("vendor/package_name", true);

The above will simply run the tests in the tests folder and output the results to the browser.

The second parameter tells the test loader use a strict or non strict policy in value assertions. This parameter is optional and defaults to true if omitted.

Below is an example test class from a package francis94c/blog whose file location is tests/BlogTest.php. Notice how the name of the file matches the name of the class. This is because tests are loaded just like libraries.

<?php
defined('BASEPATH') OR exit('No direct script access allowed');
 
class BlogTest {
 
  function uiTest(&$ci) {
    $ci->load->splint("francis94c/blog", "+Blogger", null, "blogger");
    $ci->unit->run($ci->blogger->install("admins", "id", 1), true, "Install Blog Database.");
    $ci->unit->run($ci->blogger->install("release_notes", "admins", "id", 1), true, "Install Release Notes Blog Database.");
    $ci->unit->run($ci->blogger->install("", "admins", "id", 1), true, "Install Blog Database.");
    $ci->unit->run($ci->blogger->install("test_name", "admins", "id", 1), true, "Install Test Blog Database.");
    $ci->blogger->loadEditor("callback");
    $oldVal = $_POST["action"];
    $_POST["action"] = "save";
    unset($_POST["id"]);
    $ci->blogger->renderPostItems(null, null, null, 1, 0);
    $ci->blogger->renderPostItems(null, null, "welcome_message", 1, 0);
    $ci->blogger->savePost(1);
    $ci->blogger->renderPost("Hello", null);
    $ci->blogger->renderPost("Hello", null);
    $ci->blogger->renderPost("Hello", "welcome_message");
    echo $ci->blogger->metaOg($ci->blogger->getPost("Hello", false));
    $_POST["title"] .= "1E";
    $ci->blogger->savePost(1);
    $_POST["title"] .= "1ETY";
    $ci->blogger->renderPostItems(null, null, null, 1, 0);
    $ci->blogger->renderPostItems("welcome_message", "welcome_message", null, 1, 0);
    $_POST["action"] = $oldVal;
    $this->cleanUp($ci);
  }
  function libTest(&$ci) {
    $ci->load->splint("francis94c/blog", "+Blogger", null, "blogger");
    $ci->blogger->setName("test_name");
    $ci->unit->run($ci->blogger->getName(), Blogger::TABLE_PREFIX . "_test_name", "Test Blogger setName()");
    $this->cleanUp($ci);
  }
  function createPostTest(&$ci) {
    $ci->load->splint("francis94c/blog", "+Blogger", null, "blogger");
    $ci->unit->run($ci->blogger->savePost(1), Blogger::CREATE, "Create Post Test.");
    $_POST["action"] = "createAndPublish";
    $_POST["title"] .= "1E";
    $ci->unit->run($ci->blogger->savePost(1), Blogger::CREATE_AND_PUBLISH, "Create and Publish Post Test.");
    $_POST["action"] = "save";
    $_POST["id"] = 1;
    $_POST["title"] .= "1E";
    $ci->unit->run($ci->blogger->savePost(1), Blogger::EDIT, "Edit Post.");
    $_POST["action"] = "publish";
    $_POST["title"] .= "1E";
    $ci->unit->run($ci->blogger->savePost(1), Blogger::PUBLISH, "Publish Post.");
    $_POST["title"] .= "1E";
    $this->cleanUp($ci);
  }
  private function cleanUp(&$ci) {
    $ci->db->empty_table("blogger_posts");
    $ci->db->empty_table("blogger_posts_test_name");
    $ci->db->empty_table("blogger_posts_release_notes");
  }
}
?>

As you can see, every function in the test class has a $ci parameter which is bound by reference to the Code Igniter instance.

Running Tests that Involve form POST parameters

If your are building packages that may need to interact with the values from a form, you can create a post_data.json file in your tests folder an set POST parameters using a JSON key-value pair as shown below.

{
  "name":   "Jonathan Sidwell",
  "action": "save",
  "title":  "Hello",
  "editor": "World"
}

Having a post_data.json file in your tests folder will cause the test to show you a a page with the message 'Parameters have been loaded!' and a button to actually run the tests when the tests are loaded.

If you need to alter the POST values while running your test, you can do that with the PHP associative $_POST variable.

If you would like to test your JavaScript end to verify further that your library as a whole has an error free form interaction or for other purposes, you an make use of the JavaScript testing functionality of Splint. The Javascript testing functionality of Splint leverages on Qunit.

Unit Testing JavaScript

If you have some JavaScript codes relating to your package, that you would like to test, Splint has a support for QUnit, a JavaScript Unit Testing Framework/Library from JQuery.

All you need do is create a js folder under the tests folder of your package and create .php files containing your QUnit JavaScript test within a <script> tag as below.

<?php if (!defined('BASEPATH')) exit('No direct script access allowed');?>
<script type="text/javascript">
QUnit.test( "hello test", function( assert ) {
  assert.ok( 1 == "1", "Passed!" );
});
</script>

The Unit Testing system will detect and run the tests alongside your PHP tests.

JavaScript tests are run first if present.

The ideal way to use this feature when developing packages with JavaScript functionalities, is to create those functionalities as PHP view files of your package and load them like views as shown below before testing them just as you would load them anywhere you need them before using them.

my_js_code_package_views_folder.php
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');?>
<script type="text/javascript">
function addTwoNumbers(a, b) {
  return a + b;
}
</script>
my_js_test.php
<?php
if (!defined('BASEPATH')) exit('No direct script access allowed');
$ci =& get_instance();
$ci->load->splint("vendor/package_name", "-my_js_code_in_package_views_folder");
?>
<script type="text/javascript">
QUnit.test( "hello test", function( assert ) {
  assert.ok( addTwoNumbers(5, 5)  == 10, "Passed!" );
});
</script>

NEXT

PREVIOUS

Other Topics