Skip to end of metadata
Go to start of metadata

Writing a test for CiviCRM usually consists of four steps:

  1. Familiarising yourself with test standards & the helper functions you should use
  2. Figuring out a test case scenario
  3. Preparing test data set
  4. Writing the test

Familiarising yourself with test standards & the helper functions you should use

  • All unit test classes should be marked as eNoticeCompliant (which will enforce this compliance when running the test. There are some that have not reached compliance yet but no test class should be allowed to regress.
  • When interacting with API functions within the unit test suite you should (almost) always call them via either
    • $this->callAPISuccess($entity, $action, $params, $checkAgainst);
    • $this->callAPIFailure($entity, $action, $params, $errorMessage);
    • $this->callAPIAndDocument($entity, $action, $params, $function, $file, $description, $subfile, $actionName);
    These 3 functions do the following
    • ensure version is set
    • checks / asserts the outcome is a success or failure (callAPIAndDocument checks for success too)
    • results in a failed test with good debugging output if the correct outcome doesn't result
    • optionally checks the output against an error message you pass in (Failure) or a result value you pass in for success - so far implemented for getcount, getvalue, getsingle
    • creates a test generated example if you call callAPAndDocument
  • When you see the following strings in a test it probably means the code needs to be tidied up to use the above functions & should be seen as a 'bad code smell'
    • 'version'
    • civicrm_api
    • 'error_message'
    • 'assertAPISuccess
    • assertAPIFailure
    • 'is_error'
    • __LINE__  (this is an exception to the above - adding 'in line'  . __LINE__ used to be helpful for debugging but is obsolete in that regards now

Figuring out a test case scenario

First step is making a decision about what should be tested.

When writing API tests you are encouraged to

  • focus on success tests (check the api succeeds) rather than failure tests. For example, there are a number of tests that check that passing in a string as params will result in an error. This api wrapper level functionality is tested in the SyntaxConformance tests & doesn't need to be duplicated elsewhere.
  • test the whole wrapper - don't test component functions directly unless you are specifically testing api-wrapper functionality. In which case you should be working in one of the classes like UtilsTest, SyntaxConformanceTest, APITest that is focussed on testing the wrapper


Preparing test data set

You should take a look at similar tests to see how they have prepared the data. Most API tests use api calls / functions on the test class to set up the data set. There are probably differing opinions on which is more transparent/ maintainable.

Example of setting up test data using API

protected function setUp() {
     $this->contactId = $this->individualCreate();
$caseTypes = $this->callAPISuccess('option_value', 'Create', array(
        'option_group_id' => $this->caseTypeGroup,,
'name' => 'housing_support',
        'label' => "Housing Support",
'sequential' => 1,
'description' => 'Help homeless individuals obtain temporary and long-term housing',

        //case is abnormal in that we are using the 'value' rather than the 'id as the id

    $this->caseTypeId = $caseTypes['values'][0]['value'];    
$this->optionValues[] = $caseTypes['id'];

Example of cleaning up above data in tear down

protected function tearDown() {

    foreach ($this->optionValues as $id) {

      $this->callAPISuccess('option_value', 'delete', array('id' => $id));


    $tablesToTruncate = array(


    $this->quickCleanup($tablesToTruncate, TRUE);




Example of Flat XML data set

Example of XML data set

For more information about Database testing, refer to phpUnit documentation.

Writing the test

Start off with creating a class, like in below example.


  • None
  1. Feb 05, 2015

    I've posted a related forum thread to talk about techniques for managing test data –,35627.0.html . v4.6 includes a new technique which can cleanup test data in a pretty automatic + performant way (SQL transactions), but... as always... there are trade-offs.

Creative Commons License
Except where otherwise noted, content on this site is licensed under a Creative Commons Attribution-Share Alike 3.0 United States Licence.