Community Documentation

Miscellaneous Simpletest Tips

Last updated November 9, 2010. Created by Wim Leers on August 30, 2005.
Edited by jhodgdon, sun, aj045, ksenzee. Log in to edit this page.

This is a list of some general tips for writing tests, feel free to pitch in and add your own!

Posting to a multiple select field

To select multiple options of a select field (e.g. testing taxonomy terms), in which case:

<div class="form-item">
  <label for="edit-parent">Parent term:</label>
  <select name="parent[]" multiple="multiple" size="3" id="edit-parent">
    <option value="806" selected="selected">one</option>
    <option value="807">two</option>
    <option value="808">three</option>
  </select>
</div>

we need to post an array for #name:
<?php
  $edit
= array(
   
'parent[]' => array('807', '808'),
  );
 
$this->drupalPost('taxonomy/term/123/edit', $edit, t('Save'));
?>

Testing the Uploading Functionality

In the new version of Simpletest, there is an uploading feature. The example below best illustrates this. You MUST first create the full path to the file and then pass it into the $edit parameter of the drupalPost() method. In the example (and in your tests), the path is relative to the root Drupal installation directory. The realpath() function resolves all symbolic links and references within a path string (more documentation here).

<?php
$rpath
= realpath('sites/all/modules/my_module/test-file.pdf');
$this->drupalPost('form/upload', array('name-of-file-field-here' => $rpath), t('Upload file'));
?>

Notice that the $edit parameter is a key-value array. Specifically for file upload testing, you'll want to replace the key "name-of-file-field-here" with the name of the file field as it appears in the final HTML output of a form. So if you've produced a form with a file field named "file_drop_point" as in this example...

<?php
$form
['file_drop_point'] = array(
'#type' => 'file',
'#title' => t('Upload a file'),
);
?>

... your subsequent test that tests this file field's uploading capability will actually look something like this:

<?php
$rpath
= realpath('sites/all/modules/my_module/test-file.pdf');
$this->drupalPost('form/upload', array('files[file_drop_point]' => $rpath), t('Upload file'));
// There are no quotes around "file_drop_point" in the key, by the way.  It's valid the way it looks.
?>

Why? Go to the page where the form is, then look at the HTML code for the file upload field. It will resemble this:

<input ... name="files[file_drop_point]" ... />

Your tests should now run properly, though be sure to check mark "Provide verbose information when running tests" in the test settings (Administer > Site Building > Testing > Settings tab). Verbose output will provide snapshots of the pages that the Drupal browser was seeing as the test ran.

Viewing Source during a Browser Test

Use $this->drupalGetContent() to output the source that the simpletest browser is receiving. This is useful for debugging during development.

Triggering your debugger (xdebug client) from a Browser Test

It can be quite hard to debug errors in tests, even if you have xdebug set up, because the drupalGet() and drupalPost() calls in your tests go through cURL, rather than through your browser, so they don't have the session variables, get parameters, or cookies set right so that they will be sent to xdebug.

There are a couple of ways to fix this.

  1. Use http://pollinimini.net/blog/xdebug-bookmarklet/ to set up your browser so that the cookies will trigger xdebug from simpletest. You can also try the "easy Xdebug" or "xdebug helper" plugins for Firefox and Chrome, which will set a cookie to make it so these requests automatically get sent to xdebug -- the cookie doesn't apply to drupalGet/drupalPost, however (see below).
  2. Edit the drupalGet() and drupalPost() methods in DrupalWebTestCase so that they have an
    array('query' => 'XDEBUG_SESSION_START=mw')  // D6
    array('query' => array('XDEBUG_SESSION_START' => 'mw')) // D7

    added to their $options parameter.
    Substitute your own IDE key for mw. If you already know how to trigger debugging in your browser from your IDE, you can find the IDE key by looking at the URL that your IDE generates for debugging. Here's a code snippet for Drupal 7:
    if (!isset($options['query'])) {
      $options['query'] = array();
    }
    $options['query'] += array('XDEBUG_SESSION_START' => 'ECLIPSE_DPGP');

    This is if you are using the Eclipse IDE; again, substitute the correct IDE key if you are using something else.
  3. Another alternative is to setup a VirtualHost on your Apache with the following xdebug related lines. This causes all pages on this domain to trigger the debugger. Just use this domain when you want to debug and use a different domain when you are browsing or developing bug free :).

    More xdebug remote debugging params should be set in your php.ini or in this VirtualHost.

      #customize this path to point to your Xdebug extension
      zend_extension=/Applications/Komodo IDE.app/Contents/SharedSupport/php/debugging/5.2/xdebug.so
       #customize this to match how you setup your xdebug client
      xdebug.idekey=mw
      xdebug.default_enable=1
      xdebug.remote_handler=dbgp
      php_admin_value xdebug.remote_enable 1
      #the following line triggers the xdebug client automatically for every request. useful for simpletest.
      php_admin_value xdebug.remote_autostart 1

Other notes:

  • Make sure your IDE options are set up correctly so they will prompt you to accept remote debugging requests. Otherwise, even with the steps above, your request won't open up for debugging in your IDE.

Comments

Debugging tests

I am finding that debugging (using xdebug+vim) is a lot easier when running the tests from the command line.
The process I use is:

  • start vi and hit <f5>
  • within five seconds, start run_tests.sh
  • start another vi session and hit <f5>
  • within five seconds go to the first vi session, and hit <f5> (continue)
  • go back to the second vi session and debug away...

(yes, that's the simplest I found - improvements to this process will be welcomed happily)

--yuval

Call Drupal post having the get variables?

I have written a test file that contains the get variable in the URL, i.e., having an email variable in the url like register?email=value. After calling this a page will be displayed with the fields to capture the user personal information. I have created a array type with the form fields value and passed the array in the drupalPost method. When I tried to test the case in the drupal I was returned with error that the "Failed to set field to " (all the field names I set in the array and the values) in the test case result. when I tried to call the url in the browser (replacing the %3F and %3d as mentioned below), the page is displayed correctly with the form fields. But when I called the url with the URL that is printed in the test result(http://localhost/projects/drupal/register%3Femail%3DczEzMzg2OTJ5aHhlaTEx...) a error page with Access Forbidden Error 403 is displayed. I am unable to find the problem here. Please note that when the email variable in the url is not read correctly then the form fields will not be displayed, so I have a doubt that the email variable is not read correctly when I am using the drupalPost method with the get variable. Also the URL is changed by replacing the "?" with "%3F" and "=" with "%3D". does this make any difference.

Any help.

Thanks in advance,
Sateesh B.