You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flask单元测试因私钥文件缺失触发FileNotFoundError的解决咨询

问题:Flask单元测试时找不到JWT私钥文件

我正在为一个使用公钥和私钥生成JWT令牌的Flask应用运行单元测试,但执行测试时出现FileNotFoundError,提示找不到私钥文件。

项目结构

project/
│
├── app/
│   ├── __init__.py
│   ├── user.py
│   ├── news.py
│   ├── public_key.pem
│   └── private_key.pem
│
└── tests/
    ├── __init__.py
    └── test_app.py

错误信息

运行测试时收到如下错误:

FileNotFoundError: [Errno 2] No such file or directory: 'private_key.pem'

加载私钥的代码片段

# Load the private key
with open('private_key.pem', 'r') as f:
    private_key = f.read()

终端输出

PS C:\Users\ferre\Projects\Portal-de-Noticias> & c:/Users/ferre/Projects/Portal-de-Noticias/.venv/Scripts/python.exe c:/Users/ferre/Projects/Portal-de-Noticias/backend/user_registration/test_app.py
未找到public_key.pem文件。
Traceback (most recent call last):
  File "c:\Users\ferre\Projects\Portal-de-Noticias\backend\user_registration\test_app.py", line 4, in <module>
    from user import user_bp
  File "c:\Users\ferre\Projects\Portal-de-Noticias\backend\user_registration\user.py", line 54, in <module>     
    with open('private_key.pem', 'r') as f:
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: 'private_key.pem'
PS C:\Users\ferre\Projects\Portal-de-Noticias> 

测试代码

import unittest
from flask import Flask
from flask_cors import CORS
from user import user_bp
from noticias import noticias_bp

class TestApp(unittest.TestCase):
    def setUp(self):
        # Configurar a aplicação Flask para testes
        self.app = Flask(__name__)
        CORS(self.app)
        self.app.secret_key = '2002'
        self.app.register_blueprint(user_bp)
        self.app.register_blueprint(noticias_bp)

        # Configurar o cliente de teste
        self.client = self.app.test_client()

    def test_user_blueprint_registration(self):
        # Verificar se o blueprint do usuário está registrado na aplicação Flask
        self.assertIn('user', self.app.blueprints)

    def test_noticias_blueprint_registration(self):
        # Verificar se o blueprint de notícias está registrado na aplicação Flask
        self.assertIn('noticias', self.app.blueprints)

    def test_user_blueprint_routes(self):
        # Testar se as rotas do blueprint do usuário estão acessíveis
        response = self.client.get('/user/')
        self.assertEqual(response.status_code, 200)

        response = self.client.get('/user/profile')
        self.assertEqual(response.status_code, 200)

    def test_noticias_blueprint_routes(self):
        # Testar se as rotas do blueprint de notícias estão acessíveis
        response = self.client.get('/noticias/')
        self.assertEqual(response.status_code, 200)

        response = self.client.get('/noticias/latest')
        self.assertEqual(response.status_code, 200)

if __name__ == '__main__':
    unittest.main()

我该如何解决这个问题,让单元测试正常运行?是应该直接在测试代码中加入私钥,还是有更好的处理方法?


解决方案

根本原因

问题出在加载密钥时使用了相对路径'private_key.pem',运行单元测试时的工作目录是项目根目录(或tests/目录),而不是app/目录,导致程序找不到密钥文件。

推荐解决方法

方法1:使用基于代码文件的绝对路径(最可靠)

修改user.py中加载密钥的代码,通过__file__获取当前文件所在目录,再拼接密钥文件名,这样无论从哪个目录运行代码,都能准确定位到密钥文件:

import os

# 获取当前文件所在的app目录路径
app_dir = os.path.dirname(__file__)

# 拼接私钥和公钥的绝对路径
private_key_path = os.path.join(app_dir, 'private_key.pem')
public_key_path = os.path.join(app_dir, 'public_key.pem')

# 加载私钥
with open(private_key_path, 'r') as f:
    private_key = f.read()

# 加载公钥同理
with open(public_key_path, 'r') as f:
    public_key = f.read()

这种方法不需要修改测试代码,能解决所有环境下的路径问题,是最推荐的方案。

方法2:配置Flask应用的密钥路径(适合测试隔离)

如果需要将测试环境和生产环境的密钥隔离,可以把密钥路径放到Flask配置中,测试时覆盖配置使用测试密钥:

  1. 在app/__init__.py中添加配置:
from flask import Flask
import os

app = Flask(__name__)
# 配置默认的密钥路径(指向app目录下的文件)
app.config['PRIVATE_KEY_PATH'] = os.path.join(app.root_path, 'private_key.pem')
app.config['PUBLIC_KEY_PATH'] = os.path.join(app.root_path, 'public_key.pem')
  1. 修改user.py中加载密钥的代码,使用配置中的路径:
from flask import current_app

with open(current_app.config['PRIVATE_KEY_PATH'], 'r') as f:
    private_key = f.read()
  1. 在tests/test_app.py的setUp方法中覆盖配置,使用测试目录下的密钥:
import os

def setUp(self):
    self.app = Flask(__name__)
    CORS(self.app)
    self.app.secret_key = '2002'
    
    # 设置测试用的密钥路径(假设tests目录下有test_private_key.pem等文件)
    test_dir = os.path.dirname(__file__)
    self.app.config['PRIVATE_KEY_PATH'] = os.path.join(test_dir, 'test_private_key.pem')
    self.app.config['PUBLIC_KEY_PATH'] = os.path.join(test_dir, 'test_public_key.pem')
    
    self.app.register_blueprint(user_bp)
    self.app.register_blueprint(noticias_bp)
    self.client = self.app.test_client()

这种方法的好处是测试时不会用到生产环境的真实密钥,更安全,也符合测试隔离的最佳实践。

方法3:临时切换工作目录(不推荐)

在测试文件开头切换到app/目录,让相对路径生效,但这种方法不够可靠,不同环境下路径可能有差异:

import os

# 切换到app目录
os.chdir(os.path.join(os.path.dirname(__file__), '../app'))

内容的提问来源于stack exchange,提问作者KauaKing

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 19:13:13