Moodle APIs 3.9
Moodle 3.9.13+ (Build: 20220325)
Public Member Functions | Static Public Member Functions | Protected Member Functions | Static Protected Member Functions | Protected Attributes | List of all members
qbehaviour_walkthrough_test_base Class Reference

Helper base class for question walk-through tests. More...

Inheritance diagram for qbehaviour_walkthrough_test_base:
question_testcase advanced_testcase base_testcase

Public Member Functions

 assert ($expectation, $compare, $notused='')
 
 assert_select_options ($expectation, $html)
 Use this function rather than assert when checking the value of options within a select element. More...
 
 assertDebuggingCalled ($debugmessage=null, $debuglevel=null, $message='')
 Assert that exactly debugging was just called once. More...
 
 assertDebuggingCalledCount ($expectedcount, $debugmessages=array(), $debuglevels=array(), $message='')
 Asserts how many times debugging has been called. More...
 
 assertDebuggingNotCalled ($message='')
 Call when no debugging() messages expected. More...
 
 assertEventContextNotUsed (\core\event\base $event, $message='')
 Assert that an event is not using event->contxet. More...
 
 assertEventLegacyData ($expected, core\event\base $event, $message='')
 Assert that an event legacy data is equal to the expected value. More...
 
 assertEventLegacyLogData ($expected, core\event\base $event, $message='')
 Assert that an event legacy log data is equal to the expected value. More...
 
 assertTimeCurrent ($time, $message='')
 Assert that: start < $time < time() More...
 
 getDebuggingMessages ()
 Return debugging messages from the current test. More...
 
 getExternalTestFileUrl ($path, $https=false)
 Returns UTL of the external test file. More...
 
 preventResetByRollback ()
 Call this method from test if you want to make sure that the resetting of database is done the slow way without transaction rollback. More...
 
 recurseFolders ($path, $callback, $fileregexp='/.*/', $exclude=false, $ignorefolders=array())
 Recursively visit all the files in the source tree. More...
 
 redirectEmails ()
 Starts email redirection. More...
 
 redirectEvents ()
 Starts event redirection. More...
 
 redirectMessages ()
 Starts message redirection. More...
 
 resetAfterTest ($reset=true)
 Reset everything after current test. More...
 
 resetDebugging ()
 Clear all previous debugging messages in current test and revert to default DEVELOPER_DEBUG level.
 
 runBare ()
 Runs the bare test sequence. More...
 
 setCurrentTimeStart ()
 Stores current time as the base for assertTimeCurrent(). More...
 
 waitForSecond ()
 Wait for a second to roll over, ensures future calls to time() return a different result. More...
 

Static Public Member Functions

static assertNotTag ($matcher, $actual, $message='', $ishtml=true)
 Note: we are overriding this method to remove the deprecated error. More...
 
static assertTag ($matcher, $actual, $message='', $ishtml=true)
 Note: we are overriding this method to remove the deprecated error. More...
 
static assertValidKeys (array $hash, array $validKeys)
 Validate list of keys in the associative array. More...
 
static findNodes (DOMDocument $dom, array $options, $isHtml=true)
 Parse out the options from the tag using DOM object tree. More...
 
static getDataGenerator ()
 Get data generator. More...
 
static resetAllData ($detectchanges=false)
 Reset all database tables, restore global state and clear caches and optionally purge dataroot dir. More...
 
static setAdminUser ()
 Set current $USER to admin account, reset access cache. More...
 
static setGuestUser ()
 Set current $USER to guest account, reset access cache. More...
 
static setTimezone ($servertimezone='Australia/Perth', $defaultphptimezone='Australia/Perth')
 Change server and default php timezones. More...
 
static setUser ($user=null)
 Set current $USER, reset access cache. More...
 

