Jul 30, 2014

Automated testing a jQuery / Ajax call

While converting some tests to class WebTestBase in Drupal 8, I came across an attempt to test a jQuery call for which the response was an object encoded in JSON.

Here is the solution I came up with for automated checking of this functionality. It does not use the jQuery code itself but mimics such a call to the server.

(1)  The normal jQuery / Ajax code that sets up the call.

var params = "target_oid=" + 7 + "&target_enable=" + 1;

  'url': drupalSettings.path.basePath + 'ajax/optimizely',
  'type': 'POST',
  'dataType': 'json',
  'data': params,
  'success': function(data) {
    // Check data.status, update the DOM, ...
  // Other properties ...

(2)  The server-side code that responds.

  $target_oid = $_POST['target_oid'];
  $target_enable = $_POST['target_enable'];

  // Process the request ...

  $options = array('status' => 'Updated', 'message' => 'Good job');
  return new JsonResponse($options);

(3)  The code in a WebTestBase test method to mimic the call and check the results.

class OptimizelyDefaultProjectTest extends WebTestBase {

  public function testListingAjax() {

    $params = array('target_oid' => 7, 'target_enable' => 1);
    $response = $this->drupalPost('ajax/optimizely',


    $resp_obj = json_decode($response);

    $this->assertEqual($resp_obj->status, 'Updated', ...);
    $this->assertEqual($resp_obj->message, 'Good job', ...);


N.B. WebTestBase::drupalPost() in Drupal 8 is not the same as DrupalWebTestCase::drupalPost() in Drupal 7.

An approach with better coverage would be to load the form and simulate the user action that triggers the Ajax call, which, in this case, is clicking on a checkbox.  That would test not only the server code but also the jQuery code on the client.

But I will save that problem for another day. 8-D

Update: see  http://optimizely-to-drupal-8.blogspot.com/2015/01/beta-4-drupalmatchpath-and.html


protected function WebTestBase::drupalPost


No comments:

Post a Comment