Skip to content

Commit 3d15def

Browse files
author
David Monllaó
committed
Merge branch 'MDL-65222' of git://github.com/timhunt/moodle
2 parents 65c6dec + 05ea7ab commit 3d15def

File tree

1 file changed

+72
-2
lines changed

1 file changed

+72
-2
lines changed

Diff for: question/engine/tests/helpers.php

+72-2
Original file line numberDiff line numberDiff line change
@@ -726,8 +726,78 @@ public function __construct($pattern, $message = '') {
726726

727727

728728
/**
729-
* Helper base class for tests that walk a question through a sequents of
730-
* interactions under the control of a particular behaviour.
729+
* Helper base class for question walk-through tests.
730+
*
731+
* The purpose of tests that use this base class is to simulate the entire
732+
* interaction of a student making an attempt at a question. Therefore,
733+
* these are not really unit tests. They would more accurately be described
734+
* as integration tests. However, whether they are unit tests or not,
735+
* it works well to implement them in PHPUnit.
736+
*
737+
* Historically, tests like this were made because Moodle did not have anything
738+
* like Behat for end-to-end testing. Even though we do now have Behat, it makes
739+
* sense to keep these walk-through tests. They run massively faster than Behat
740+
* tests, which gives you a much faster feedback loop while doing development.
741+
* They also make it quite easy to test things like regrading the attempt after
742+
* the question has been edited, which would be possible but very fiddly in Behat.
743+
*
744+
* Ideally, the full set of tests for the question class of a question type would be:
745+
*
746+
* 1. A lot of unit tests for each qtype_myqtype_question class method
747+
* like grade_response, is_complete_response, is_same_response, ...
748+
*
749+
* 2. Several of these walk-through tests, to test the end-to-end interaction
750+
* of a student with a question, for example with different behaviours.
751+
*
752+
* 3. Just one Behat test, using question preview, to verify that everything
753+
* is plugged together correctly and works when used through the UI.
754+
*
755+
* What one would expect to see in one of these walk-through tests is:
756+
*
757+
* // 1. Set up a question: $q.
758+
*
759+
* // 2. A call to $this->start_attempt_at_question($q, ...); with the relevant options.
760+
*
761+
* // 3. Some number of calls to $this->process_submission passing an array of simulated
762+
* // POST data that matches what would be sent back be submitting a form that contains
763+
* // the form fields that are output by rendering the question. This is like clicking
764+
* // the 'Check' button in a question, or navigating to the next page in a quiz.
765+
*
766+
* // 4. A call to $this->finish(); which is the equivalent of clicking
767+
* // 'Submit all and finish' in the quiz.
768+
*
769+
* // 5. After each of steps 2-4 above, one would expect to see a certain amount of
770+
* // validation of the state of the question and how the question is rendered,
771+
* // using methods like $this->check_current_state(), $this->check_current_output, etc.
772+
*
773+
* The best way to work out how to write tests like this is probably to look at
774+
* some examples in other question types or question behaviours.
775+
*
776+
* In writing these tests, it is worth noting the following points:
777+
*
778+
* a) The easiest mistake to make is at step 3. You need to ensure that your
779+
* simulated post data actually matches what gets sent back when the
780+
* question is submitted in the browser. Try checking it against the
781+
* HTTP POST requests you see in your browser when the question is submitted.
782+
* Some question types have a $q->prepare_simulated_post_data() method that
783+
* can help with this.
784+
*
785+
* b) In the past, tests like these used to contain even more repetitive code,
786+
* and so they were re-factored to add the helper methods like
787+
* start_attempt_at_question, process_submission, finish. That change had
788+
* good effects, like reducing duplicate code. However, there were down-sides.
789+
* The extra layers of indirection hide what is going on, which means these
790+
* tests are harder to understand until you know what the helpers are doing.
791+
* If you want an interesting exercise, take one of the walk-through tests,
792+
* and inline all the helpers. This might be a good way to understand more about
793+
* the question engine API. However, having made the everything-inlined code
794+
* and learned from the process, you should then just throw it away.
795+
*
796+
* c) The way check_current_output works is weird. When these tests were first written
797+
* Moodle used SimpleTest for unit tests and check_current_output os written in a
798+
* style that made sense there. When we moved to PHPUnit, a quick and dirty
799+
* conversion was done. That was a pragmatic move at the time, and we just have
800+
* to live with the result. Sorry. (And: don't copy that style for new things.)
731801
*
732802
* @copyright 2009 The Open University
733803
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later

0 commit comments

Comments
 (0)