2

In our Behat tests we delete all test users in a before-hook. But sometimes our Behat test throws an error like:

Could not find a user account with the name vN8eLbrd!

Could not find a user account with the name some.wiredstuff-registration-test_10706!

Strange thing is that I get this user name direct from database. So I do not understand why this drush ucan command can not find it.

/** @beforeScenario */
  public function before($event) {
    $this->getSession()->getDriver()->resizeWindow(1280, 1024);

    // List all Scenarios which create the testuser.
    $scenarios = array(
      'Register for testing with Credit-Card',
      'Register for testing with Paypal',
      'Register for testing with valid Direct-Debit',
      'Register for testing with invalid Direct-Debit',
      'Access my subscriptions page',
      'Register for testing',
      'Register and use link from registration mail',
      'Logout',
      'Log in with username and password',
      'Recover your password'
    );

    $users_to_clean = array(
      '[email protected]',
      '[email protected]',
      '[email protected]'
    );

    $title = $event->getScenario()->getTitle();

    // Delete Testuser before the Scenario.
    if (in_array($title, $scenarios)) {
      foreach ($users_to_clean as $mail) {
        $user = user_load_by_mail($mail);
        if ($user) {
          shell_exec('drush ucan ' . $user->name . ' -y');
        }
      }
    }
  }

Problem with not deleted users is that other tests fail because a test user already exists.

Do you have a clue why this happens?

2
  • Are you sure the users exist? Can you check the order the tests are run? Oct 15, 2015 at 12:16
  • In this line $user = user_load_by_mail($mail); I get the user with user_load_by_mail() - so I am pretty sure that the user exists. Otherwise if would be false and do not run shell_exec.
    – Jurik
    Oct 15, 2015 at 12:46

1 Answer 1

3

While debugging with xdebug in PhpStorm I figured out that user_load_by_mail($mail) loads cached users. user_load_by_mail() uses this function:

/**
 * Load multiple users based on certain conditions.
 *
 * This function should be used whenever you need to load more than one user
 * from the database. Users are loaded into memory and will not require
 * database access if loaded again during the same page request.
 *
 * @param $uids
 *   An array of user IDs.
 * @param $conditions
 *   (deprecated) An associative array of conditions on the {users}
 *   table, where the keys are the database fields and the values are the
 *   values those fields must have. Instead, it is preferable to use
 *   EntityFieldQuery to retrieve a list of entity IDs loadable by
 *   this function.
 * @param $reset
 *   A boolean indicating that the internal cache should be reset. Use this if
 *   loading a user object which has been altered during the page request.
 *
 * @return
 *   An array of user objects, indexed by uid.
 *
 * @see entity_load()
 * @see user_load()
 * @see user_load_by_mail()
 * @see user_load_by_name()
 * @see EntityFieldQuery
 *
 * @todo Remove $conditions in Drupal 8.
 */
function user_load_multiple($uids = array(), $conditions = array(), $reset = FALSE) {
  return entity_load('user', $uids, $conditions, $reset);
}

But it calls this function without $reset == true. That's why it uses cached user objects and tries to delete an already deleted user.

I fixed this lines with:

// Delete Testuser before the Scenario.
    if (in_array($title, $scenarios)) {
      foreach ($users_to_clean as $mail) {
        $users = user_load_multiple(array(), array('mail' => $mail), true);
        $user = reset($users);
        if ($user) {
          shell_exec('drush ucan ' . $user->name . ' -y');
        }
      }
    }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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