[ Index ]

PHP Cross Reference of moodle-2.8

title

Body

[close]

/question/behaviour/interactive/tests/ -> walkthrough_test.php (source)

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * This file contains tests that walks a question through the interactive
  19   * behaviour.
  20   *
  21   * @package    qbehaviour
  22   * @subpackage interactive
  23   * @copyright  2009 The Open University
  24   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  25   */
  26  
  27  
  28  defined('MOODLE_INTERNAL') || die();
  29  
  30  global $CFG;
  31  require_once(dirname(__FILE__) . '/../../../engine/lib.php');
  32  require_once(dirname(__FILE__) . '/../../../engine/tests/helpers.php');
  33  
  34  
  35  /**
  36   * Unit tests for the interactive behaviour.
  37   *
  38   * @copyright  2009 The Open University
  39   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  40   */
  41  class qbehaviour_interactive_walkthrough_test extends qbehaviour_walkthrough_test_base {
  42  
  43      public function test_interactive_feedback_multichoice_right() {
  44  
  45          // Create a multichoice single question.
  46          $mc = test_question_maker::make_a_multichoice_single_question();
  47          $mc->hints = array(
  48              new question_hint_with_parts(0, 'This is the first hint.', FORMAT_HTML, false, false),
  49              new question_hint_with_parts(0, 'This is the second hint.', FORMAT_HTML, true, true),
  50          );
  51          $this->start_attempt_at_question($mc, 'interactive');
  52  
  53          $rightindex = $this->get_mc_right_answer_index($mc);
  54          $wrongindex = ($rightindex + 1) % 3;
  55  
  56          // Check the initial state.
  57          $this->check_current_state(question_state::$todo);
  58          $this->check_current_mark(null);
  59          $this->check_current_output(
  60                  $this->get_contains_marked_out_of_summary(),
  61                  $this->get_contains_question_text_expectation($mc),
  62                  $this->get_contains_mc_radio_expectation(0, true, false),
  63                  $this->get_contains_mc_radio_expectation(1, true, false),
  64                  $this->get_contains_mc_radio_expectation(2, true, false),
  65                  $this->get_contains_submit_button_expectation(true),
  66                  $this->get_does_not_contain_feedback_expectation(),
  67                  $this->get_tries_remaining_expectation(3),
  68                  $this->get_no_hint_visible_expectation());
  69  
  70          // Save the wrong answer.
  71          $this->process_submission(array('answer' => $wrongindex));
  72  
  73          // Verify.
  74          $this->check_current_state(question_state::$todo);
  75          $this->check_current_mark(null);
  76          $this->check_current_output(
  77                  $this->get_contains_marked_out_of_summary(),
  78                  $this->get_contains_mc_radio_expectation($wrongindex, true, true),
  79                  $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, true, false),
  80                  $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, true, false),
  81                  $this->get_contains_submit_button_expectation(true),
  82                  $this->get_does_not_contain_correctness_expectation(),
  83                  $this->get_does_not_contain_feedback_expectation(),
  84                  $this->get_tries_remaining_expectation(3),
  85                  $this->get_no_hint_visible_expectation());
  86  
  87          // Submit the wrong answer.
  88          $this->process_submission(array('answer' => $wrongindex, '-submit' => 1));
  89  
  90          // Verify.
  91          $this->check_current_state(question_state::$todo);
  92          $this->check_current_mark(null);
  93          $this->check_current_output(
  94                  $this->get_contains_marked_out_of_summary(),
  95                  $this->get_contains_mc_radio_expectation($wrongindex, false, true),
  96                  $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, false, false),
  97                  $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, false, false),
  98                  $this->get_contains_submit_button_expectation(false),
  99                  $this->get_contains_try_again_button_expectation(true),
 100                  $this->get_does_not_contain_correctness_expectation(),
 101                  new question_pattern_expectation('/' .
 102                          preg_quote(get_string('notcomplete', 'qbehaviour_interactive'), '/') . '/'),
 103                  $this->get_contains_hint_expectation('This is the first hint'));
 104  
 105          // Check that, if we review in this state, the try again button is disabled.
 106          $displayoptions = new question_display_options();
 107          $displayoptions->readonly = true;
 108          $html = $this->quba->render_question($this->slot, $displayoptions);
 109          $this->assert($this->get_contains_try_again_button_expectation(false), $html);
 110  
 111          // Do try again.
 112          $this->process_submission(array('-tryagain' => 1));
 113  
 114          // Verify.
 115          $this->check_current_state(question_state::$todo);
 116          $this->check_current_mark(null);
 117          $this->check_current_output(
 118                  $this->get_contains_marked_out_of_summary(),
 119                  $this->get_contains_mc_radio_expectation($wrongindex, true, true),
 120                  $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, true, false),
 121                  $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, true, false),
 122                  $this->get_contains_submit_button_expectation(true),
 123                  $this->get_does_not_contain_correctness_expectation(),
 124                  $this->get_does_not_contain_feedback_expectation(),
 125                  $this->get_tries_remaining_expectation(2),
 126                  $this->get_no_hint_visible_expectation());
 127  
 128          // Submit the right answer.
 129          $this->process_submission(array('answer' => $rightindex, '-submit' => 1));
 130  
 131          // Verify.
 132          $this->check_current_state(question_state::$gradedright);
 133          $this->check_current_mark(0.6666667);
 134          $this->check_current_output(
 135                  $this->get_contains_mark_summary(0.6666667),
 136                  $this->get_contains_mc_radio_expectation($rightindex, false, true),
 137                  $this->get_contains_mc_radio_expectation(($rightindex + 1) % 3, false, false),
 138                  $this->get_contains_mc_radio_expectation(($rightindex + 1) % 3, false, false),
 139                  $this->get_contains_submit_button_expectation(false),
 140                  $this->get_contains_correct_expectation(),
 141                  $this->get_no_hint_visible_expectation());
 142  
 143          // Finish the attempt - should not need to add a new state.
 144          $numsteps = $this->get_step_count();
 145          $this->quba->finish_all_questions();
 146  
 147          // Verify.
 148          $this->assertEquals($numsteps, $this->get_step_count());
 149          $this->check_current_state(question_state::$gradedright);
 150          $this->check_current_mark(0.6666667);
 151          $this->check_current_output(
 152                  $this->get_contains_mark_summary(0.6666667),
 153                  $this->get_contains_mc_radio_expectation($rightindex, false, true),
 154                  $this->get_contains_mc_radio_expectation(($rightindex + 1) % 3, false, false),
 155                  $this->get_contains_mc_radio_expectation(($rightindex + 1) % 3, false, false),
 156                  $this->get_contains_correct_expectation(),
 157                  $this->get_no_hint_visible_expectation());
 158  
 159          // Process a manual comment.
 160          $this->manual_grade('Not good enough!', 0.5, FORMAT_HTML);
 161  
 162          // Verify.
 163          $this->check_current_state(question_state::$mangrpartial);
 164          $this->check_current_mark(0.5);
 165          $this->check_current_output(
 166                  $this->get_contains_mark_summary(0.5),
 167                  $this->get_contains_partcorrect_expectation(),
 168                  new question_pattern_expectation('/' . preg_quote('Not good enough!', '/') . '/'));
 169  
 170          // Check regrading does not mess anything up.
 171          $this->quba->regrade_all_questions();
 172  
 173          // Verify.
 174          $this->check_current_state(question_state::$mangrpartial);
 175          $this->check_current_mark(0.5);
 176          $this->check_current_output(
 177                  $this->get_contains_mark_summary(0.5),
 178                  $this->get_contains_partcorrect_expectation());
 179  
 180          $autogradedstep = $this->get_step($this->get_step_count() - 2);
 181          $this->assertEquals($autogradedstep->get_fraction(), 0.6666667, '', 0.0000001);
 182      }
 183  
 184      public function test_interactive_finish_when_try_again_showing() {
 185  
 186          // Create a multichoice single question.
 187          $mc = test_question_maker::make_a_multichoice_single_question();
 188          $mc->hints = array(
 189              new question_hint_with_parts(0, 'This is the first hint.', FORMAT_HTML, false, false),
 190          );
 191          $this->start_attempt_at_question($mc, 'interactive');
 192  
 193          $rightindex = $this->get_mc_right_answer_index($mc);
 194          $wrongindex = ($rightindex + 1) % 3;
 195  
 196          // Check the initial state.
 197          $this->check_current_state(question_state::$todo);
 198          $this->check_current_mark(null);
 199          $this->check_current_output(
 200                  $this->get_contains_marked_out_of_summary(),
 201                  $this->get_contains_question_text_expectation($mc),
 202                  $this->get_contains_mc_radio_expectation(0, true, false),
 203                  $this->get_contains_mc_radio_expectation(1, true, false),
 204                  $this->get_contains_mc_radio_expectation(2, true, false),
 205                  $this->get_contains_submit_button_expectation(true),
 206                  $this->get_does_not_contain_feedback_expectation(),
 207                  $this->get_tries_remaining_expectation(2),
 208                  $this->get_no_hint_visible_expectation(),
 209                  new question_pattern_expectation('/' .
 210                          preg_quote(get_string('selectone', 'qtype_multichoice'), '/') . '/'));
 211  
 212          // Submit the wrong answer.
 213          $this->process_submission(array('answer' => $wrongindex, '-submit' => 1));
 214  
 215          // Verify.
 216          $this->check_current_state(question_state::$todo);
 217          $this->check_current_mark(null);
 218          $this->check_current_output(
 219                  $this->get_contains_marked_out_of_summary(),
 220                  $this->get_contains_mc_radio_expectation($wrongindex, false, true),
 221                  $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, false, false),
 222                  $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, false, false),
 223                  $this->get_contains_submit_button_expectation(false),
 224                  $this->get_contains_try_again_button_expectation(true),
 225                  $this->get_does_not_contain_correctness_expectation(),
 226                  new question_pattern_expectation('/' .
 227                          preg_quote(get_string('notcomplete', 'qbehaviour_interactive'), '/') . '/'),
 228                  $this->get_contains_hint_expectation('This is the first hint'));
 229  
 230          // Finish the attempt.
 231          $this->quba->finish_all_questions();
 232  
 233          // Verify.
 234          $this->check_current_state(question_state::$gradedwrong);
 235          $this->check_current_mark(0);
 236          $this->check_current_output(
 237                  $this->get_contains_mark_summary(0),
 238                  $this->get_contains_mc_radio_expectation($wrongindex, false, true),
 239                  $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, false, false),
 240                  $this->get_contains_mc_radio_expectation(($wrongindex + 1) % 3, false, false),
 241                  $this->get_contains_incorrect_expectation(),
 242                  $this->get_no_hint_visible_expectation());
 243      }
 244  
 245      public function test_interactive_shortanswer_try_to_submit_blank() {
 246  
 247          // Create a short answer question.
 248          $sa = test_question_maker::make_question('shortanswer');
 249          $sa->hints = array(
 250              new question_hint(0, 'This is the first hint.', FORMAT_HTML),
 251              new question_hint(0, 'This is the second hint.', FORMAT_HTML),
 252          );
 253          $this->start_attempt_at_question($sa, 'interactive');
 254  
 255          // Check the initial state.
 256          $this->check_current_state(question_state::$todo);
 257          $this->check_current_mark(null);
 258          $this->check_current_output(
 259                  $this->get_contains_marked_out_of_summary(),
 260                  $this->get_contains_submit_button_expectation(true),
 261                  $this->get_does_not_contain_feedback_expectation(),
 262                  $this->get_does_not_contain_validation_error_expectation(),
 263                  $this->get_does_not_contain_try_again_button_expectation(),
 264                  $this->get_no_hint_visible_expectation());
 265  
 266          // Submit blank.
 267          $this->process_submission(array('-submit' => 1, 'answer' => ''));
 268  
 269          // Verify.
 270          $this->check_current_state(question_state::$invalid);
 271          $this->check_current_mark(null);
 272          $this->check_current_output(
 273                  $this->get_contains_marked_out_of_summary(),
 274                  $this->get_contains_submit_button_expectation(true),
 275                  $this->get_does_not_contain_feedback_expectation(),
 276                  $this->get_contains_validation_error_expectation(),
 277                  $this->get_does_not_contain_try_again_button_expectation(),
 278                  $this->get_no_hint_visible_expectation());
 279  
 280          // Now get it wrong.
 281          $this->process_submission(array('-submit' => 1, 'answer' => 'newt'));
 282  
 283          // Verify.
 284          $this->check_current_state(question_state::$todo);
 285          $this->check_current_mark(null);
 286          $this->check_current_output(
 287                  $this->get_contains_marked_out_of_summary(),
 288                  $this->get_contains_submit_button_expectation(false),
 289                  $this->get_does_not_contain_validation_error_expectation(),
 290                  $this->get_contains_try_again_button_expectation(true),
 291                  new question_pattern_expectation('/' .
 292                          preg_quote(get_string('notcomplete', 'qbehaviour_interactive'), '/') . '/'),
 293                  $this->get_contains_hint_expectation('This is the first hint'));
 294          $this->assertEquals('newt',
 295                  $this->quba->get_response_summary($this->slot));
 296  
 297          // Try again.
 298          $this->process_submission(array('-tryagain' => 1));
 299  
 300          // Verify.
 301          $this->check_current_state(question_state::$todo);
 302          $this->check_current_mark(null);
 303          $this->check_current_output(
 304                  $this->get_contains_marked_out_of_summary(),
 305                  $this->get_contains_submit_button_expectation(true),
 306                  $this->get_does_not_contain_feedback_expectation(),
 307                  $this->get_does_not_contain_validation_error_expectation(),
 308                  $this->get_does_not_contain_try_again_button_expectation(),
 309                  $this->get_no_hint_visible_expectation());
 310  
 311          // Now submit blank again.
 312          $this->process_submission(array('-submit' => 1, 'answer' => ''));
 313  
 314          // Verify.
 315          $this->check_current_state(question_state::$invalid);
 316          $this->check_current_mark(null);
 317          $this->check_current_output(
 318                  $this->get_contains_marked_out_of_summary(),
 319                  $this->get_contains_submit_button_expectation(true),
 320                  $this->get_does_not_contain_feedback_expectation(),
 321                  $this->get_contains_validation_error_expectation(),
 322                  $this->get_does_not_contain_try_again_button_expectation(),
 323                  $this->get_no_hint_visible_expectation());
 324  
 325          // Now get it right.
 326          $this->process_submission(array('-submit' => 1, 'answer' => 'frog'));
 327  
 328          // Verify.
 329          $this->check_current_state(question_state::$gradedright);
 330          $this->check_current_mark(0.6666667);
 331          $this->check_current_output(
 332                  $this->get_contains_mark_summary(0.6666667),
 333                  $this->get_contains_submit_button_expectation(false),
 334                  $this->get_contains_correct_expectation(),
 335                  $this->get_does_not_contain_validation_error_expectation(),
 336                  $this->get_no_hint_visible_expectation());
 337          $this->assertEquals('frog',
 338                  $this->quba->get_response_summary($this->slot));
 339      }
 340  
 341      public function test_interactive_feedback_multichoice_multiple_reset() {
 342  
 343          // Create a multichoice multiple question.
 344          $mc = test_question_maker::make_a_multichoice_multi_question();
 345          $mc->hints = array(
 346              new question_hint_with_parts(0, 'This is the first hint.', FORMAT_HTML, true, true),
 347              new question_hint_with_parts(0, 'This is the second hint.', FORMAT_HTML, true, true),
 348          );
 349          $this->start_attempt_at_question($mc, 'interactive', 2);
 350  
 351          $right = array_keys($mc->get_correct_response());
 352          $wrong = array_diff(array('choice0', 'choice1', 'choice2', 'choice3'), $right);
 353          $wrong = array_values(array_diff(
 354                  array('choice0', 'choice1', 'choice2', 'choice3'), $right));
 355  
 356          // Check the initial state.
 357          $this->check_current_state(question_state::$todo);
 358          $this->check_current_mark(null);
 359          $this->check_current_output(
 360                  $this->get_contains_marked_out_of_summary(),
 361                  $this->get_contains_question_text_expectation($mc),
 362                  $this->get_contains_mc_checkbox_expectation('choice0', true, false),
 363                  $this->get_contains_mc_checkbox_expectation('choice1', true, false),
 364                  $this->get_contains_mc_checkbox_expectation('choice2', true, false),
 365                  $this->get_contains_mc_checkbox_expectation('choice3', true, false),
 366                  $this->get_contains_submit_button_expectation(true),
 367                  $this->get_does_not_contain_feedback_expectation(),
 368                  $this->get_does_not_contain_num_parts_correct(),
 369                  $this->get_tries_remaining_expectation(3),
 370                  $this->get_no_hint_visible_expectation(),
 371                  new question_pattern_expectation('/' .
 372                          preg_quote(get_string('selectmulti', 'qtype_multichoice'), '/') . '/'));
 373  
 374          // Submit an answer with one right, and one wrong.
 375          $this->process_submission(array($right[0] => 1, $wrong[0] => 1, '-submit' => 1));
 376  
 377          // Verify.
 378          $this->check_current_state(question_state::$todo);
 379          $this->check_current_mark(null);
 380          $this->check_current_output(
 381                  $this->get_contains_marked_out_of_summary(),
 382                  $this->get_contains_mc_checkbox_expectation($right[0], false, true),
 383                  $this->get_contains_mc_checkbox_expectation($right[1], false, false),
 384                  $this->get_contains_mc_checkbox_expectation($wrong[0], false, true),
 385                  $this->get_contains_mc_checkbox_expectation($wrong[1], false, false),
 386                  $this->get_contains_submit_button_expectation(false),
 387                  $this->get_contains_try_again_button_expectation(true),
 388                  $this->get_does_not_contain_correctness_expectation(),
 389                  new question_pattern_expectation('/' .
 390                          preg_quote(get_string('notcomplete', 'qbehaviour_interactive'), '/') . '/'),
 391                  $this->get_contains_hint_expectation('This is the first hint'),
 392                  $this->get_contains_num_parts_correct(1),
 393                  $this->get_contains_standard_incorrect_combined_feedback_expectation(),
 394                  $this->get_contains_hidden_expectation(
 395                          $this->quba->get_field_prefix($this->slot) . $right[0], '1'),
 396                  $this->get_does_not_contain_hidden_expectation(
 397                          $this->quba->get_field_prefix($this->slot) . $right[1]),
 398                  $this->get_contains_hidden_expectation(
 399                          $this->quba->get_field_prefix($this->slot) . $wrong[0], '0'),
 400                  $this->get_does_not_contain_hidden_expectation(
 401                          $this->quba->get_field_prefix($this->slot) . $wrong[1]));
 402  
 403          // Do try again.
 404          $this->process_submission(array($right[0] => 1, '-tryagain' => 1));
 405  
 406          // Verify.
 407          $this->check_current_state(question_state::$todo);
 408          $this->check_current_mark(null);
 409          $this->check_current_output(
 410                  $this->get_contains_marked_out_of_summary(),
 411                  $this->get_contains_mc_checkbox_expectation($right[0], true, true),
 412                  $this->get_contains_mc_checkbox_expectation($right[1], true, false),
 413                  $this->get_contains_mc_checkbox_expectation($wrong[0], true, false),
 414                  $this->get_contains_mc_checkbox_expectation($wrong[1], true, false),
 415                  $this->get_contains_submit_button_expectation(true),
 416                  $this->get_does_not_contain_correctness_expectation(),
 417                  $this->get_does_not_contain_feedback_expectation(),
 418                  $this->get_tries_remaining_expectation(2),
 419                  $this->get_no_hint_visible_expectation());
 420      }
 421  
 422      public function test_interactive_regrade_changing_num_tries_leaving_open() {
 423          // Create a multichoice multiple question.
 424          $q = test_question_maker::make_question('shortanswer');
 425          $q->hints = array(
 426              new question_hint_with_parts(0, 'This is the first hint.', FORMAT_HTML, true, true),
 427              new question_hint_with_parts(0, 'This is the second hint.', FORMAT_HTML, true, true),
 428          );
 429          $this->start_attempt_at_question($q, 'interactive', 3);
 430  
 431          // Check the initial state.
 432          $this->check_current_state(question_state::$todo);
 433          $this->check_current_mark(null);
 434          $this->check_current_output(
 435                  $this->get_tries_remaining_expectation(3));
 436  
 437          // Submit the right answer.
 438          $this->process_submission(array('answer' => 'frog', '-submit' => 1));
 439  
 440          // Verify.
 441          $this->check_current_state(question_state::$gradedright);
 442          $this->check_current_mark(3);
 443  
 444          // Now change the quiestion so that answer is only partially right, and regrade.
 445          $q->answers[13]->fraction = 0.6666667;
 446          $q->answers[14]->fraction = 1;
 447  
 448          $this->quba->regrade_all_questions(false);
 449  
 450          // Verify.
 451          $this->check_current_state(question_state::$todo);
 452          $this->check_current_mark(null);
 453      }
 454  
 455      public function test_interactive_regrade_changing_num_tries_finished() {
 456          // Create a multichoice multiple question.
 457          $q = test_question_maker::make_question('shortanswer');
 458          $q->hints = array(
 459              new question_hint_with_parts(0, 'This is the first hint.', FORMAT_HTML, true, true),
 460              new question_hint_with_parts(0, 'This is the second hint.', FORMAT_HTML, true, true),
 461          );
 462          $this->start_attempt_at_question($q, 'interactive', 3);
 463  
 464          // Check the initial state.
 465          $this->check_current_state(question_state::$todo);
 466          $this->check_current_mark(null);
 467          $this->check_current_output(
 468                  $this->get_tries_remaining_expectation(3));
 469  
 470          // Submit the right answer.
 471          $this->process_submission(array('answer' => 'frog', '-submit' => 1));
 472  
 473          // Verify.
 474          $this->check_current_state(question_state::$gradedright);
 475          $this->check_current_mark(3);
 476  
 477          // Now change the quiestion so that answer is only partially right, and regrade.
 478          $q->answers[13]->fraction = 0.6666667;
 479          $q->answers[14]->fraction = 1;
 480  
 481          $this->quba->regrade_all_questions(true);
 482  
 483          // Verify.
 484          $this->check_current_state(question_state::$gradedpartial);
 485          // TODO I don't think 1 is the right fraction here. However, it is what
 486          // you get attempting a question like this without regrading being involved,
 487          // and I am currently interested in testing regrading here.
 488          $this->check_current_mark(1);
 489      }
 490  }


Generated: Fri Nov 28 20:29:05 2014 Cross-referenced by PHPXref 0.7.1