This commit is contained in:
Sara Arjona 2024-07-01 10:42:32 +02:00
commit 606a82b95f
No known key found for this signature in database
6 changed files with 99 additions and 53 deletions

View File

@ -16,12 +16,15 @@
namespace tool_generator\local\testscenario;
use behat_admin;
use behat_data_generators;
use behat_base;
use Behat\Gherkin\Parser;
use Behat\Gherkin\Lexer;
use Behat\Gherkin\Keywords\ArrayKeywords;
use ReflectionClass;
use ReflectionMethod;
use stdClass;
/**
* Class to process a scenario generator file.
@ -72,6 +75,7 @@ class runner {
require_once($CFG->libdir . '/behat/classes/behat_command.php');
require_once($CFG->libdir . '/behat/behat_base.php');
require_once("{$CFG->libdir}/tests/behat/behat_data_generators.php");
require_once("{$CFG->dirroot}/admin/tests/behat/behat_admin.php");
return true;
}
@ -81,6 +85,15 @@ class runner {
private function load_generator() {
$this->generator = new behat_data_generators();
$this->validsteps = $this->scan_generator($this->generator);
// Set config values is not inside the general behat generators.
$extra = $this->scan_method(
new ReflectionMethod(behat_admin::class, 'the_following_config_values_are_set_as_admin'),
new behat_admin(),
);
if ($extra) {
$this->validsteps[$extra->given] = $extra;
}
}
/**
@ -93,14 +106,32 @@ class runner {
$class = new ReflectionClass($generator);
$methods = $class->getMethods(ReflectionMethod::IS_PUBLIC);
foreach ($methods as $method) {
$given = $this->get_method_given($method);
if ($given) {
$result[$given] = $method->getName();
$scan = $this->scan_method($method, $generator);
if ($scan) {
$result[$scan->given] = $scan;
}
}
return $result;
}
/**
* Scan a method to get the given expression tag.
* @param ReflectionMethod $method the method to scan.
* @param behat_base $behatclass the behat class instance to use.
* @return stdClass|null the method data (given, name, class).
*/
private function scan_method(ReflectionMethod $method, behat_base $behatclass): ?stdClass {
$given = $this->get_method_given($method);
if (!$given) {
return null;
}
return (object)[
'given' => $given,
'name' => $method->getName(),
'generator' => $behatclass,
];
}
/**
* Get the given expression tag of a method.
*
@ -146,7 +177,7 @@ class runner {
$result->add_scenario($scenario->getNodeType(), $scenario->getTitle());
$steps = $scenario->getSteps();
foreach ($steps as $step) {
$result->add_step(new steprunner($this->generator, $this->validsteps, $step));
$result->add_step(new steprunner(null, $this->validsteps, $step));
}
}
}

View File

@ -16,7 +16,7 @@
namespace tool_generator\local\testscenario;
use behat_data_generators;
use behat_base;
use Behat\Gherkin\Node\StepNode;
/**
@ -27,8 +27,8 @@ use Behat\Gherkin\Node\StepNode;
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class steprunner {
/** @var behat_data_generators the behat data generator instance. */
private behat_data_generators $generator;
/** @var behat_base|null the behat step class instance. */
private ?behat_base $generator = null;
/** @var array the valid steps indexed by given expression tag. */
private array $validsteps;
@ -53,12 +53,14 @@ class steprunner {
/**
* Constructor.
* @param behat_data_generators $generator the behat data generator instance.
* @param behat_base|null $unused This does nothing, do not use it.
* @param array $validsteps the valid steps indexed by given expression tag.
* @param StepNode $stepnode the step node to process.
*/
public function __construct(behat_data_generators $generator, array $validsteps, StepNode $stepnode) {
$this->generator = $generator;
public function __construct($unused, array $validsteps, StepNode $stepnode) {
if ($unused !== null) {
debugging('Deprecated argument passed to ' . __FUNCTION__, DEBUG_DEVELOPER);
}
$this->validsteps = $validsteps;
$this->stepnode = $stepnode;
$this->init();
@ -73,12 +75,13 @@ class steprunner {
private function init() {
$matches = [];
$linetext = $this->stepnode->getText();
foreach ($this->validsteps as $pattern => $method) {
if (!$this->match_given($pattern, $linetext, $matches)) {
foreach ($this->validsteps as $method) {
if (!$this->match_given($method->given, $linetext, $matches)) {
continue;
}
$this->method = $method;
$this->params = $this->build_method_params($method, $matches);
$this->method = $method->name;
$this->params = $this->build_method_params($method->name, $matches, $method->generator);
$this->generator = $method->generator;
$this->isvalid = true;
return;
}
@ -89,10 +92,11 @@ class steprunner {
* Build the method parameters.
* @param string $methodname the method name.
* @param array $matches the matches.
* @param behat_base $generator the method class.
* @return array the method parameters.
*/
private function build_method_params($methodname, $matches) {
$method = new \ReflectionMethod($this->generator, $methodname);
private function build_method_params(string $methodname, array $matches, behat_base $generator) {
$method = new \ReflectionMethod($generator, $methodname);
$params = [];
foreach ($method->getParameters() as $param) {
$paramname = $param->getName();

View File

@ -21,6 +21,11 @@ Feature: Create testing scenarios using generators
And I should see "Student Test3"
And I should see "Student Test4"
And I should see "Student Test5"
And I set the field "Participants tertiary navigation" to "Enrolment methods"
And I click on "Edit" "link" in the "Manual enrolments" "table_row"
And the field "Send course welcome message" matches value "No"
And I navigate to "Plugins > Enrolments > Manual enrolments" in site administration
And the field "Send course welcome message" matches value "No"
@javascript
Scenario: Prevent creating a testing scenario with no steps to execute

View File

@ -1,6 +1,8 @@
Feature: Prepare scenario for testing
Scenario: Create course content
Given the following "course" exists:
Given the following config values are set as admin:
| sendcoursewelcomemessage | 0 | enrol_manual |
And the following "course" exists:
| fullname | Course test |
| shortname | C1 |
| category | 0 |

View File

@ -46,7 +46,7 @@ class runner_test extends \advanced_testcase {
$feature = $runner->parse_feature($contents);
$this->assertEquals(2, count($feature->get_scenarios()));
$this->assertEquals(6, count($feature->get_all_steps()));
$this->assertEquals(7, count($feature->get_all_steps()));
$this->assertTrue($feature->is_valid());
$result = $runner->execute($feature);

View File

@ -58,6 +58,31 @@ class steprunner_test extends \advanced_testcase {
return $steps[0];
}
/**
* Get the list of valid behat steps for the tests.
* @return array the valid steps details.
*/
private function get_valid_steps(): array {
$generator = new behat_data_generators();
return [
'/^the following "(?P<element_string>(?:[^"]|\\")*)" exist:$/' => (object) [
'name' => 'the_following_entities_exist',
'given' => '/^the following "(?P<element_string>(?:[^"]|\\")*)" exist:$/',
'generator' => $generator,
],
':count :entitytype exist with the following data:' => (object) [
'name' => 'the_following_repeated_entities_exist',
'given' => ':count :entitytype exist with the following data:',
'generator' => $generator,
],
'the following :entitytype exists:' => (object) [
'name' => 'the_following_entity_exists',
'given' => 'the following :entitytype exists:',
'generator' => $generator,
],
];
}
/**
* Test for parse_feature.
* @covers ::is_valid
@ -66,15 +91,9 @@ class steprunner_test extends \advanced_testcase {
* @dataProvider execute_steps_provider
*/
public function test_is_valid(string $step, bool $expected): void {
$generator = new behat_data_generators();
$validsteps = [
'/^the following "(?P<element_string>(?:[^"]|\\")*)" exist:$/' => 'the_following_entities_exist',
':count :entitytype exist with the following data:' => 'the_following_repeated_entities_exist',
'the following :entitytype exists:' => 'the_following_entity_exists',
];
$validsteps = $this->get_valid_steps();
$step = $this->get_step($step);
$steprunner = new steprunner($generator, $validsteps, $step);
$steprunner = new steprunner(null, $validsteps, $step);
$this->assertEquals($expected, $steprunner->is_valid());
}
@ -92,15 +111,10 @@ class steprunner_test extends \advanced_testcase {
$this->resetAfterTest();
$generator = new behat_data_generators();
$validsteps = [
'/^the following "(?P<element_string>(?:[^"]|\\")*)" exist:$/' => 'the_following_entities_exist',
':count :entitytype exist with the following data:' => 'the_following_repeated_entities_exist',
'the following :entitytype exists:' => 'the_following_entity_exists',
];
$validsteps = $this->get_valid_steps();
$step = $this->get_step($step);
$steprunner = new steprunner($generator, $validsteps, $step);
$steprunner = new steprunner(null, $validsteps, $step);
$this->assertFalse($steprunner->is_executed());
@ -163,18 +177,13 @@ class steprunner_test extends \advanced_testcase {
$this->resetAfterTest();
$generator = new behat_data_generators();
$validsteps = [
'/^the following "(?P<element_string>(?:[^"]|\\")*)" exist:$/' => 'the_following_entities_exist',
':count :entitytype exist with the following data:' => 'the_following_repeated_entities_exist',
'the following :entitytype exists:' => 'the_following_entity_exists',
];
$validsteps = $this->get_valid_steps();
$step = $this->get_step('Given the following "course" exists:
| fullname | Course test |
| shortname | C1 |
| category | 0 |');
$steprunner = new steprunner($generator, $validsteps, $step);
$steprunner = new steprunner(null, $validsteps, $step);
$this->assertFalse($steprunner->is_executed());
@ -191,7 +200,7 @@ class steprunner_test extends \advanced_testcase {
);
// Execute the same course creation.
$steprunner = new steprunner($generator, $validsteps, $step);
$steprunner = new steprunner(null, $validsteps, $step);
$this->assertFalse($steprunner->is_executed());
$result = $steprunner->execute();
$this->assertFalse($result);
@ -205,19 +214,14 @@ class steprunner_test extends \advanced_testcase {
* @covers ::get_arguments_string
*/
public function test_get_step_content(): void {
$generator = new behat_data_generators();
$validsteps = [
'/^the following "(?P<element_string>(?:[^"]|\\")*)" exist:$/' => 'the_following_entities_exist',
':count :entitytype exist with the following data:' => 'the_following_repeated_entities_exist',
'the following :entitytype exists:' => 'the_following_entity_exists',
];
$step = $this->get_step('Given the following "course" exists:
| fullname | Course test |
| shortname | C1 |
| category | 0 |
| numsections | 3 |');
$steprunner = new steprunner($generator, $validsteps, $step);
| fullname | Course test |
| shortname | C1 |
| category | 0 |
| numsections | 3 |');
$validsteps = $this->get_valid_steps();
$steprunner = new steprunner(null, $validsteps, $step);
$this->assertEquals(
'the following "course" exists:',