Django博客应用测试:如何实现无Session全局登录用户?
解决方案:在Django API测试中复用全局已认证用户
核心思路
既然不想用Session,那咱们直接基于DRF的Token/JWT认证机制,在测试阶段提前获取用户的认证凭证,然后给测试客户端全局设置该凭证,这样所有API请求都会自动带上认证信息,不用每次都登录。
步骤1:创建全局测试用户与已认证客户端Fixture
用pytest的Fixture(如果用unittest可以改成 setUpClass),把用户创建和认证逻辑抽出来,让整个测试会话复用同一个用户和已认证客户端:
import pytest from django.urls import reverse from your_app.models import CustomUser # 全局测试用户,整个测试会话只创建一次 @pytest.fixture(scope="session") def global_test_user(): user_data = {"username": "test_global", "password": "test_pass_123", "email": "test_global@example.com"} # 创建真实用户(测试环境会自动销毁,不用怕污染数据库) user = CustomUser.objects.create_user(**user_data) # 存原始密码,后续登录用 user.raw_password = user_data["password"] return user # 带认证凭证的客户端,全局复用 @pytest.fixture(scope="session") def authenticated_client(client, global_test_user): # 调用真实登录API获取认证凭证 login_payload = { "username": global_test_user.username, "password": global_test_user.raw_password } response = client.post(reverse("login"), login_payload, format="json") assert response.status_code == 200 # 假设登录接口返回的token字段是"token"(JWT的话可能是"access") auth_token = response.data.get("token") # 给客户端设置全局认证头 client.credentials(HTTP_AUTHORIZATION=f"Token {auth_token}") return client
步骤2:在测试用例中直接复用
不管是创建文章、更新文章还是查看博客,直接用authenticated_client即可,无需再处理登录:
def test_publish_article(authenticated_client): article_data = {"title": "我的第一篇测试博客", "content": "测试内容"} response = authenticated_client.post(reverse("publish_article"), article_data, format="json") assert response.status_code == 201 def test_update_own_article(authenticated_client, test_article): update_data = {"title": "修改后的博客标题"} response = authenticated_client.patch( reverse("update_article", kwargs={"pk": test_article.pk}), update_data, format="json" ) assert response.status_code == 200 assert response.data["title"] == "修改后的博客标题"
优化你当前的登录测试代码
你之前的mock其实没必要(API测试应该验证真实登录流程),改成真实调用的测试:
def test_login_api(client, global_test_user): login_payload = { "username": global_test_user.username, "password": global_test_user.raw_password } response = client.post(reverse("login"), login_payload, format="json") assert response.status_code == 200 assert "token" in response.data # 验证返回认证凭证
注意事项
- 如果用JWT认证,把认证头改成
Bearer {access_token}即可 - Fixture的
scope="session"确保用户和凭证只生成一次,提升测试速度 - 测试环境的数据库是临时的,不用担心数据残留
内容的提问来源于stack exchange,提问作者Yogesh Magarde
相关产品推荐
相关产品推荐

