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

如何在基于fixture初始化driver的pytest类中复用Selenium函数?

如何将复用函数整合到基于pytest fixture的Selenium测试类中

我是自动化测试新手,手里有一些Selenium基础函数想复用,但WebDriver是在pytest的fixture里初始化的,不知道怎么把这些函数整合到测试类里。

现有代码

conftest.py

from selenium.webdriver.chrome.options import Options
from selenium import webdriver
import pytest
import pyautogui
import time

@pytest.fixture(scope="class")
def setup(request):
    options = Options()
    options.add_experimental_option("detach", True)  # 注意:这行需在初始化driver前设置
    driver = webdriver.Chrome(options=options)

    request.cls.driver = driver

    url = "你的测试URL"  # 补充实际测试地址
    username = "你的用户名"  # 补充实际账号
    password = "你的密码"  # 补充实际密码
    driver.get(url)
    driver.maximize_window()
    pyautogui.typewrite(username)
    pyautogui.press('tab')
    pyautogui.typewrite(password)
    pyautogui.press('enter')
    time.sleep(3)

    yield

    driver.quit()


@pytest.mark.usefixtures("setup")
class BaseTest:
    pass

test.py

from selenium.webdriver.common.by import By
from conftest import BaseTest

buttonDisplayed = []
buttonNotDisplayed = []
buttonEnabled = []
buttonDisabled = []
clickActionPassed = []

class TestLandingPage(BaseTest):
    def test_profilenav(self):
        profile = self.driver.find_element(by=By.XPATH,
                                      value="/html/body/div[1]/div/div[1]/div[2]/div[3]/div[3]/div[1]/div/a[1]")

        if profile.is_displayed():
            profileDisplayed = "Profile Icon is displayed"
            print(profileDisplayed)
            buttonDisplayed.append(profileDisplayed)
        else:
            profileNotDisplayed = "Profile Icon is not displayed"
            print(profileNotDisplayed)
            buttonNotDisplayed.append(profileNotDisplayed)

        if profile.is_enabled():
            profileEnabled = "Profile button is enabled"
            print(profileEnabled)
            buttonEnabled.append(profileEnabled)
        else:
            profileDisabled = "Profile button is disabled"
            print(profileDisabled)
            buttonDisabled.append(profileDisabled)

        profile.click()
        profileClickAction = "Profile passed"
        print(profileClickAction)
        clickActionPassed.append(profileClickAction)

        # 待调用的复用函数
        # returnToHome()
        # profileIcon()

需要复用的函数

import time
from selenium.webdriver.common.by import By

def returnToHome():
    time.sleep(2)
    logo = driver.find_element(by=By.CSS_SELECTOR, value='[alt="banner"]')
    if logo.is_displayed():
       print("Logo return to home is displayed")
    else:
        print("Logo return to home is not displayed")
    logo.click()
    time.sleep(2)


def profileIcon():
    profileIcon = driver.find_element(by=By.XPATH, value="/html/body/div[1]/div/div[1]/div[2]/div[3]")
    if profileIcon.is_displayed():
        print("Profile Icon button is displayed")
    else:
        print("Profile Icon button is not displayed")
    profileIcon.click()
    print("Profile Icon passed")
    time.sleep(1)

解决方案

方案1:将复用函数转为BaseTest的实例方法

这种方式最贴合现有测试结构,BaseTest已通过fixture获取self.driver,直接集成到基类即可:

1. 修改conftest.py中的BaseTest类

把复用函数改成BaseTest的实例方法,将函数内的driver替换为self.driver:

@pytest.mark.usefixtures("setup")
class BaseTest:
    def return_to_home(self):
        time.sleep(2)
        logo = self.driver.find_element(by=By.CSS_SELECTOR, value='[alt="banner"]')
        if logo.is_displayed():
           print("Logo return to home is displayed")
        else:
            print("Logo return to home is not displayed")
        logo.click()
        time.sleep(2)

    def profile_icon(self):
        profile_icon = self.driver.find_element(by=By.XPATH, value="/html/body/div[1]/div/div[1]/div[2]/div[3]")
        if profile_icon.is_displayed():
            print("Profile Icon button is displayed")
        else:
            print("Profile Icon button is not displayed")
        profile_icon.click()
        print("Profile Icon passed")
        time.sleep(1)

注:函数名改为下划线命名,符合Python PEP8编码规范,也可保留原名称

2. 在测试类中调用方法

由于TestLandingPage继承了BaseTest,直接通过self.方法名()调用即可:

class TestLandingPage(BaseTest):
    def test_profilenav(self):
        # 原有测试逻辑...

        # 调用基类中的复用方法
        self.return_to_home()
        self.profile_icon()

方案2:将driver作为参数传入复用函数

如果希望复用函数保持独立(比如放在单独的工具文件中),可以给函数添加driver参数,调用时传入self.driver:

1. 调整复用函数

import time
from selenium.webdriver.common.by import By

def returnToHome(driver):
    time.sleep(2)
    logo = driver.find_element(by=By.CSS_SELECTOR, value='[alt="banner"]')
    if logo.is_displayed():
       print("Logo return to home is displayed")
    else:
        print("Logo return to home is not displayed")
    logo.click()
    time.sleep(2)


def profileIcon(driver):
    profileIcon = driver.find_element(by=By.XPATH, value="/html/body/div[1]/div/div[1]/div[2]/div[3]")
    if profileIcon.is_displayed():
        print("Profile Icon button is displayed")
    else:
        print("Profile Icon button is not displayed")
    profileIcon.click()
    print("Profile Icon passed")
    time.sleep(1)

2. 在测试类中调用函数

# 先导入复用函数
from your_utils_file import returnToHome, profileIcon

class TestLandingPage(BaseTest):
    def test_profilenav(self):
        # 原有测试逻辑...

        # 传入self.driver调用函数
        returnToHome(self.driver)
        profileIcon(self.driver)

额外提示

  • 原conftest.py中options.add_experimental_option("detach", True)要放在driver = webdriver.Chrome(options=options)之前,否则设置不生效。
  • 避免使用硬编码的绝对XPATH(如/html/body/...),建议改用更稳定的定位方式(如ID、class或相对XPATH)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 20:55:58