Mock data for testing/Interface Definition

We encourage users to post events happening in the community to the community events group on https://www.drupal.org.
cabbiepete's picture

So I am writing a new CCK field and because I practice test driven development I find myself testing that I have implemented the CCK api hooks correctly. This basically means testing against the interface. Usually in a pure OO class orientated world for unit testing we would use a mock library (e.g. Simpletest's Mock) to make a mockup object based on reflection of an interface or abstract object but because drupal doesn't define interfaces in this way (for good reasons from what I can tell) we need another mechanism.

A real example is testing an implementation of hooks such as

hook_widget($op, &$node, $field, &$items)

Now as it turns out its pretty basic data. $op is a string and the rest are arrays. But the arrays are actually nested arrays that in real life are often driven off database tables including foreign keys and the like as further nested arrays. Take $field for example.

I got the output below from a live debugging session by printing $field inside my hook implementation using devel module's dpr function:

Array
(
    [field_name] => field_itm_test_phone
    [type] => itmphone
    [required] => 1
    [multiple] => 0
    [db_storage] => 1
    [max_length] => 
    [error_msg] => "%value" not valid for %label. You are only allowed plus, numbers and spaces and the phone number must be at least 5 characters long e.g. +44 3422342 234234
    [regex] => 
    [widget] => Array
        (
            [default_value] => Array
                (
                    [0] => Array
                        (
                            [value] => 
                        )

                )

            [default_value_php] => 
            [error_msg] => "%value" not valid for %label. You are only allowed plus, numbers and spaces and the phone number must be at least 5 characters long e.g. +44 3422342 234234
            [type] => itmphone
            [weight] => 0
            [label] => itm_test_phone
            [description] => asdfadf
        )

    [type_name] => form_test
    [display_settings] => Array
        (
            [label] => Array
                (
                    [format] => above
                )

            [teaser] => Array
                (
                    [format] => default
                )

            [full] => Array
                (
                    [format] => default
                )

        )

)

So as you can see this is a reasonably complicated structure and hand coding mockup data for this value gets tedious. Obviously I could get drupal to spit this out just like I have here and then paste it into my code (with minor changes) but 1. that wouldn't really allow for test driven development as I need a working implementation before I can write the test code and 2. it seems to me that having some way to better define the interface (via say utility functions to generate this type of mock data) would be very useful. e.g. I could use it on testing other cck fields I implement OR for helping to write tests for CCK itself.

Another obvious example that is bigger than CCK is $node and mock data for that this reference to a node seems pretty common from the code I have seen so far.

I don't know if an effort has started on this or something similar to solve the same problem let me know if it has.

I am also asking whether anyone else agrees/disagrees or has a different opinion about this and welcome all comments.

Comments

Helper Library

cabbiepete's picture

So it seems I am on my own.

There are some plans for some similar stuff in the testing plans (I forget where but I read it the other day) and Angie Byron mentions the need for node creation helpers for DrupalTestCase in her excellent article A Drupal Module Developer's Guide to SimpleTest.

This sounds like a good approach so I am going to start writing a ITMDrupalTestCase that extends DrupalTestCase and can be used as an extension of custom TestCases. ITM because I work for Informa Telecoms and Media currently.

First version of ITMDrupalTestCase pasted below, currently has two protected variables which you override in your custom test. Using these overridden values the test function checks the module implements the hook functions.

It just checks the hook is implemented as a function not that its parameters are correctly defined or the return values come out correctly.

<?php
/<strong>
*
Helper class for testing drupal modules.
*
*
Usage
*
*   class
MyTestCase extends ITMDrupalTestCase
*/
class
ITMDrupalTestCase extends DrupalTestCase {

  protected
$module_name = '';
  protected
$hooks = array();

  function
get_info() {
    return array(
     
'name' => t('helper test case'),
     
'desc' => t('A helper test case.'),
     
'group' => t('ITM Test'),
    );
  }

  /</
strong>
   *
Test cck hooks are implemented.
   *
   *
Usage
  
*
   * 
Re-declare $module_name and $hooks in your test case to test a module
  
*  implements those hooks as functions.
   * 
   */
  function
test_hook_impl() {
   
$module_name = $this->module_name;
   
$hooks = $this->hooks;

    if (
$module_name and $hooks) {
      foreach (
$hooks as $hook) {
       
$function_exists = 0;
       
$function_name = $module_name. '_' .$hook;
       
$function_exists = function_exists($function_name);
       
$this->assertTrue($function_exists, 'Expected hook ' .$hook);
      }
    }
  }
}
?>

We have node creation helper

Rok Žlender's picture

We have node creation helper function in queue atm and its not far away from being committed to simpletest. http://drupal.org/node/203825

Excellent will apply that

cabbiepete's picture

Excellent will apply that patch. Are there plans for any others, or should I just post issues in the queue?

Also when I make a helper function to help test CCK field modules any ideas where best for that, in the simpletest or in another module?