@@ -726,8 +726,78 @@ public function __construct($pattern, $message = '') {
726
726
727
727
728
728
/**
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.)
731
801
*
732
802
* @copyright 2009 The Open University
733
803
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
0 commit comments