MDL-40729 check marks and grades from quiz attempts
authorJamie Pratt <me@jamiep.org>
Thu, 18 Jul 2013 03:44:46 +0000 (10:44 +0700)
committerDan Poltawski <dan@moodle.com>
Tue, 23 Jul 2013 08:04:13 +0000 (16:04 +0800)
compare to marks in csv file.

mod/quiz/tests/attempt_walkthrough_from_csv_test.php
mod/quiz/tests/fixtures/results00.csv [new file with mode: 0644]
mod/quiz/tests/fixtures/steps00.csv

index dfca2b1..553e021 100644 (file)
@@ -128,7 +128,8 @@ class mod_quiz_attempt_walkthrough_from_csv_testcase extends advanced_testcase {
         foreach ($this->tests as $test) {
             $qs = $this->load_csv_data_file('questions', $test);
             $steps = $this->load_csv_data_file('steps', $test);
-            $dataset[] = array($qs, $steps);
+            $results = $this->load_csv_data_file('results', $test);
+            $dataset[] = array($qs, $steps, $results);
         }
         return $dataset;
     }
@@ -156,20 +157,48 @@ class mod_quiz_attempt_walkthrough_from_csv_testcase extends advanced_testcase {
         return $this->createCsvDataSet($files)->getTable($setname);
     }
 
+    /**
+     * Break down row of csv data into sub arrays, according to column names.
+     *
+     * @param array $row from csv file with field names with parts separate by '.'.
+     * @return array the row with each part of the field name following a '.' being a separate sub array's index.
+     */
+    protected function explode_dot_separated_keys_to_make_subindexs(array $row) {
+        $parts = array();
+        foreach ($row as $columnkey => $value) {
+            $newkeys = explode('.', trim($columnkey));
+            $placetoputvalue =& $parts;
+            foreach ($newkeys as $newkeydepth => $newkey) {
+                if ($newkeydepth + 1 === count($newkeys)) {
+                    $placetoputvalue[$newkey] = $value;
+                } else {
+                    // Going deeper down.
+                    if (!isset($placetoputvalue[$newkey])) {
+                        $placetoputvalue[$newkey] = array();
+                    }
+                    $placetoputvalue =& $placetoputvalue[$newkey];
+                }
+            }
+        }
+        return $parts;
+    }
+
     /**
      * Create a quiz add questions to it, walk through quiz attempts and then check results.
      *
      * @param PHPUnit_Extensions_Database_DataSet_ITable $qs questions to add to quiz, read from csv file "questionsXX.csv".
      * @param PHPUnit_Extensions_Database_DataSet_ITable $steps steps to simulate, read from csv file "stepsXX.csv".
+     * @param PHPUnit_Extensions_Database_DataSet_ITable $results results expected, read from csv file "resultsXX.csv".
      * @dataProvider get_data_for_walkthrough
      */
