diff --git a/doc/en/Authoring/Testing.md b/doc/en/Authoring/Testing.md index bcea0f3071a..8f9459687fa 100644 --- a/doc/en/Authoring/Testing.md +++ b/doc/en/Authoring/Testing.md @@ -37,7 +37,9 @@ In this way, the teacher can record, within the question itself, how they expect 3. The _Preview question_ window will open. If you have authority to edit the question, then the top right of the question window will contain a link to _question tests and deployed variants..._. Follow this link. 4. This page manages both question tests and deployed variants. Initially you will have no tests or deployed variants. Choose _Add a test case..._ 5. Specify values for each input. This may use the question variables. The values of these variables will be used for any random variants. -6. Specify the expected outcomes for each potential response tree. This includes the score, penalty and answer note. _Note_: currently only the last Answer Note, not the whole path through the potential response tree, is examined. This is a limitation. +6. Specify the expected outcomes for each potential response tree. This includes the score, penalty and answer note. + * Currently only the last Answer Note, not the whole path through the potential response tree, is examined. This is a limitation. + * Scores and penalties are rounded to three decimal places for testing purposes. 7. Once you have added the test case, STACK will automatically validate and submit these responses and display the outcomes. 8. You may add as many test cases are you need. It is sensible to add in the following. 1. The correct response. There is a button which will copy the expression used as the "Teacher's answer" in the input as a basis for a test case to help create this test. diff --git a/stack/questiontestresult.php b/stack/questiontestresult.php index 930678a4b0e..3e3f5c4704f 100644 --- a/stack/questiontestresult.php +++ b/stack/questiontestresult.php @@ -19,6 +19,8 @@ // @copyright 2012 The Open University. // @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later. +require_once('utils.class.php'); + class stack_question_test_result { /** * @var stack_question_test the test case that this is the results for. @@ -121,6 +123,14 @@ public function get_input_states() { return $states; } + /** + * Ensure we round scores and penalties consistently. + * @param float $score + */ + private function round_prt_scores($score) { + return round(stack_utils::fix_to_continued_fraction($score + 0, 4), 3); + } + /** * @return array input name => object with fields ->mark, ->expectedmark, * ->penalty, ->expectedpenalty, ->answernote, ->expectedanswernote, @@ -135,20 +145,26 @@ public function get_prt_states() { $state = new stdClass(); $state->expectedscore = $expectedresult->score; if (!is_null($state->expectedscore)) { - // Single PRTs only work to three decimal places, so we only expect that level. - $state->expectedscore = round($state->expectedscore + 0, 3); + $state->expectedscore = $this->round_prt_scores($state->expectedscore + 0); } $state->expectedpenalty = $expectedresult->penalty; if (!is_null($state->expectedpenalty)) { - // Single PRTs only work to three decimal places, so we only expect that level. - $state->expectedpenalty = round($state->expectedpenalty + 0, 3); + $state->expectedpenalty = $this->round_prt_scores($state->expectedpenalty + 0); } $state->expectedanswernote = reset($expectedanswernote); if (array_key_exists($prtname, $this->actualresults)) { $actualresult = $this->actualresults[$prtname]; - $state->score = $actualresult->get_score(); - $state->penalty = $actualresult->get_penalty(); + $actualscore = $actualresult->get_score(); + if (!is_null($actualscore)) { + $actualscore = $this->round_prt_scores($actualscore + 0); + } + $state->score = $actualscore; + $actualpenalty = $actualresult->get_penalty(); + if (!is_null($actualpenalty)) { + $actualpenalty = $this->round_prt_scores($actualpenalty + 0); + } + $state->penalty = $actualpenalty; $state->answernote = implode(' | ', $actualresult->get_answernotes()); $state->trace = implode("\n", $actualresult->get_trace()); $state->feedback = $actualresult->get_feedback();