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

如何在Python中重新初始化类变量,适配不同版本的Selenium定位器?

问题描述

我用Python结合Selenium编写测试用例,调用Common类中的定位器。

原测试代码

def testPage(driver, url):
    login(driver, url)
    activateProfile(driver, url)

    driver.get(my_url)
    assert_true(driver, *Common.user_lbl)
    assert_true(driver, *Common.pass_lbl)
    # ... 其他测试逻辑

原Common类代码

from collections import namedtuple

class Common():
    locator = namedtuple('Locator', ['elem_type', 'elem_target', 'elem_val'])

    user_lbl = locator("By.ID", "username", "username")
    pass_lbl = locator("By.ID", "password", "password")
    # ... 其他定位器

我希望修改Common类,让user_lbl和pass_lbl的值根据全局变量version确定,但该变量在Common类初始化后才会被确定。理想的类结构如下:

from collections import namedtuple

class Common():
    locator = namedtuple('Locator', ['elem_type', 'elem_target', 'elem_val'])

    if global.version == 5:
        user_lbl = locator("By.ID", "username", "username")
        pass_lbl = locator("By.ID", "password", "password")
    else:
        user_lbl = locator("By.CLASS_NAME", "user", "username")
        pass_lbl = locator("By.CLASS_NAME", "pass", "password")
    # ... 其他定位器

现在需要根据version动态设置这些类变量,请问如何强制Common类重新初始化这些变量?


解决方案

方法1:用类方法动态初始化定位器

将定位器的初始化逻辑封装到类方法中,在version确定后调用该方法更新类属性:

from collections import namedtuple

class Common():
    locator = namedtuple('Locator', ['elem_type', 'elem_target', 'elem_val'])
    # 先定义默认占位属性,后续通过类方法覆盖
    user_lbl = None
    pass_lbl = None

    @classmethod
    def init_locators(cls, version):
        if version == 5:
            cls.user_lbl = cls.locator("By.ID", "username", "username")
            cls.pass_lbl = cls.locator("By.ID", "password", "password")
        else:
            cls.user_lbl = cls.locator("By.CLASS_NAME", "user", "username")
            cls.pass_lbl = cls.locator("By.CLASS_NAME", "pass", "password")
        # ... 其他定位器的初始化逻辑

使用时,先确定version再调用初始化方法:

# 假设此处已确定version的值
version = 5
Common.init_locators(version)

# 后续正常执行测试逻辑
testPage(driver, url)

方法2:改用实例属性,初始化时传入version

如果允许使用类实例而非直接调用类属性,可以将Common改为实例化类,在初始化时传入version:

from collections import namedtuple

class Common():
    def __init__(self, version):
        self.locator = namedtuple('Locator', ['elem_type', 'elem_target', 'elem_val'])
        if version == 5:
            self.user_lbl = self.locator("By.ID", "username", "username")
            self.pass_lbl = self.locator("By.ID", "password", "password")
        else:
            self.user_lbl = self.locator("By.CLASS_NAME", "user", "username")
            self.pass_lbl = self.locator("By.CLASS_NAME", "pass", "password")
        # ... 其他定位器

测试代码需调整为使用实例:

def testPage(driver, url, version):
    login(driver, url)
    activateProfile(driver, url)

    common = Common(version)
    driver.get(my_url)
    assert_true(driver, *common.user_lbl)
    assert_true(driver, *common.pass_lbl)
    # ... 其他测试逻辑

方法3:直接动态修改类属性

如果不想大幅改动原有类结构,可在version确定后直接修改Common类的属性:

from collections import namedtuple

# 确定version的值后执行以下代码
version = 5
locator = namedtuple('Locator', ['elem_type', 'elem_target', 'elem_val'])

if version == 5:
    Common.user_lbl = locator("By.ID", "username", "username")
    Common.pass_lbl = locator("By.ID", "password", "password")
else:
    Common.user_lbl = locator("By.CLASS_NAME", "user", "username")
    Common.pass_lbl = locator("By.CLASS_NAME", "pass", "password")

这种方式无需修改Common类的原有结构,仅需在version确定后执行赋值逻辑即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 00:46:02