Search by

lhabbich / drupal-mock-data-seeder

lotfihabbiche

Drupal development module to generate realistic nested content trees for testing.

Package info

github.com/habbichelotfi/drupal-mock-data-seeder

Type:drupal-module

pkg:composer/lhabbich/drupal-mock-data-seeder

Statistics

Installs: 2

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.0 2026-09-06 12:42 UTC

This package is auto-updated.

Last update: 2026-09-06 18:45:14 UTC


README

Development module for generating realistic Drupal content trees for local development, UI testing, and load testing. It can create or reuse:

  • nodes;
  • nested Paragraphs, when the Paragraphs module is available;
  • taxonomy references and optional terms;
  • media references and optional remote-video media.

This module is intended for non-production environments. It is disabled by default and includes environment, count, and rollback safeguards.

Requirements

  • PHP 8.1 or newer according to composer.json;
  • Drupal 10.3+ or Drupal 11;
  • Composer;
  • Drush for the command-line examples;
  • optional: Paragraphs and Media modules for those entity types.

The current committed composer.lock resolves Drupal 11.4.6, which requires PHP 8.3 or newer. Use PHP 8.3+ with the lock file, or regenerate the lock file under PHP 8.1/8.2 with dependency versions compatible with that runtime.

Installation

From the Drupal project root containing this package:

composer install --no-interaction --prefer-dist
drush en drupal_mock_data_seeder -y
drush cset drupal_mock_data_seeder.settings enabled 1 -y
drush cr

Review the generated configuration before enabling the module in any shared environment. The module's default configuration is in config/install/drupal_mock_data_seeder.settings.yml.

Quick start

Configure an existing content type and enable seeding with the setup assistant:

drush mock:setup

It prompts for an existing type. For scripts, supply the machine name explicitly:

drush mock:setup --profile=default --bundle=page

On an empty site, explicitly request creation of a minimal content type:

drush mock:setup --bundle=article --create-bundle=1

This creates the content type without adding custom fields or a body field. Add those through Drupal's field administration as needed. Setup updates only the selected existing profile's bundle and enables the seeder. It respects the environment block list and does not generate content.

Run a dry-run first. It validates the profile and bundle without saving entities:

drush mock:seed --profile=default --dry-run=1

Generate 20 nodes using the page bundle, three levels of nesting, and French fake data:

drush mock:seed \
  --profile=default \
  --bundle=page \
  --count=20 \
  --depth=3 \
  --locale=fr_FR

Reproducible runs

Pass an integer seed to make Faker and PHP random choices repeatable:

drush mock:seed --profile=default --count=20 --seed=4242

The seed is included in the run result and stored run metadata.

Custom fields

Empty configurable fields on nodes and Paragraphs are now filled for these types: string, string_long, email, telephone, boolean, integer, decimal, float, link, datetime, timestamp, list_string, list_integer, and list_float. One item is generated per field. String length, numeric bounds, decimal precision, static allowed values, date storage format, and internal-only links are taken into account. Existing values and base, computed, and read-only fields are preserved.

Dynamic allowed-value callbacks and unsupported field types are skipped. The existing specialized logic still handles body text, Paragraph title/text fields, taxonomy and media references. Arbitrary formatted-text fields, images, files, and custom module constraints are not automatically handled by this generator.

JSON reports

Use --json=1 for scripts and CI integrations. The report includes the run ID, profile, bundle, requested count, depth, locale, seed, duration, and entity statistics:

drush mock:seed --profile=default --count=10 --json=1

Paragraph field configuration and warnings

All empty writable Paragraph reference fields are populated, including multiple fields on the same node. Generation uses installed Paragraph types permitted by each field's target_bundles and negate settings, and respects field cardinality. An absent or null target list allows all installed types; an empty list allows none (or all when negated). Custom selection plugins may impose additional rules that this configuration-based selection does not evaluate.

The profile's paragraph_types list further restricts those types. An empty or omitted profile list enables automatic discovery; new installations use an empty list by default. Existing installations keep their configured list. To use automatic discovery on an existing site, set this in its active seeder config:

profiles:
  default:
    paragraph_types: []

This fragment shows only the setting to change; preserve the rest of the config. An explicit list with no allowed match produces a warning and skips the field. Root fields use paragraphs_per_node, capped by their cardinality. Required fields receive at least one item when possible. Nested fields receive one child when required; optional nested fields have a 35% chance of receiving one. --depth always limits nesting, including required fields and self-referencing types.

The run report includes a deduplicated warnings array, also displayed in Drush. It identifies empty required configurable fields by entity type, bundle and field name, including fields left empty at the depth limit. Check a simulation with:

drush mock:seed --count=5 --depth=3 --dry-run=1 --json=1

These warnings are advisory, not complete Drupal entity validation, and do not prevent a real run. A dry run saves neither entities nor run metadata; its entity statistics remain zero. Because dry runs do not create missing taxonomy or media, required references to those entities may be reported empty even when a real run could create them.

Diagnostics

Check configuration and runtime prerequisites without creating entities:

drush mock:doctor --profile=default

The diagnostic checks include:

  • whether the seeder is enabled;
  • whether the requested profile exists;
  • whether the target node bundle exists;
  • whether the current environment is blocked by safeguards;
  • whether the system temporary directory is writable.

For automation, request JSON output:

drush mock:doctor --profile=default --json=1

Rollback

Each non-dry run stores the IDs of entities it created. Roll back a specific run with its reported ID:

drush mock:reset --run-id=20260901_102030_abcd1234

The run is recorded before generation and its entity IDs are saved after each successful entity save, including related entities created before their parent. If generation throws an error, the run is marked failed and the error includes the exact reset command. Cleanup is explicit: run that command to delete the recorded entities. Reused entities are not recorded or deleted.

A process interruption leaves the recorded run available for reset. This is a recovery journal, not an atomic transaction: a hard stop between an entity save and its journal update, or a failure inside an entity save hook, may leave an unrecorded entity. Successful reset also clears the last-run pointer when it points to the deleted run.

If the configured safeguard requires a run ID, omitting it fails safely. To roll back the last stored run explicitly:

drush mock:reset --force=1

Safety configuration

The module is disabled by default. Relevant settings are:

  • enabled: explicitly enables seeding;
  • safeguards.max_count: maximum root nodes per run;
  • safeguards.blocked_envs: environment values that block execution;
  • safeguards.env_var_names: environment variables inspected;
  • safeguards.require_run_id_for_reset: requires an explicit rollback ID.

Use --force=1 only when you understand the consequences:

drush mock:seed --profile=default --count=500 --force=1
drush mock:reset --force=1

Development and quality checks

Install development dependencies and run the complete local quality suite:

composer install
composer qa

Individual checks:

composer test:smoke
composer lint
composer analyze
composer test

The service tests can run without a bootstrapped Drupal site:

vendor/bin/phpunit tests/src/Unit

The GitHub Actions workflow runs the smoke test, Drupal coding standards, and PHPStan analysis. Kernel tests require a correctly configured Drupal test environment.

Contributing

See CONTRIBUTING.md before opening a pull request. Behavior changes should include tests and corresponding documentation updates. User-facing changes should be recorded in CHANGELOG.md.

License

This project is released under the MIT License. See LICENSE.