Open Source Software Technical Articles

Want the Best of the Wazi Blogs Delivered Directly to your Inbox?

Subscribe to Wazi by Email

Your email:

Connect with Us!

Current Articles | RSS Feed RSS Feed

Drupal 7: More on custom modules and checking your data

  
  
  

Testing and data validation are important parts of any software development projects. In this tutorial we'll see how to validate information entered into a Drupal form and learn how to test modules as a whole.

You may want to look back at our previous tutorials on Drupal 7, in which we wrote a custom Drupal 7 module that accessed the Drupal database and generated a custom block, looked at how to handle Drupal paths, and set up a configuration form for our module. Here we'll use the same module as we did in the previous tutorials, called same_author, which lives in the [DRUPAL]/sites/all/modules/ directory.

Validating data

The Drupal Forms API has some limited built-in validation, and provides scope for adding your own. We'll demonstrate this by creating a same_author_form_validate() function to check a couple of the values in our form. (You mustn't call the function same_author_validate(), as that's part of the regular hook system.) Here's a suggested function:

 
function same_author_form_validate($form, &$form_state) {
  $same_author_days = $form_state['values']['same_author_days'];
  if (!is_numeric(same_author_days)) {
    form_set_error('same_author_days', 
                   t("The number of days value must be a number"));
  }
  else if ($same_author_days <= 0) {
    form_set_error('same_author_days', 
                   t("The number of days value must be positive"));
  }
  else if ($same_author_days >= 31) {
    form_set_error('same_author_days', 
                   t("The number of days value must be 31 or less"));
  }
}

You may remember the &$form_state parameter from our same_author_form() function from the last tutorial. $form_state is an array variable that keeps track of the form and its state (including variable values) throughout its processing. This variable enables us to access information about the form that has been set already. (You can read more about $form_state in the form_submit() docs.) In this case, the information we want is from the values array, which holds the values entered in the form. We want the value the user entered for same_author_days.

The code itself is straightforward. We get the same_author_days value that the user entered, check that it is numeric, that it is positive (0 or more), and that it is at most 31 days. (It would be good practice, and provide a better user experience, to state this on the form itself.) If any of those conditions fails, the form errors, and Drupal will show the error on the form in red. As usual, our string messages are wrapped in t().

Drupal form validation

Testing your module

In addition to form validation capabilities, Drupal provides a basic testing module, SimpleTest, which creates a virtual Drupal install and web browser and runs specified tests in it. Because the tests run in this brand new temporary Drupal install, created by SimpleTest just for this set of tests, none of your users or configuration settings exist – anything you need you have to set up first. However, for our basic module test, we don't need anything beyond the module itself.

First, make sure that SimpleTest is enabled. Go to the Modules admin page, find the Testing module in the Core section, tick the box to enable it and save, then go to the module's configuration link to make sure that all the output options are enabled. You want as much information as possible while you're developing!

Once you've got testing enabled, create the tests for the Same Author module. First, set up the skeleton of the file and declare it in your module.info file. For our module, the skeleton of the same_author.test file looks like this:

<?php
/**
 * @file
 * Testing the Same Author module
 */

class SameAuthorTestCase extends DrupalWebTestCase {

  public static function getInfo() {
    return array(
      'name' => 'Same Author module functionality',
      'description' => 'Tests some hooks in the Same Author module',
      'group' => 'Same Author',
    );
  }

  public function setUp() {
    parent::setUp('same_author');
  }
}

Notice that the PHP marker goes only at the start of the file; don't use the PHP close marker. Also notice that this file creates a new class rather than declaring hooks as with the same_author.module file. This class must extend DrupalWebTestCase, as this provides the test framework. You also must have a getInfo() function, with the three values specified here, for your test to work. This function provides the user interface information that will be shown on the SimpleTest page.

Before actually running any tests you need to set the module up by creating the setUp() function. This will be run automatically by SimpleTest, and here we just use it to call up to DrupalWebTestCase.setUp() with the module name.

You also need to add a single line to same_author.info. The files[] directive in a module's .info file is used to list all files that contain class or interface declarations, as our test file does. Drupal scans the files when the module is loaded, and code can then be dynamically loaded as needed. Without this directive, Drupal won't find your test code and your tests won't run.

