Summary
When tests are run from VS Code Test Explorer, using deno.testing.args with --env-file does not behave the same as running deno test manually from CLI.
CLI loads env vars correctly, but Test Explorer can run with env vars unset, even when logs suggest equivalent args.
I expected that Test Explorer and CLI should have equivalent behavior for env loading when using the same test args, especially --env-file.
Whilst this bug is most easily reproduced using the vscode extension, I believe the bug actually exists within the language server.
Related issue on the vscode extension:
denoland/vscode_deno#1317
Example Scenario
Short test file
import { assertEquals } from "jsr:@std/assert/equals";
Deno.test("prints env markers for diagnosis", () => {
const myVar = Deno.env.get("MYVAR") ?? "<unset>";
const source = Deno.env.get("SOURCE") ?? "<unset>";
console.log(`MYVAR=${myVar}`);
console.log(`SOURCE=${source}`);
// This expectation should pass only when test-run env loading is correct.
assertEquals(myVar, "from_test_arg");
});
Our environment file, called env.test.args.env
MYVAR=from_test_arg
SOURCE=test_args_env_file
SCENARIO A, CLI run (Expected: pass, Currently: pass)
deno test --allow-env --no-check --env-file=env.test.args.env
This gives us:
running 1 test from ./env_loading_test.ts
prints env markers for diagnosis ...
------- output -------
MYVAR=from_test_arg
SOURCE=test_args_env_file
----- output end -----
prints env markers for diagnosis ... ok (0ms)
ok | 1 passed | 0 failed (7ms)
This is what we expect, vars are loaded from the named environment we are pointing to in our test command.
SCENARIO B, Test Explorer run (Expected: pass, Currently: fail)
Our .vscode/settings.json
{
"deno.enable": true,
"deno.testing.args": [
"--allow-env",
"--no-check",
"--env-file=env.test.args.env"
]
}
Now we run using the test explorer, and the test fails. The environment variables are now unset!
SCENARIO C, Test Explorer run, but with a preloaded env. (Expected: pass, Currently: pass)
Our new .vscode/settings.json
{
"deno.enable": true,
"deno.envFile": "env.test.args.env",
"deno.testing.args": [
"--allow-env",
"--no-check",
"--env-file=env.test.args.env"
]
}
Now, we run again using the test explorer, and the test passes. The environment variables are now loading again.
Expected behaviour
I would expect that all scenarios, A, B, and C should pass.
Why this is a problem beyond the VSCode extension
In both scenario B and C, in the output log from the Deno Language Server we see
2026-04-15 14:32:38.987 [error] Executing test run with arguments: deno test --allow-env --no-check --env-file=env.test.args.env --trace-leaks
This to me suggests argument reconstruction includes --env-file, but does not prove env-file was actually loaded with CLI-equivalent semantics.
For context, I did also try scenario B with an absolute file path to the env file, with the exact same outcome.
I believe this will affect any extensions or integrations trying to run tests via an LSP request, which I will explain in my attempt at a diagnosis.
My diagnosis
The VSC test explorer sends a LSP request, deno/testRun to run tests like we do with the CLI. The request shape defined in cli/lsp/testing/lsp_custom.rs . This request shape does not include a raw argv list, cwd, or any env vars. This means the server has to reconstruct the execution context itself, which is where the divergence from the CLI behaviour occurs.
The CLI scenario succeeds, as it takes a different execution path which explicity loads env files, cli/lib.rs.
Test Explorer uses deno/testRun, handled here:
cli/lsp/language_server.rs
That calls the testing server with workspace settings, then execution happens in:
cli/lsp/testing/execution.rs
In this path, args are rebuilt from settings (get_args) and then interpreted in the LSP process context. If this path does not mirror CLI env loading and cwd resolution exactly, --env-file can appear in logs but variables can still be missing at runtime.
Scenario C masks the bug in Scenario B, as I am assuming this is injecting the env file at language server startup.
Fixed when
For the same test args and env file, Test Explorer runs and CLI runs should resolve and load env-file consistently.
PS: This also raises the question when the bug is fixed, with multiple env files, should deno test, or the existing env file 'win'?
Version: deno 2.7.12 (release, x86_64-pc-windows-msvc) | vscode_deno 3.52.0 | vscode 1.115.0
Summary
When tests are run from VS Code Test Explorer, using deno.testing.args with --env-file does not behave the same as running deno test manually from CLI.
CLI loads env vars correctly, but Test Explorer can run with env vars unset, even when logs suggest equivalent args.
I expected that Test Explorer and CLI should have equivalent behavior for env loading when using the same test args, especially --env-file.
Whilst this bug is most easily reproduced using the vscode extension, I believe the bug actually exists within the language server.
Related issue on the vscode extension:
denoland/vscode_deno#1317
Example Scenario
Short test file
Our environment file, called env.test.args.env
SCENARIO A, CLI run (Expected: pass, Currently: pass)
deno test --allow-env --no-check --env-file=env.test.args.envThis gives us:
This is what we expect, vars are loaded from the named environment we are pointing to in our test command.
SCENARIO B, Test Explorer run (Expected: pass, Currently: fail)
Our .vscode/settings.json
Now we run using the test explorer, and the test fails. The environment variables are now unset!
SCENARIO C, Test Explorer run, but with a preloaded env. (Expected: pass, Currently: pass)
Our new .vscode/settings.json
Now, we run again using the test explorer, and the test passes. The environment variables are now loading again.
Expected behaviour
I would expect that all scenarios, A, B, and C should pass.
Why this is a problem beyond the VSCode extension
In both scenario B and C, in the output log from the Deno Language Server we see
This to me suggests argument reconstruction includes --env-file, but does not prove env-file was actually loaded with CLI-equivalent semantics.
For context, I did also try scenario B with an absolute file path to the env file, with the exact same outcome.
I believe this will affect any extensions or integrations trying to run tests via an LSP request, which I will explain in my attempt at a diagnosis.
My diagnosis
The VSC test explorer sends a LSP request, deno/testRun to run tests like we do with the CLI. The request shape defined in
cli/lsp/testing/lsp_custom.rs. This request shape does not include a raw argv list, cwd, or any env vars. This means the server has to reconstruct the execution context itself, which is where the divergence from the CLI behaviour occurs.The CLI scenario succeeds, as it takes a different execution path which explicity loads env files,
cli/lib.rs.Test Explorer uses
deno/testRun, handled here:cli/lsp/language_server.rsThat calls the testing server with workspace settings, then execution happens in:
cli/lsp/testing/execution.rsIn this path, args are rebuilt from settings (
get_args) and then interpreted in the LSP process context. If this path does not mirror CLI env loading and cwd resolution exactly,--env-filecan appear in logs but variables can still be missing at runtime.Scenario C masks the bug in Scenario B, as I am assuming this is injecting the env file at language server startup.
Fixed when
For the same test args and env file, Test Explorer runs and CLI runs should resolve and load env-file consistently.
PS: This also raises the question when the bug is fixed, with multiple env files, should deno test, or the existing env file 'win'?
Version: deno 2.7.12 (release, x86_64-pc-windows-msvc) | vscode_deno 3.52.0 | vscode 1.115.0