-    public function test_walkthrough_from_csv($qs, $steps) {
+    public function test_walkthrough_from_csv($qs, $steps, $results) {
         global $DB;
         $this->resetAfterTest(true);
         question_bank::get_qtype('random')->clear_caches_before_testing();
 
         $this->create_quiz($qs);
 
+        $attemptids = array();
         for ($rowno = 0; $rowno < $steps->getRowCount(); $rowno++) {
 
             $step = $this->explode_dot_separated_keys_to_make_subindexs($steps->getRow($rowno));
@@ -203,6 +232,8 @@ class mod_quiz_attempt_walkthrough_from_csv_testcase extends advanced_testcase {
             quiz_start_new_attempt($quizobj, $quba, $attempt, 1, $timenow, $step['randqs'], $step['variants']);
             quiz_attempt_save_started($quizobj, $quba, $attempt);
 
+            $attemptids[$step['quizattempt']] = $attempt->id;
+
             // Process some responses from the student.
             $attemptobj = quiz_attempt::create($attempt->id);
             $attemptobj->process_submitted_actions($timenow, false, $step['responses']);
@@ -211,51 +242,73 @@ class mod_quiz_attempt_walkthrough_from_csv_testcase extends advanced_testcase {
             $attemptobj = quiz_attempt::create($attempt->id);
             $attemptobj->process_finish($timenow, false);
 
+
+        }
+
+        for ($rowno = 0; $rowno < $results->getRowCount(); $rowno++) {
+            $result = $this->explode_dot_separated_keys_to_make_subindexs($results->getRow($rowno));
             // Re-load quiz attempt data.
-            $attemptobj = quiz_attempt::create($attempt->id);
+            $attemptobj = quiz_attempt::create($attemptids[$result['quizattempt']]);
+            $this->check_attempt_results($result, $attemptobj);
 
-            // Check that results are stored as expected.
-            $this->assertEquals(1, $attemptobj->get_attempt_number());
-            $this->assertEquals(true, $attemptobj->is_finished());
-            $this->assertEquals($timenow, $attemptobj->get_submitted_date());
-            $this->assertEquals($user->id, $attemptobj->get_userid());
-
-            // Check quiz grades.
-            $grades = quiz_get_user_grades($this->quiz, $user->id);
-            $grade = array_shift($grades);
-            $this->assertEquals(100.0, $grade->rawgrade);
-
-            // Check grade book.
-            $gradebookgrades = grade_get_grades($attemptobj->get_courseid(), 'mod', 'quiz', $this->quiz->id, $user->id);
-            $gradebookitem = array_shift($gradebookgrades->items);
-            $gradebookgrade = array_shift($gradebookitem->grades);
-            $this->assertEquals(100, $gradebookgrade->grade);
         }
     }
 
     /**
-     * Break down row of csv data into sub arrays, according to column names.
+     * Check that attempt results are as specified in $result.
      *
-     * @param array $row from csv file with field names with parts separate by '.'.
-     * @return array the row with each part of the field name following a '.' being a separate sub array's index.
+     * @param array        $result             row of data read from csv file.
+     * @param quiz_attempt $attemptobj         the attempt object loaded from db.
+     * @throws coding_exception
      */
-    protected function explode_dot_separated_keys_to_make_subindexs(array $row) {
-        $parts = array();
-        foreach ($row as $columnkey => $value) {
-            $newkeys = explode('.', trim($columnkey));
-            $placetoputvalue =& $parts;
-            foreach ($newkeys as $newkeydepth => $newkey) {
-                if ($newkeydepth + 1 === count($newkeys)) {
-                    $placetoputvalue[$newkey] = $value;
-                } else {
-                    // Going deeper down.
-                    if (!isset($placetoputvalue[$newkey])) {
-                        $placetoputvalue[$newkey] = array();
+    protected function check_attempt_results($result, $attemptobj) {
+        foreach ($result as $fieldname => $value) {
+            switch ($fieldname) {
+                case 'quizattempt' :
+                    break;
+                case 'attemptnumber' :
+                    $this->assertEquals($value, $attemptobj->get_attempt_number());
+                    break;
+                case 'slots' :
+                    foreach ($value as $slotno => $slottests) {
+                        foreach ($slottests as $slotfieldname => $slotvalue) {
+                            switch ($slotfieldname) {
+                                case 'mark' :
+                                    $this->assertEquals(round($slotvalue, 2), $attemptobj->get_question_mark($slotno),
+                                                        "Mark for slot $slotno of attempt {$result['quizattempt']}.");
+                                    break;
+                                default :
+                                    throw new coding_exception('Unknown slots sub field column in csv file '
+                                                                   .s($slotfieldname));
+                            }
+                        }
                     }
-                    $placetoputvalue =& $placetoputvalue[$newkey];
-                }
+                    break;
+                case 'finished' :
+                    $this->assertEquals($value, $attemptobj->is_finished());
+                    break;
+                case 'summarks' :
+                    $this->assertEquals($value, $attemptobj->get_sum_marks(), "Sum of marks of attempt {$result['quizattempt']}.");
+                    break;
+                case 'quizgrade' :
+                    // Check quiz grades.
+                    $grades = quiz_get_user_grades($attemptobj->get_quiz(), $attemptobj->get_userid());
+                    $grade = array_shift($grades);
+                    $this->assertEquals($value, $grade->rawgrade, "Quiz grade for attempt {$result['quizattempt']}.");
+                    break;
+                case 'gradebookgrade' :
+                    // Check grade book.
+                    $gradebookgrades = grade_get_grades($attemptobj->get_courseid(),
+                                                        'mod', 'quiz',
+                                                        $attemptobj->get_quizid(),
+                                                        $attemptobj->get_userid());
+                    $gradebookitem = array_shift($gradebookgrades->items);
+                    $gradebookgrade = array_shift($gradebookitem->grades);
+                    $this->assertEquals($value, $gradebookgrade->grade, "Gradebook grade for attempt {$result['quizattempt']}.");
+                    break;
+                default :
+                    throw new coding_exception('Unknown column in csv file '.s($fieldname));
             }
         }
-        return $parts;
     }
 }
diff --git a/mod/quiz/tests/fixtures/results00.csv b/mod/quiz/tests/fixtures/results00.csv
new file mode 100644 (file)
index 0000000..95e9afb
--- /dev/null
@@ -0,0 +1,11 @@
+quizattempt,slots.1.mark,slots.2.mark,slots.3.mark,slots.4.mark,slots.5.mark,slots.6.mark,slots.7.mark,summarks
+1,0.8,1,1,1,0.5,1,0,5.3
+2,1,0,1,1,0.5,0,0.5,4
+3,0,1,1,0,0.5,0,0.5,3
+4,0,1,0.3333333,1,1,1,1,5.33333
+5,1,1,1,1,0.5,1,1,6.5
+6,0,1,1,1,0.5,1,1,5.5
+7,0,0,1,0,0.5,0,0,1.5
+8,0.8,1,1,1,0.5,1,0,5.3
+9,0,0,0.3333333,0,0.5,1,1,2.83333
+10,0.8,1,1,1,0.5,1,0.5,5.8
index 8eb77fa..a44c003 100644 (file)
@@ -1,3 +1,11 @@
-quizattempt,firstname,lastname,randqs.1,responses.1.answer,responses.2.answer,variants.2,responses.3.0,responses.3.1,responses.3.2,responses.4.answer,responses.5.0,responses.5.1,responses.5.2,responses.5.3,responses.6.answer,responses.7.1.answer,responses.7.2.answer
-1,John,Doe,shortanswer,frog,3.3,3,amphibian,mammal,amphibian,1,1,0,1,0,0,Owl,2
-2,Jane,Doe,numerical,3.14,19.4,4,amphibian,mammal,amphibian,1,1,0,1,0,0,Owl,2
+quizattempt,firstname,lastname,randqs.1,responses.1.answer,variants.2,responses.2.answer,responses.3.0,responses.3.1,responses.3.2,responses.4.answer,responses.5.0,responses.5.1,responses.5.2,responses.5.3,responses.6.answer,responses.7.1.answer,responses.7.2.answer
+1,John,Jones,shortanswer,toad,4,19.4,amphibian,mammal,amphibian,1,0,1,1,0,0,Pussy-cat,0
+2,John,Smith,shortanswer,frog,6,-0.6,amphibian,mammal,amphibian,1,1,1,0,0,3,Dog,2
+3,John,Vicars,numerical,3.142,4,19.4,amphibian,mammal,amphibian,0,0,0,1,1,1,Owl,1
+4,John,Pacino,numerical,3.142,6,9.4,mammal,amphibian,amphibian,1,1,0,1,0,0,Owl,2
+5,John,Deniro,shortanswer,frog,9,7.1,amphibian,mammal,amphibian,1,0,0,1,1,0,Owl,2
+6,John,Banks,numerical,3.1,7,9.1,amphibian,mammal,amphibian,1,1,0,0,1,0,Owl,2
+7,John,Asimov,numerical,2.5,3,-0.2,amphibian,mammal,amphibian,0,1,1,0,0,1,Dog,1
+8,John,Chomsky,shortanswer,toad,2,8.5,amphibian,mammal,amphibian,1,0,0,1,1,0,Dog,1
+9,John,Yamaguchi,shortanswer,tadpole,5,-0.1,amphibian,amphibian,mammal,0,1,1,0,0,0,Owl,2
+10,John,Robbins,shortanswer,toad,7,9.1,amphibian,mammal,amphibian,1,1,0,0,1,0,Owl,1