● Here's my [Claude Code's] assessment of the dotenv module's test coverage and a plan for addressing gaps.
Current State
One test file exists: DotenvServiceProviderTest.php with a single test method (testRegister) that covers:
- Fallback to 'prod' when APP_ENV is not set
- Using APP_ENV value when it is set
- Setting dotenv.project_dir parameter
Gaps
DotenvServiceProvider (alter method) — partially covered
The existing test doesn't exercise these branches:
- When dotenv.project_dir is already set on the container (the hasParameter guard on line 21)
- When dotenv.environment is already set on the container (the hasParameter guard on line 31)
- The DrupalFinderComposerRuntime vs DrupalFinder class existence branch (lines 22-28)
- Cleanup of $_ENV['APP_ENV'] when it was originally unset — the test sets it to null but never actually unsets it, so the null-coalesce fallback works by
coincidence rather than testing a truly absent key
These are straightforward unit test additions — extend the existing test class with 2-3 more test methods.
DotenvInitCommand — zero coverage
This is the biggest gap. The init() method has significant branching logic:
- Early return when .env already exists
- Early return when .env.example already exists
- Early return when settings.php doesn't exist
- Happy path: creating .env and .env.example with APP_ENV
- --database-settings option: reading DB connection info and writing to all three files
- --add-loader option: copying load.environment.php, modifying composer.json, running composer dump-autoload
- --add-gitignore option: appending to .gitignore
- Various warning paths when files are missing mid-flow (e.g., composer.json not found)
Testing this command is harder because it does direct filesystem I/O (fopen/fwrite), shells out to composer, and depends on Database::getConnectionInfo().
A unit test would need to either use a temp directory (via vfsStream or sys_get_temp_dir()) or be refactored to inject the filesystem dependency more
testably.
interact method — zero coverage
Lower priority. It's a thin wrapper around Drush IO prompts.
load.environment.php — zero coverage
One-liner that boots Symfony Dotenv. Not worth a dedicated test — it's effectively tested by the module working at all.
Recommended Plan (priority order)
1. Extend DotenvServiceProviderTest — Add tests for the "already set" guard clauses and the DrupalFinder branch. Pure unit tests, no new dependencies
needed. Small effort, closes the remaining gaps on the only class with existing tests.
2. Add DotenvInitCommandTest — Unit test using a temp directory for filesystem operations. Mock Database::getConnectionInfo() and the Drush process
manager. Cover the three early-return paths and the happy path with each option toggled on/off. This is the bulk of the work but covers the most untested
logic.
3. Skip interact and load.environment.php — Not worth the test scaffolding for the value they'd provide.
Issue fork dotenv-3581790
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 #3
benstallings commentedComment #4
dieterholvoet commentedComment #5
dieterholvoet commentedThanks!