0

I'm trying to build a simple test. I'm having trouble submitting webforms. With help form a previous question I've cobbled together these functions within the larger class.

They completely work in the following test.php script run on the command line via drush scr test.php

$data = array(
  1 => array('1'),
  2 => array('2'),
  3 => array('3')
);

$T = new MyTest();
$T->insertMockData($data);

However, when I try to run as `drush test-run MyTest things fail completely.

Source snippet:

  function setUp($modules = array()) {
        $modules[] = 'webform';
        parent::setUp($modules);

        $this->insertMockData($this->randomData());
    }
function insertMockData($data = array(), $submitted_datetime = REQUEST_TIME) {

        $node_web = node_load(1);
        $submission = (object) array(
        'nid' => $node_web->nid,
        //'uid' => $user->uid,
        'submitted' => $submitted_datetime,
        'remote_addr' => ip_address(),
        'is_draft' => FALSE,
        'data' => $data,
            'serial' => $this->serial_value++,
        );
        module_load_include('inc', 'webform', 'includes/webform.submissions');
        webform_submission_insert($node_web, $submission);
            //webform_submission_send_mail($node_web, $submission);
          }

    function randomData() {
    $random_line_of_text  = array(
      "Mary had a little lamb",
      "a little lamb",
      "With fleece as white as snow",
      "And everywhere that Mary went",
      "That lamb was sure to go");

    return array(
      1 => array($random_line_of_text[array_rand($random_line_of_text)]),
      2 => array($random_line_of_text[array_rand($random_line_of_text)]),
      3 => array($random_line_of_text[array_rand($random_line_of_text)]),
    );
}

Errors on console

Test MyTest->insertMockData() failed: Trying to get property of non-object                       [error] Test webform_webform_submission_presave() failed: Trying to get property of non-object             [error] 
Test webform_webform_submission_presave() failed: Invalid argument supplied for foreach()          [error] Test webform_submission_insert() failed: Trying to get property of non-object                      [error] 
Test webform_submission_insert() failed: Trying to get property of non-object                      [error] Test webform_submission_insert() failed: Trying to get property of non-object                      [error] 
Test webform_submission_insert() failed: Trying to get property of non-object                      [error] Test webform_submission_send_mail() failed: Trying to get property of non-object                   [error] 
Test webform_submission_send_mail() failed: Invalid argument supplied for foreach()                [error] Test MyTest->insertMockData() failed: Trying to get property of non-object                       [error] 

Question: How do I debug a the output of SimpleTest when I'm not sure where in the script the error occurred?

1

Good for you for writing tests!

The best friend I've had while doing Drupal development work is a little gal called xdebug with an IDE like PHPStorm. Xdebug allows you to set breakpoints, much like you can for JS in Chrome dev tools, and stop the PHP script at that moment. You get access to all the variables and a stack trace among other things.

I'm no expert on xdebug or debugging, but getting PHPStorm and installing xdebug has saved me so much time and pain, I wouldn't go a day more without it.

Once you have xdebug handy, start setting breakpoints early on where you would think the issue is. For your example, I can tell $this->insertMockData($this->randomData()); was called since it is in the error messages. Set a breakpoint before that and you can see what $this is and why that object method isn't available.

If you don't want to pay for PHPStorm (which is so worth it!), Netbeans is free.

A simple var_dump($this); die(); should also print the $this variable to the screen for you to see what it is at that point, but you might as well upgrade to an IDE and xdebug. You're gonna need it for Drupal 8 anyway :)

  • Perhaps you're correct. I am a day away from giving up on SimpleTest. What I need words in the context of drush scr. Would it be poor form to write a flat PHP file to run and test from drush? This module isn't even mine. It's a sandbox project that I want to use but they need tests before it can be promoted to a real project. – Rick Mar 4 '15 at 15:51
  • You should still be able to debug the way I said while using drush scr. Any PHP activity on your server should still be stopped by breakpoints you set. I was only answering the debugging part. Unfortunately, I don't have a lot of experience with SimpleTest and have only contributed a patch or two to a couple modules. I would think it would be poor form to do what you are suggesting. I see all .test extensions in this tutorial – Alex Finnarn Mar 5 '15 at 0:43
  • SimpleTest doesn't put line numbers into its command line output, which makes life harder. But using the interactive debugger will help. You might also add assertNotNull or similar into your "insertMocks" routine, since it sounds like node 1 does not exist. Which makes sense: SimpleTest isn't looking into your regular database. You didn't create it in your script, so I'd guess it just doesn't exist. – Torenware Networks Oct 19 '15 at 0:19
2

Part of why your test is failing is pretty easy to see. Your code is relying on node 1 existing:

function insertMockData($data = array(), $submitted_datetime = REQUEST_TIME) {

        $node_web = node_load(1);
        $submission = (object) array(
        'nid' => $node_web->nid,
        //'uid' => $user->uid,
        'submitted' => $submitted_datetime,
        'remote_addr' => ip_address(),
        'is_draft' => FALSE,
        'data' => $data,
            'serial' => $this->serial_value++,
        );
  //lots of stuff omitted here...
}

The code assumes that there's a node in your DB for you to load. Sadly, no :-)

When SimpleTest runs, it creates a whole empty DB that's just installed. If you need a node, you have to create one, like this:

$settings = [
  'title' => 'My Test Content',
  'body'  => 'and what a body it is',
  'status' => 1,
  'type' => 'article',
];

$test_node = $this->drupalCreateNode($settings);
$this->assertNotNull($test_node, "Make sure our settings work");

See core/modules/simpletest/src/WebTestBase.php for some of the methods you can use to create nodes and users and other useful test data. But in general: your test or the test's superclasses need to create everything you need either in setUp() or in your test itself.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.