Protected Member Functions

 check_comment ($comment, $commentformat)
 Asserts if the manual comment for the question is equal to the provided arguments. More...
 
 check_current_mark ($mark)
 
 check_current_output ()
 
 check_current_state ($state)
 
 check_output_contains ($string)
 
 check_output_contains_hidden_input ($name, $value)
 
 check_output_contains_lang_string ($identifier, $component='', $a=null)
 
 check_output_contains_selectoptions (... $expectations)
 Use this function rather than check_current_output for select expectations where checking the value of the options is required. More...
 
 check_output_contains_text_input ($name, $value=null, $enabled=true)
 
 check_output_contains_text_input_with_class ($name, $class=null)
 
 check_output_does_not_contain ($string)
 
 check_output_does_not_contain_text_input_with_class ($name, $class=null)
 
 check_step_count ($expectednumsteps)
 
 createArrayDataSet (array $data)
 Creates new ArrayDataSet from given array. More...
 
 createCsvDataSet ($files, $delimiter=',', $enclosure='"', $escape = '"')
 Creates a new CsvDataSet from the given array of csv files. More...
 
 createFlatXMLDataSet ($xmlFile)
 Creates a new FlatXmlDataSet with the given $xmlFile. More...
 
 createXMLDataSet ($xmlFile)
 Creates a new XMLDataSet with the given $xmlFile. More...
 
 delete_quba ()
 
 finish ()
 
 get_contains_button_expectation ($name, $value=null, $enabled=null)
 
 get_contains_cbm_radio_expectation ($certainty, $enabled=null, $checked=null)
 
 get_contains_checkbox_expectation ($baseattr, $enabled, $checked)
 
 get_contains_correct_expectation ()
 
 get_contains_general_feedback_expectation ($question)
 
 get_contains_hidden_expectation ($name, $value=null)
 
 get_contains_hint_expectation ($hinttext)
 
 get_contains_incorrect_expectation ()
 
 get_contains_mark_summary ($mark)
 
 get_contains_marked_out_of_summary ()
 
 get_contains_mc_checkbox_expectation ($index, $enabled=null, $checked=null)
 
 get_contains_mc_radio_expectation ($index, $enabled=null, $checked=null)
 
 get_contains_num_parts_correct ($num)
 
 get_contains_partcorrect_expectation ()
 
 get_contains_question_text_expectation ($question)
 
 get_contains_radio_expectation ($baseattr, $enabled, $checked)
 
 get_contains_select_expectation ($name, $choices, $selected=null, $enabled=null)
 
 get_contains_standard_correct_combined_feedback_expectation ()
 
 get_contains_standard_incorrect_combined_feedback_expectation ()
 
 get_contains_standard_partiallycorrect_combined_feedback_expectation ()
 
 get_contains_submit_button_expectation ($enabled=null)
 Returns an epectation that a string contains the HTML of a button with name {question-attempt prefix}-submit, and eiter enabled or not. More...
 
 get_contains_tf_false_radio_expectation ($enabled=null, $checked=null)
 
 get_contains_tf_true_radio_expectation ($enabled=null, $checked=null)
 
 get_contains_try_again_button_expectation ($enabled=null)
 
 get_contains_validation_error_expectation ()
 
 get_does_not_contain_correctness_expectation ()
 
 get_does_not_contain_feedback_expectation ()
 
 get_does_not_contain_hidden_expectation ($name, $value=null)
 
 get_does_not_contain_mark_summary ()
 
 get_does_not_contain_num_parts_correct ()
 
 get_does_not_contain_specific_feedback_expectation ()
 
 get_does_not_contain_submit_button_expectation ()
 Returns an epectation that a string does not contain the HTML of a button with name {question-attempt prefix}-submit. More...
 
 get_does_not_contain_try_again_button_expectation ()
 
 get_does_not_contain_validation_error_expectation ()
 
 get_invalid_answer_expectation ()
 
 get_mc_right_answer_index ($mc)
 
 get_no_hint_visible_expectation ()
 
 get_question_attempt ()
 
 get_step ($stepnum)
 
 get_step_count ()
 
 get_tag_matcher ($tag, $attributes)
 
 get_tries_remaining_expectation ($n)
 
 load_quba (moodle_database $db=null)
 
 loadDataSet (PHPUnit\DbUnit\DataSet\IDataSet $dataset)
 Load date into moodle database tables from standard PHPUnit data set. More...
 
 manual_grade ($comment, $mark, $commentformat=null)
 
 process_autosave ($data)
 
 process_submission ($data)
 
 render ()
 Generate the HTML rendering of the question in its current state in $this->currentoutput so that it can be verified.
 
 response_data_to_post ($data)
 Convert an array of data destined for one question to the equivalent POST data. More...
 
 runAdhocTasks ($matchclass='', $matchuserid=null)
 Run adhoc tasks, optionally matching the specified classname. More...
 
 save_quba (moodle_database $db=null)
 
 setUp ()
 
 start_attempt_at_question ($question, $preferredbehaviour, $maxmark=null, $variant=1)
 
 tearDown ()
 

