MDL-40729 check marks and grades from quiz attempts

compare to marks in csv file.
This commit is contained in:
Jamie Pratt
2013-07-23 16:04:13 +08:00
committed by Dan Poltawski
parent d735f3d8f3
commit e39a2faa58
3 changed files with 112 additions and 40 deletions
@@ -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;
}
}
+11
View File
@@ -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
1 quizattempt slots.1.mark slots.2.mark slots.3.mark slots.4.mark slots.5.mark slots.6.mark slots.7.mark summarks
2 1 0.8 1 1 1 0.5 1 0 5.3
3 2 1 0 1 1 0.5 0 0.5 4
4 3 0 1 1 0 0.5 0 0.5 3
5 4 0 1 0.3333333 1 1 1 1 5.33333
6 5 1 1 1 1 0.5 1 1 6.5
7 6 0 1 1 1 0.5 1 1 5.5
8 7 0 0 1 0 0.5 0 0 1.5
9 8 0.8 1 1 1 0.5 1 0 5.3
10 9 0 0 0.3333333 0 0.5 1 1 2.83333
11 10 0.8 1 1 1 0.5 1 0.5 5.8
+11 -3
View 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
1 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
2 1 John Doe Jones shortanswer frog toad 3 4 3.3 19.4 amphibian mammal amphibian 1 1 0 0 1 1 0 0 Owl Pussy-cat 2 0
3 2 Jane John Doe Smith numerical shortanswer 3.14 frog 4 6 19.4 -0.6 amphibian mammal amphibian 1 1 0 1 1 0 0 0 3 Owl Dog 2
4 3 John Vicars numerical 3.142 4 19.4 amphibian mammal amphibian 0 0 0 1 1 1 Owl 1
5 4 John Pacino numerical 3.142 6 9.4 mammal amphibian amphibian 1 1 0 1 0 0 Owl 2
6 5 John Deniro shortanswer frog 9 7.1 amphibian mammal amphibian 1 0 0 1 1 0 Owl 2
7 6 John Banks numerical 3.1 7 9.1 amphibian mammal amphibian 1 1 0 0 1 0 Owl 2
8 7 John Asimov numerical 2.5 3 -0.2 amphibian mammal amphibian 0 1 1 0 0 1 Dog 1
9 8 John Chomsky shortanswer toad 2 8.5 amphibian mammal amphibian 1 0 0 1 1 0 Dog 1
10 9 John Yamaguchi shortanswer tadpole 5 -0.1 amphibian amphibian mammal 0 1 1 0 0 0 Owl 2
11 10 John Robbins shortanswer toad 7 9.1 amphibian mammal amphibian 1 1 0 0 1 0 Owl 1