Problem/Motivation
Tests in this module should build their webforms from exported configuration fixtures (under tests/modules/graphql_webform_test/config/install/), not by creating webform entities programmatically — neither Webform::create([...]) nor $storage->create([...]) from the entity type manager. This is a convention the maintainers follow, but nothing documents or enforces it, so a contributor (or an AI assistant) can reintroduce programmatic webform creation and have it pass review by accident.
Exported fixtures are strongly preferred over inline creation for three reasons:
- They are runnable documentation. An exported webform can be imported into a real Drupal site and tried by hand, exactly as a site builder would use it.
- They are a reference for frontend implementers. The exported test form showcases every element type the GraphQL API covers, so a developer building a matching frontend that consumes the API has a concrete, complete example to implement each form element against.
- They survive Webform schema changes. When Webform's config schema changes, a single exported file is updated, rather than many copies of the same YAML hand-inlined across PHP test files.
Programmatically created webforms defeat all three: the ad-hoc form is invisible to a site builder and to frontend implementers, and it drifts from the exported fixtures as Webform evolves.
Proposed resolution
Add a small custom PHP_CodeSniffer sniff that forbids creating webform entities programmatically in test code, and wire it into the module's coding-standards run so it fails CI like any other sniff.
- Add a local sniff (e.g.
GraphQLWebform/Sniffs/Testing/NoProgrammaticWebformCreationSniff.php) that reports an error on the ways a webform entity gets created in code:- a static
create()call on theWebformentity class — both the imported short nameWebform::create()and the fully-qualified\Drupal\webform\Entity\Webform::create(); - a
create()call on the webform entity storage, i.e.->getStorage('webform')->create(...)(the obvious next thing a developer reaches for onceWebform::create()is blocked).
- a static
- Add a local ruleset that registers the sniff's namespace, and reference it from
phpcs.xmlscoped to the test paths (tests/), so production code is unaffected. - Make the error message prescriptive, not just prohibitive. It must tell the developer exactly what to do instead, so they do not simply swap one creation mechanism for another. Something like: "Do not create webforms programmatically in tests. Add or extend an exported webform config fixture under
tests/modules/graphql_webform_test/config/install/and install it; the exported config doubles as documentation and as a reference for frontend implementers." - Document the convention in
AGENTS.mdunder "Test conventions", so the sniff and the prose agree. - Cover the sniff with its own fixture-based test so the detection logic is verifiable.
Remaining tasks
- Add the sniff class (covering
Webform::create()and->getStorage('webform')->create()) and its local ruleset/standard, with a prescriptive error message. - Reference the local standard from
phpcs.xml, scoped totests/. - Document the convention in
AGENTS.md"Test conventions". - Add a sniff test (fixture + expected error map).
- Verify
ddev phpcsstill passes on the current tree (no programmatic webform creation remains in tests) and that the sniff fires on a deliberate violation.
Release notes snippet
Contributor tooling: a coding-standards check now forbids creating webforms programmatically in tests, enforcing that test webforms are built from exported configuration fixtures.
Issue fork graphql_webform-3599835
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #4
pfrenssen