files[] = same_author.test

Now for a couple of actual tests! The names of these testing functions don't matter, but for maintainability they should be meaningful.

 
public function testMenu() {
  $menuitems = module_invoke('same_author', 'menu');
  $this->assertEqual(1, count($menuitems), t('One item in menu'));
  $this->assertIdentical($items['admin/config/content/same_author']['title'],
                         'Same Author config',
                         t('Title of menu item is correct'));
}

public function testBlockInfo() {
  $blockinfo = module_invoke('same_author', 'block_info');
  $this->assertFalse(count($blockinfo) > 1, t('At most one block defined.'));
}

public function testBlockContent() {
  $blockcontent = module_invoke('same_author', 'block_view', 'same_author');
  $this->assertNotNull($blockcontent['content'], t('Block has content.'));
}

For each function, the first line invokes the module and the hook that we're testing. The syntax is module_invoke('module', 'hookname'), where hookname is taken from the function title hook_hookname() in the module code. Note that in the case of the block content, the hook has multiple cases, so we need to specify the same_author case (go back and check the code if you need to clarify this).

Once we have the output from the hook under testing, we use one of the provided assertions to test it. Use assertEqual() for numbers and assertIdentical() for strings. assertFalse() and assertNotNull() do exactly as you'd expect. In each case, the final argument to the function is a string (run through t()) that tells you what to conclude if the test passes.

Run the tests by going to admin/config/development/testing on your Drupal site, selecting the Same Author test, and clicking Run. It can take a little while to fire up the virtual environment and run the tests.

This level of testing is a good start, but this test suite is also incomplete as it stands. Take a look at the information on what to test in the SimpleTest tutorial and see if you can write the other appropriate tests for this module.

This sort of unit testing doesn't obviate user testing, such as loading up the web page yourself and looking at it, but it can identify some problems quickly.

Drupal is immensely powerful and flexible, and there are plenty more things you can do with a module once you understand the basics we have covered in these tutorials. Check out the online API and documentation if you need more information, but as ever, the best way to learn is to start coding.




This work is licensed under a Creative Commons Attribution 3.0 Unported License
Creative Commons License.

Comments

Best part of it is that some of them provide you the quality of designer inspired Replica Purses and affordability of replica purses. Some even action cash-back offers. Manufacturing of these Louis Vuitton Handbags accoutrements takes abode in Far East. China has become a arch supplier in this regard. In fact, some of the Replica Handbags are so acceptable that even backpack experts cannot acquaint the difference. These manufacturers are acceptable at authoritative apery Replica Gucci Handbags. With Replica Rolex watches on your wrist, the babes themselves will access you. The Replica Watches you are abrasioning is by itself a ariseance account and it tells these women a lot about your afterwardstaste.
Posted @ Tuesday, December 31, 2013 2:32 AM by Replica Luxuries
Want to know how to cheat at poker, you should know the poker cheating device and cheat cards, then you will cheat at cards by using this device.
Posted @ Sunday, March 16, 2014 10:56 PM by Marked Cheating Cards
* Look at the iphone four instances perfectly right before buying them-do not simply make a invest in dependent on how they look rather seem for how very well they are able to increase the phone's functionality.* You need to ideally browse through the quite a few on line websites advertising iphone 4 circumstances. Have a look at leather-based iphone conditions, silicon circumstances together with other iphone equipment prior to making the remaining choice.When you may have chosen the suitable a single, you may proudly screen your cellular phone with eye-catching mobile phone handles. If you want an stylish or classy searching iphone situation, you'll want to opt for that leather apple iphone conditions. These are a huge hit in the industry simply because of their model quotient and their ability to protect these sensitive devices from any sort of damage. 
 
iPhone 5 Cases 
Chanel iPhone 5s Cases 
prada iPhone 5 Cases
Posted @ Tuesday, May 06, 2014 11:30 PM by iphone case
Post Comment
Name
 *
Email
 *
Website (optional)
Comment
 *

Allowed tags: <a> link, <b> bold, <i> italics