Static Protected Member Functions

static getDescendants (DOMNode $node)
 Recursively get flat array of all descendants of this node. More...
 
static getElementsByCaseInsensitiveTagName (DOMDocument $dom, $tag)
 Gets elements by case insensitive tagname. More...
 
static getNodeText (DOMNode $node)
 Get the text value of this node's child text node. More...
 

Protected Attributes

string $currentoutput = ''
 after render() has been called, this contains the display of the question in its current state.
 
question_display_options $displayoptions
 
question_usage_by_activity $quba
 
integer $slot
 

Detailed Description

Helper base class for question walk-through tests.

The purpose of tests that use this base class is to simulate the entire interaction of a student making an attempt at a question. Therefore, these are not really unit tests. They would more accurately be described as integration tests. However, whether they are unit tests or not, it works well to implement them in PHPUnit.

Historically, tests like this were made because Moodle did not have anything like Behat for end-to-end testing. Even though we do now have Behat, it makes sense to keep these walk-through tests. They run massively faster than Behat tests, which gives you a much faster feedback loop while doing development. They also make it quite easy to test things like regrading the attempt after the question has been edited, which would be possible but very fiddly in Behat.

Ideally, the full set of tests for the question class of a question type would be:

  1. A lot of unit tests for each qtype_myqtype_question class method like grade_response, is_complete_response, is_same_response, ...
  2. Several of these walk-through tests, to test the end-to-end interaction of a student with a question, for example with different behaviours.
  3. Just one Behat test, using question preview, to verify that everything is plugged together correctly and works when used through the UI.

What one would expect to see in one of these walk-through tests is:

// 1. Set up a question: $q.

// 2. A call to $this->start_attempt_at_question($q, ...); with the relevant options.

// 3. Some number of calls to $this->process_submission passing an array of simulated // POST data that matches what would be sent back be submitting a form that contains // the form fields that are output by rendering the question. This is like clicking // the 'Check' button in a question, or navigating to the next page in a quiz.

// 4. A call to $this->finish(); which is the equivalent of clicking // 'Submit all and finish' in the quiz.

// 5. After each of steps 2-4 above, one would expect to see a certain amount of // validation of the state of the question and how the question is rendered, // using methods like $this->check_current_state(), $this->check_current_output, etc.

The best way to work out how to write tests like this is probably to look at some examples in other question types or question behaviours.

In writing these tests, it is worth noting the following points:

a) The easiest mistake to make is at step 3. You need to ensure that your simulated post data actually matches what gets sent back when the question is submitted in the browser. Try checking it against the HTTP POST requests you see in your browser when the question is submitted. Some question types have a $q->prepare_simulated_post_data() method that can help with this.

b) In the past, tests like these used to contain even more repetitive code, and so they were re-factored to add the helper methods like start_attempt_at_question, process_submission, finish. That change had good effects, like reducing duplicate code. However, there were down-sides. The extra layers of indirection hide what is going on, which means these tests are harder to understand until you know what the helpers are doing. If you want an interesting exercise, take one of the walk-through tests, and inline all the helpers. This might be a good way to understand more about the question engine API. However, having made the everything-inlined code and learned from the process, you should then just throw it away.

