AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Moodle Behat Testing

skill-saadrahman01-claude-moodle-dev-moodle-behat-testing · by SaadRahman01

Use when writing or running Behat acceptance tests for Moodle plugins. Covers feature files, custom step definitions, tags, data generators in Background, JavaScript scenarios, and Selenium/Chromedriver setup.

No reviews yet
0 installs
47 views
0.0% view→install

Install

$ agentstack add skill-saadrahman01-claude-moodle-dev-moodle-behat-testing

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-saadrahman01-claude-moodle-dev-moodle-behat-testing)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
3mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Moodle Behat Testing? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Moodle Behat Testing

Overview

Behat drives a real browser against a dedicated Moodle test site. Features live in /tests/behat/*.feature. Custom steps go in tests/behat/behat_.php extending behat_base. Moodle provides hundreds of built-in steps (login, course creation, navigation).

When to Use

  • Writing end-to-end / acceptance tests
  • Testing JavaScript-driven UI (drag-drop, modals, AJAX)
  • Reproducing bugs that need full request cycle + cookies + session
  • Adding scenarios to a plugin's regression suite

Skip when: writing unit tests for business logic — use moodle-phpunit-testing.

First-time setup

# config.php additions:
$CFG->behat_wwwroot   = 'http://localhost:8000';
$CFG->behat_dataroot  = '/var/moodledata_behat';
$CFG->behat_prefix    = 'beh_';

# Initialize test site:
php admin/tool/behat/cli/init.php

# Install + start a Selenium-compatible driver (one of):
docker run -d -p 4444:4444 selenium/standalone-chrome:latest
# or chromedriver, geckodriver

# Run:
vendor/bin/behat --config /var/moodledata_behat/behat/behat.yml \
  --tags @local_example

Feature file skeleton

@local_example @javascript
Feature: Mark attendance
  In order to track presence
  As a teacher
  I need to mark students present

  Background:
    Given the following "courses" exist:
      | fullname | shortname |
      | Maths    | M101      |
    And the following "users" exist:
      | username | firstname | lastname |
      | teacher1 | Tina      | Teach    |
      | student1 | Sam       | Student  |
    And the following "course enrolments" exist:
      | user     | course | role           |
      | teacher1 | M101   | editingteacher |
      | student1 | M101   | student        |

  Scenario: Teacher marks a student present
    Given I log in as "teacher1"
    And I am on "Maths" course homepage
    When I follow "Attendance"
    And I click on "Mark present" "button" in the "Sam Student" "table_row"
    Then I should see "1 present" in the "Today" "fieldset"

Tags:

  • @ — required for --tags filtering
  • @javascript — uses real browser; without it, runs headless (Goutte) — fast but no JS
  • @_file_upload, @_switch_window, @_alert — capability tags so runner can skip on incompatible drivers

Background data generators

Moodle exposes generators as Behat steps via behat_data_generators:

Given the following "local_example > items" exist:
  | course | name        | userid    |
  | M101   | First item  | student1  |

To enable, declare in tests/generator/lib.php AND register in tests/behat/behat_local_example.php:

public function get_creatable_entities(): array {
    return [
        'items' => [
            'singular' => 'item',
            'datagenerator' => 'item',
            'required' => ['name'],
            'switchids' => ['course' => 'courseid', 'user' => 'userid'],
        ],
    ];
}

Generator method:

// in local_example_generator
public function create_item(array $record): \stdClass {
    // same as PHPUnit generator
}

Custom step definitions

tests/behat/behat_local_example.php:

get_plugin_generator('local_example');
        for ($i = 0; $i create_item();
        }
    }

    /**
     * @Then /^the attendance count should be "(\d+)"$/
     */
    public function attendance_count_should_be(int $expected): void {
        global $DB;
        $actual = $DB->count_records('local_example_items');
        if ($actual !== $expected) {
            throw new ExpectationException(
                "Expected $expected, got $actual",
                $this->getSession()
            );
        }
    }
}

Class name must match behat_. After adding/changing steps:

php admin/tool/behat/cli/init.php    # re-scan

Running

# All Behat for plugin
vendor/bin/behat --config $CFG->behat_dataroot/behat/behat.yml --tags @local_example

# Single feature
vendor/bin/behat --config ... tests/behat/mark_attendance.feature

# Single scenario (line number)
vendor/bin/behat --config ... tests/behat/mark_attendance.feature:23

# Parallel (4 runners)
php admin/tool/behat/cli/init.php --parallel=4
vendor/bin/moodle_behat_parallel_run --tags @local_example

Selectors (Mink)

| Type | Example | |------|---------| | link | I follow "Settings" | | button | I press "Save changes" | | field | I set the field "Name" to "X" | | select | I set the field "Role" to "Manager" | | checkbox | I check "Visible" | | table_row | ... in the "Alice" "table_row" | | fieldset | ... in the "General" "fieldset" | | dialogue | ... in the "Confirm" "dialogue" | | css_element | I click on ".foo .bar" "css_element" | | xpath_element | I click on "//button[@data-x='y']" "xpath_element" |

Useful built-in steps

And I am on the "Course 1" "course" page logged in as "teacher1"
And I navigate to "Users > Enrolment methods" in current course administration
And I should see "X" in the "block_settings" "block"
And I wait until the page is ready
And I wait "2" seconds                # avoid; prefer wait-until
And I run the scheduled task "\local_example\task\cleanup"
And I run all adhoc tasks
And the following config values are set as admin:
  | config        | value | plugin        |
  | enabled       | 1     | local_example |

Common Mistakes

| Mistake | Fix | |---------|-----| | Adding step but not running behat/cli/init.php | Re-init after every PHP step change | | Missing @javascript for AJAX UI | Tag scenario @javascript and run with browser driver | | Hard-coded sleeps I wait 5 seconds | Use I wait until ... exists/disappears | | Class name mismatch | Must be behat_ | | Not switching to dialogue context | Add in the "..." "dialogue" selector | | Forgetting capability tags (@_file_upload) | Add so runner can skip on incompatible browsers | | Editing behat.yml directly | Regenerated by init.php — config in config.php instead |

Debugging

# Save HTML+screenshot on failure
$CFG->behat_faildump_path = '/tmp/behat-fails';

# Run a single scenario in foreground browser
vendor/bin/behat --config ... --tags @mytag --stop-on-failure -v

# Pause for inspection
And I should see "this will fail"     # forces a wait you can attach to

CI snippet

- name: Behat
  run: |
    php admin/tool/behat/cli/init.php
    vendor/bin/behat --config $MOODLE_DATA/behat/behat.yml \
      --tags @local_example --format=progress

References

  • Behat in Moodle: https://moodledev.io/general/development/tools/behat
  • Writing tests: https://moodledev.io/general/development/tools/behat/writing
  • Step reference: https://moodledev.io/general/development/tools/behat/writing#step-definitions
  • Data generators: https://moodledev.io/docs/apis/subsystems/testing/generators#behat

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.