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

在Pytest框架中使用Python Selenium实现登录测试动态凭证持久化

解决方案:全局复用生成的登录凭证

问题根源

  1. 当前Helper类在定义阶段就直接生成随机凭证,每次导入Helper类(比如不同测试套件导入时)都会重新生成新值,导致凭证不断变化。
  2. 缺少凭证初始化的判断逻辑,无法确保只生成一次凭证。

修复后的Helper类

修正语法错误,调整凭证生成逻辑,确保仅在需要时生成并持久化:

import uuid

class Helper:
    # 初始化类变量为None,标记未生成状态
    user_name = None
    user_email = None
    user_password = None
    USER_INFO_FILE = 'user_name_info.txt'

    @classmethod
    def generate_and_save_user_info(cls):
        # 仅当凭证未生成时才生成新值
        if cls.user_name is None:
            random_mail = f'tester{str(uuid.uuid4())[:5]}@example.com'  # 补全邮箱后缀,避免split报错
            cls.user_name = random_mail.split("@")[0]
            cls.user_email = random_mail
            cls.user_password = f'Pa#{str(uuid.uuid4())[:10]}'
            # 保存到文件,作为备用复用方案
            cls.create_user_info_file()
        return cls.get_user_info()

    @classmethod
    def create_user_info_file(cls):
        with open(cls.USER_INFO_FILE, 'w') as file:
            file.write(f'{cls.user_name}\n{cls.user_email}\n{cls.user_password}')

    @classmethod
    def read_user_info_file(cls):
        # 从文件读取,用于测试重启后的复用(可选)
        try:
            with open(cls.USER_INFO_FILE, 'r') as file:
                lines = file.readlines()
                cls.user_name = lines[0].strip()
                cls.user_email = lines[1].strip()
                cls.user_password = lines[2].strip()
            return cls.get_user_info()
        except FileNotFoundError:
            # 文件不存在则生成新凭证
            return cls.generate_and_save_user_info()

    @classmethod
    def get_user_info(cls):
        return {
            'user_name': cls.user_name,
            'user_email': cls.user_email,
            'user_password': cls.user_password
        }

用Pytest Fixture全局管理凭证和登录状态

在conftest.py中定义会话级别的fixture,确保凭证只生成一次,所有测试复用:

import pytest
from selenium import webdriver
from your_module import Helper  # 替换为你的Helper类所在模块

@pytest.fixture(scope="session")
def user_credentials():
    # 优先从类变量获取,无则生成/读取
    if Helper.user_name is None:
        Helper.generate_and_save_user_info()
    return Helper.get_user_info()

@pytest.fixture(scope="session")
def logged_in_driver(user_credentials):
    driver = webdriver.Chrome()  # 根据你的浏览器配置调整
    # 执行登录逻辑
    driver.get("your_login_page_url")
    driver.find_element("id", "username").send_keys(user_credentials['user_name'])
    driver.find_element("id", "password").send_keys(user_credentials['user_password'])
    driver.find_element("id", "login-btn").click()
    # 等待登录完成(可根据实际情况添加显式等待)
    yield driver
    # 测试结束后关闭浏览器
    driver.quit()

测试用例写法

test_suit_01/test_01.py(第一个测试,触发凭证生成)

from your_module import Helper

def test_01_generate_credentials_and_login(logged_in_driver):
    # logged_in_driver fixture会自动触发凭证生成和登录
    # 这里可添加登录后的验证逻辑,比如检查用户名是否显示
    assert logged_in_driver.find_element("id", "current-user").text == Helper.user_name

其他测试套件(比如test_suit_02/test_02.py)

def test_02_user_profile(logged_in_driver, user_credentials):
    # 直接使用已登录的driver和全局凭证
    logged_in_driver.get("your_profile_page_url")
    assert logged_in_driver.find_element("id", "profile-email").text == user_credentials['user_email']

关键说明

  1. 会话级Fixture:scope="session"确保user_credentials和logged_in_driver在整个pytest会话中只执行一次,所有测试复用同一个凭证和登录状态。
  2. 类变量判断:Helper类中通过if cls.user_name is None确保凭证仅生成一次,避免重复覆盖。
  3. 文件持久化:可选保留文件读写逻辑,用于测试会话重启后复用同一凭证(如果需要)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 03:52:45