c) The way check_current_output works is weird. When these tests were first written Moodle used SimpleTest for unit tests and check_current_output os written in a style that made sense there. When we moved to PHPUnit, a quick and dirty conversion was done. That was a pragmatic move at the time, and we just have to live with the result. Sorry. (And: don't copy that style for new things.)

License
http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later

Member Function Documentation

◆ assert_select_options()

question_testcase::assert_select_options (   $expectation,
  $html 
)
inherited

Use this function rather than assert when checking the value of options within a select element.

Parameters
question_contains_select_expectation$expectationThe select expectation class
string$htmlThe rendered output to check against

◆ assertDebuggingCalled()

advanced_testcase::assertDebuggingCalled (   $debugmessage = null,
  $debuglevel = null,
  $message = '' 
)
inherited

Assert that exactly debugging was just called once.

Discards the debugging message if successful.

Parameters
null | string$debugmessagenull means any
null | string$debuglevelnull means any
string$message

◆ assertDebuggingCalledCount()

advanced_testcase::assertDebuggingCalledCount (   $expectedcount,
  $debugmessages = array(),
  $debuglevels = array(),
  $message = '' 
)
inherited

Asserts how many times debugging has been called.

Parameters
int$expectedcountThe expected number of times
array$debugmessagesExpected debugging messages, one for each expected message.
array$debuglevelsExpected debugging levels, one for each expected message.
string$message
Return values
void

◆ assertDebuggingNotCalled()

advanced_testcase::assertDebuggingNotCalled (   $message = '')
inherited

Call when no debugging() messages expected.

Parameters
string$message

◆ assertEventContextNotUsed()

advanced_testcase::assertEventContextNotUsed ( \core\event\base  $event,
  $message = '' 
)
inherited

Assert that an event is not using event->contxet.

While restoring context might not be valid and it should not be used by event url or description methods.

Parameters
core::event::base$eventthe event object.
string$message
Return values
void

◆ assertEventLegacyData()

advanced_testcase::assertEventLegacyData (   $expected,
core\event\base  $event,
  $message = '' 
)
inherited

Assert that an event legacy data is equal to the expected value.

Parameters
mixed$expectedexpected data.
core::event::base$eventthe event object.
string$message
Return values
void

◆ assertEventLegacyLogData()

advanced_testcase::assertEventLegacyLogData (   $expected,
core\event\base  $event,
  $message = '' 
)
inherited

Assert that an event legacy log data is equal to the expected value.

Parameters
mixed$expectedexpected data.
core::event::base$eventthe event object.
string$message
Return values
void

◆ assertNotTag()

static base_testcase::assertNotTag (   $matcher,
  $actual,
  $message = '',
  $ishtml = true 
)
staticinherited

Note: we are overriding this method to remove the deprecated error.

See also
https://tracker.moodle.org/browse/MDL-47129
Parameters
array$matcher
string$actual
string$message
boolean$ishtml
Deprecated:
3.0

◆ assertTag()

static base_testcase::assertTag (   $matcher,
  $actual,
  $message = '',
  $ishtml = true 
)
staticinherited

Note: we are overriding this method to remove the deprecated error.

See also
https://tracker.moodle.org/browse/MDL-47129
Parameters
array$matcher
string$actual
string$message
boolean$ishtml
Deprecated:
3.0

◆ assertTimeCurrent()

advanced_testcase::assertTimeCurrent (   $time,
  $message = '' 
)
inherited

Assert that: start < $time < time()

Parameters
int$time
string$message
Return values
void

◆ assertValidKeys()

static base_testcase::assertValidKeys ( array  $hash,
array  $validKeys 
)
staticinherited

Validate list of keys in the associative array.

Parameters
array$hash
array$validKeys
Return values
array
Exceptions
PHPUnit::Framework::Exception

◆ check_comment()

qbehaviour_walkthrough_test_base::check_comment (   $comment,
  $commentformat 
)
protected

Asserts if the manual comment for the question is equal to the provided arguments.

Parameters
$commentComment text
$commentformatComment format

◆ check_current_output()

qbehaviour_walkthrough_test_base::check_current_output ( )
protected
Parameters
$conditionone or more Expectations. (users varargs).

◆ check_output_contains_selectoptions()

qbehaviour_walkthrough_test_base::check_output_contains_selectoptions (   $expectations)
protected

Use this function rather than check_current_output for select expectations where checking the value of the options is required.

check_current_output only checks that the right number of options are available.

Parameters
question_contains_select_expectation$expectationsOne or more expectations.

◆ createArrayDataSet()

advanced_testcase::createArrayDataSet ( array  $data)
protectedinherited

Creates new ArrayDataSet from given array.

Parameters
array$dataarray of tables, first row in each table is columns
Return values
phpunit_ArrayDataSet

◆ createCsvDataSet()

advanced_testcase::createCsvDataSet (   $files,
  $delimiter = ',',
  $enclosure = '"',
  $escape = '"' 
)
protectedinherited

Creates a new CsvDataSet from the given array of csv files.

(absolute paths.)

Parameters
array$filesarray tablename=>cvsfile
string$delimiter
string$enclosure
string$escape
Return values
PHPUnit::DbUnit::DataSet::CsvDataSet

◆ createFlatXMLDataSet()

advanced_testcase::createFlatXMLDataSet (   $xmlFile)
protectedinherited

Creates a new FlatXmlDataSet with the given $xmlFile.

(absolute path.)

Parameters
string$xmlFile
Return values
PHPUnit::DbUnit::DataSet::FlatXmlDataSet

◆ createXMLDataSet()

advanced_testcase::createXMLDataSet (   $xmlFile)
protectedinherited

Creates a new XMLDataSet with the given $xmlFile.

(absolute path.)

Parameters
string$xmlFile
Return values
PHPUnit::DbUnit::DataSet::XmlDataSet

◆ findNodes()

static base_testcase::findNodes ( DOMDocument  $dom,
array  $options,
  $isHtml = true 
)
staticinherited

Parse out the options from the tag using DOM object tree.

Parameters
DOMDocument$dom
array$options
bool$isHtml
Return values
array

◆ get_contains_submit_button_expectation()

qbehaviour_walkthrough_test_base::get_contains_submit_button_expectation (   $enabled = null)
protected

Returns an epectation that a string contains the HTML of a button with name {question-attempt prefix}-submit, and eiter enabled or not.

Parameters
bool$enabledif not null, check the enabled/disabled state of the button. True = enabled.
Return values
question_contains_tag_with_attributesan expectation for use with check_current_output.

◆ get_does_not_contain_submit_button_expectation()

qbehaviour_walkthrough_test_base::get_does_not_contain_submit_button_expectation ( )
protected

Returns an epectation that a string does not contain the HTML of a button with name {question-attempt prefix}-submit.

Return values
question_contains_tag_with_attributesan expectation for use with check_current_output.

◆ getDataGenerator()

static advanced_testcase::getDataGenerator ( )
staticinherited

Get data generator.

Return values
testing_data_generator

◆ getDebuggingMessages()

advanced_testcase::getDebuggingMessages ( )
inherited

Return debugging messages from the current test.

Return values
arraywith instances having 'message', 'level' and 'stacktrace' property.

◆ getDescendants()

static base_testcase::getDescendants ( DOMNode  $node)
staticprotectedinherited

Recursively get flat array of all descendants of this node.

Parameters
DOMNode$node
Return values
array

◆ getElementsByCaseInsensitiveTagName()

static base_testcase::getElementsByCaseInsensitiveTagName ( DOMDocument  $dom,
  $tag 
)
staticprotectedinherited

Gets elements by case insensitive tagname.

Parameters
DOMDocument$dom
string$tag
Return values
DOMNodeList

◆ getExternalTestFileUrl()

advanced_testcase::getExternalTestFileUrl (   $path,
  $https = false 
)
inherited

Returns UTL of the external test file.

The result depends on the value of following constants:

  • TEST_EXTERNAL_FILES_HTTP_URL
  • TEST_EXTERNAL_FILES_HTTPS_URL

They should point to standard external test files repository, it defaults to 'http://download.moodle.org/unittest'.

False value means skip tests that require external files.

Parameters
string$path
bool$httpstrue if https required
Return values
stringurl

◆ getNodeText()

static base_testcase::getNodeText ( DOMNode  $node)
staticprotectedinherited

Get the text value of this node's child text node.

Parameters
DOMNode$node
Return values
string

◆ loadDataSet()

advanced_testcase::loadDataSet ( PHPUnit\DbUnit\DataSet\IDataSet  $dataset)
protectedinherited

Load date into moodle database tables from standard PHPUnit data set.

Note: it is usually better to use data generators

Parameters
PHPUnit::DbUnit::DataSet::IDataSet$dataset
Return values
void

◆ preventResetByRollback()

advanced_testcase::preventResetByRollback ( )
inherited

Call this method from test if you want to make sure that the resetting of database is done the slow way without transaction rollback.

This is useful especially when testing stuff that is not compatible with transactions.

Return values
void

◆ recurseFolders()

advanced_testcase::recurseFolders (   $path,
  $callback,
  $fileregexp = '/.*/',
  $exclude = false,
  $ignorefolders = array() 
)
inherited

Recursively visit all the files in the source tree.

Calls the callback function with the pathname of each file found.

Parameters
string$paththe folder to start searching from.
string$callbackthe method of this class to call with the name of each file found.
string$fileregexpa regexp used to filter the search (optional).
bool$excludeIf true, pathnames that match the regexp will be ignored. If false, only files that match the regexp will be included. (default false).
array$ignorefolderswill not go into any of these folders (optional).
Return values
void

◆ redirectEmails()

advanced_testcase::redirectEmails ( )
inherited

Starts email redirection.

You can verify if email were sent or not by inspecting the email array in the returned phpmailer sink instance. The redirection can be stopped by calling $sink->close();

Return values
phpunit_message_sink

◆ redirectEvents()

advanced_testcase::redirectEvents ( )
inherited

Starts event redirection.

You can verify if events were triggered or not by inspecting the events array in the returned event sink instance. The redirection can be stopped by calling $sink->close();

Return values
phpunit_event_sink

◆ redirectMessages()

advanced_testcase::redirectMessages ( )
inherited

Starts message redirection.

You can verify if messages were sent or not by inspecting the messages array in the returned messaging sink instance. The redirection can be stopped by calling $sink->close();

Return values
phpunit_message_sink

◆ resetAfterTest()

advanced_testcase::resetAfterTest (   $reset = true)
inherited

Reset everything after current test.

Parameters
bool$resettrue means reset state back, false means keep all data for the next test, null means reset state and show warnings if anything changed
Return values
void

◆ resetAllData()

static advanced_testcase::resetAllData (   $detectchanges = false)
staticinherited

Reset all database tables, restore global state and clear caches and optionally purge dataroot dir.

Parameters
bool$detectchangestrue - changes in global state and database are reported as errors false - no errors reported null - only critical problems are reported as errors
Return values
void

◆ response_data_to_post()

qbehaviour_walkthrough_test_base::response_data_to_post (   $data)
protected

Convert an array of data destined for one question to the equivalent POST data.

Parameters
array$datathe data for the quetsion.
Return values
arraythe complete post data.

◆ runAdhocTasks()

advanced_testcase::runAdhocTasks (   $matchclass = '',
  $matchuserid = null 
)
protectedinherited

Run adhoc tasks, optionally matching the specified classname.

Parameters
string$matchclassThe name of the class to match on.
int$matchuseridThe userid to match.

◆ runBare()

advanced_testcase::runBare ( )
finalinherited

Runs the bare test sequence.

Return values
void

◆ setAdminUser()

static advanced_testcase::setAdminUser ( )
staticinherited

Set current $USER to admin account, reset access cache.

Return values
void

◆ setCurrentTimeStart()

advanced_testcase::setCurrentTimeStart ( )
inherited

Stores current time as the base for assertTimeCurrent().

Note: this is called automatically before calling individual test methods.

Return values
intcurrent time

◆ setGuestUser()

static advanced_testcase::setGuestUser ( )
staticinherited

Set current $USER to guest account, reset access cache.

Return values
void

◆ setTimezone()

static advanced_testcase::setTimezone (   $servertimezone = 'Australia/Perth',
  $defaultphptimezone = 'Australia/Perth' 
)
staticinherited

Change server and default php timezones.

Parameters
string$servertimezonetimezone to set in $CFG->timezone (not validated)
string$defaultphptimezonetimezone to fake default php timezone (must be valid)

◆ setUser()

static advanced_testcase::setUser (   $user = null)
staticinherited

Set current $USER, reset access cache.

Parameters
null | int | stdClass$useruser record, null or 0 means non-logged-in, positive integer means userid
Return values
void

◆ waitForSecond()

advanced_testcase::waitForSecond ( )
inherited

Wait for a second to roll over, ensures future calls to time() return a different result.

This is implemented instead of sleep() as we do not need to wait a full second. In some cases due to calls we may wait more than sleep() would have, on average it will be less.


The documentation for this class was generated from the following file: