pytest运行时load_dotenv()未生效最常见原因是未在测试启动前执行,应放在conftest.py顶部显式调用并指定正确路径,同时检查工作目录、覆盖策略及.env语法是否合规。

pytest 运行时 load_dotenv() 没被调用
最常见的情况是:你写了 load_dotenv(),但它没在 pytest 启动流程中执行。pytest 默认不运行你的 main.py 或 app.py 入口文件,而是直接导入测试模块。如果你把 load_dotenv() 写在某个模块顶部(比如 app.py),而测试里只 import 了 app 的某个函数,load_dotenv() 就可能被跳过——尤其当它被包在条件块或函数里时。
解决方法是确保加载逻辑在测试启动前就生效:
- 在
conftest.py文件顶部立即调用load_dotenv()(pytest 会自动加载该文件) - 或者用
pytest-env插件,在pytest.ini中声明变量,避免依赖 Python 层加载 - 不要把
load_dotenv()放在if __name__ == "__main__":里——pytest 不走这个分支
当前工作目录(cwd)不是 .env 所在路径
pytest 默认以你执行命令的目录为 os.getcwd()。比如你在项目根目录下运行 pytest tests/,但 .env 在 src/ 下,load_dotenv() 就会静默失败(返回 False,但不报错)。
验证方式:在 conftest.py 里加一行 print(os.getcwd()),确认是否和 .env 实际位置一致。
立即学习“Python免费学习笔记(深入)”;
稳妥做法是显式传路径:
-
load_dotenv(Path(__file__).parent.parent / ".env")—— 从conftest.py向上找两层到项目根 - 避免用
"../.env"这类相对字符串,某些系统解析不稳定 - 加上
verbose=True和返回值检查:assert load_dotenv(...), "failed to load .env"
pytest 环境变量被系统级变量覆盖
即使 .env 加载成功,os.getenv("DEBUG") 仍可能返回系统已设的值(比如 shell 里 export 过的)。因为 load_dotenv() 默认 override=False,只设置未定义的键。
开发阶段建议强制覆盖:
-
load_dotenv(override=True)—— 让.env的值无条件生效 - 注意:这仅影响当前 Python 进程,不影响子进程或 shell 环境
- 如果用
pytest-env,它默认行为类似override=False;要跳过已有变量,得加前缀D:,如D:DATABASE_URL=...
文件编码或语法错误导致解析失败
python-dotenv 对格式很敏感。以下任一情况都会让某行变量“消失”:
-
.env保存为 UTF-8 with BOM(Windows 记事本默认),会导致首行解析失败 - 用了
export KEY=value(shell 语法,不支持) -
KEY = value中等号前后有空格(必须写成KEY=value) - 值含空格但没加引号:
NAME=John Doe❌ →NAME="John Doe"✅ - 注释写在行尾:
KEY=value # comment❌(只支持整行注释# comment)
建议用 VS Code 或 PyCharm 打开 .env,确认右下角显示 “UTF-8” 且无 BOM,同时关闭“自动插入 export”类插件。
真正容易被忽略的是:pytest 的模块导入顺序和工作目录是两个独立变量,改对一个不一定解决另一个。多数人卡在“以为 load_dotenv() 被执行了”,其实它根本没跑,或者跑在了错误的路径下。


















