Expecting exception in Behat

Expecting exception in Behat

by Tim V. -
Number of replies: 5
Hi, I'm writing Behat tests for our plugins. Everything works very well but I'm having some trouble testing behaviours  where I expect to see an exception. The problem is that the "look_for_exceptions()" function is called after each step and if an exception occurs, the step fails. But in my case I expect to see an exception. This behaviour has been already discussed last year: https://moodle.org/mod/forum/discuss.php?d=392187

Unfortunately there was no solution atm. Only Andrew Nicols suggested a possible solution but it doesn't work because the step before the "I should see exception"-step fails. So, when I navigate to the page, the navigation step already fails because an exception has been detected.

Sorry for my ignorance, but are there any updates about this "problem"? Anyone can suggest a solution? The idea of automatically calling "look_for_exceptions" is awesome but the result is that I cannot completely test the options of our plugins where I expect an exception.

So any suggestions are extremly welcome 🙂
Average of ratings: -
In reply to Tim V.

Re: Expecting exception in Behat

by Mark Johnson -
Picture of Core developers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

Hi Tim, I dont know the exact behaviour you're trying to test, so this may not be useful.

However, when it comes to behat, you should be testing the behaviour you're expecting your users to experience. In the event of an error, would it not be better to catch the exception and display a meaningful error message to the user (which you can then test for), rather than showing them an uncaught exception?

In reply to Tim V.

Re: Expecting exception in Behat

by Renaat Debleu -
Picture of Core developers Picture of Particularly helpful Moodlers Picture of Plugin developers

You can also test the options of your plugins using PHPUnit

1. where you expect an exception:

$this->expectException(\moodle_exception::class);
$this->expectExceptionMessage('Course or activity not accessible. (Not enrolled)');
function_that_throws_an_exception($course, $user, $module);

2. or providing wrong parameters:

$this->expectException(\moodle_exception::class);
$this->expectExceptionMessage('Invalid number of parameters');
function_that_throws_an_exception($course, null);

3....

 

In reply to Renaat Debleu

Re: Expecting exception in Behat

by Tim V. -
Thank you in advance, but unfortunately I've to test a local plugin. It has a view.php and inside the view.php there's a check like that (pseudo code):

$id = require_param('id');

if ($data = $DB->get_record($id)) {
   // do something
} else {
  // throw moodle_exception()
}

So it's no encapsulated by a function...
In reply to Tim V.

Re: Expecting exception in Behat

by Renaat Debleu -
Picture of Core developers Picture of Particularly helpful Moodlers Picture of Plugin developers

Perhaps it will not pass a review of nice code, but it is possible to test code that is not encapsulated by a function:


    global $CFG, $PAGE;
    $course = $this->getDataGenerator()->create_course();
    $this->setAdminUser();
    $PAGE->get_renderer('core', 'course');
    $_POST['id'] = 89;
    ob_start();
    include_once($CFG->dirroot . '/local/plugin/view.php');
    ob_end_clean();

In reply to Tim V.

Re: Expecting exception in Behat

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers
Well, you can always re-factor, and move into a function which can be unit tested.

However, in this case, I wouldn't. As Martin Fowler would say (I think that is the right attribution) there is only point writing test to catch mistakes you will actually make. Here, having a Behat test to catch the happy path is probably all you need, and probably all your Behat tests will cover that.