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

如何在Python中将Selenium WebDriver实例传递给另一个类

如何在unittest中共享已登录的WebDriver实例给后续测试类

你当前的代码里,DataTableTest和ChartTest直接继承LoginTest,这会导致每个子类都单独执行setUpClass和tearDownClass——也就是每个测试类都会新开Chrome窗口、重新走一遍登录流程,根本没法复用已登录的会话。下面给你两种可行的解决方案:


方案一:重构为共享Driver的基类结构

把Driver的生命周期管理和登录逻辑抽成一个基类,后续所有需要登录状态的测试类都继承这个基类,就能保证整个测试套件只初始化一次Driver、只执行一次登录。

修改后的完整代码:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from dotenv import load_dotenv
import os
import unittest

class BaseTest(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        # 加载环境变量
        load_dotenv()
        # 初始化Chrome Driver(整个测试只执行一次)
        cls.driver = webdriver.Chrome()
        cls.driver.implicitly_wait(10)
        # 提前完成登录,给后续测试类留好已登录会话
        cls.login()

    @classmethod
    def login(cls):
        email = os.getenv("EMAIL")
        password = os.getenv("PASSWORD")
        driver = cls.driver
        
        driver.get("https://website.com/login")
        # 输入账号密码
        email_field = driver.find_element(By.ID, "input_email")
        email_field.send_keys(email)
        password_field = driver.find_element(By.ID, "input_password")
        password_field.send_keys(password)
        # 点击登录按钮
        driver.find_element(By.NAME, "form.submitted").click()
        
        # 修复原代码的登录验证:用显式等待确认登录成功
        WebDriverWait(driver, 10).until(EC.title_contains('Login | Dashboard'))
        assert 'Dashboard' in driver.title, "登录失败,未跳转到仪表盘页面"

    @classmethod
    def tearDownClass(cls):
        # 所有测试完成后关闭浏览器
        cls.driver.quit()

# 需要登录状态的测试类直接继承BaseTest即可
class DataTableTest(BaseTest):
    def test_table_entries(self):
        self.driver.get("https://datatable.com")
        # 这里添加表格相关的测试逻辑,比如断言表格加载完成
        # 示例:self.assertTrue(self.driver.find_element(By.ID, "data_table").is_displayed())

class ChartTest(BaseTest):
    def test_chart(self):
        self.driver.get("https://chart.com")
        # 添加图表相关的测试逻辑,比如检查图表元素是否存在

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

关键改动说明:

  • 把Driver初始化和登录逻辑统一放到BaseTest的类级前置方法里,确保整个测试流程只执行一次。
  • 修复了原代码中无效的登录验证:原代码直接断言EC.title_contains对象,这根本起不到验证作用,改成用WebDriverWait等待标题出现后再做断言。

方案二:用测试套件控制执行顺序(保留原有类结构)

如果你不想大改现有类结构,可以通过自定义测试套件,先执行登录测试,再把已登录的Driver实例传递给后续测试类。

示例代码:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from dotenv import load_dotenv
import os
import unittest

class LoginTest(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        load_dotenv()
        cls.driver = webdriver.Chrome()
        cls.driver.implicitly_wait(10)

    def test_login(self):
        email = os.getenv("EMAIL")
        password = os.getenv("PASSWORD")
        driver = self.driver
        
        driver.get("https://website.com/login")
        email_field = driver.find_element(By.ID, "input_email")
        email_field.send_keys(email)
        password_field = driver.find_element(By.ID, "input_password")
        password_field.send_keys(password)
        driver.find_element(By.NAME, "form.submitted").click()
        
        # 修复登录验证
        WebDriverWait(driver, 10).until(EC.title_contains('Login | Dashboard'))
        self.assertIn('Dashboard', driver.title, "登录失败")

    @classmethod
    def tearDownClass(cls):
        # 暂时不关闭Driver,留给后续测试类使用
        pass

class DataTableTest(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        # 复用LoginTest中已登录的Driver实例
        cls.driver = LoginTest.driver

    def test_table_entries(self):
        self.driver.get("https://datatable.com")
        # 添加表格测试逻辑

    @classmethod
    def tearDownClass(cls):
        # 最后一个测试类负责关闭浏览器
        cls.driver.quit()

class ChartTest(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.driver = LoginTest.driver

    def test_chart(self):
        self.driver.get("https://chart.com")
        # 添加图表测试逻辑

# 自定义测试套件,指定必须先执行登录测试
def suite():
    test_suite = unittest.TestSuite()
    test_suite.addTest(LoginTest('test_login'))
    test_suite.addTest(DataTableTest('test_table_entries'))
    test_suite.addTest(ChartTest('test_chart'))
    return test_suite

if __name__ == "__main__":
    runner = unittest.TextTestRunner()
    runner.run(suite())

注意事项:

  • 必须严格控制测试执行顺序,确保登录测试先跑。
  • 只有最后一个测试类调用driver.quit(),避免提前关闭浏览器导致后续测试失败。

额外提示

  • 尽量用显式等待(WebDriverWait)替代隐式等待,测试逻辑会更稳定可靠。
  • 不要用全局变量管理Driver,单线程测试还好,多线程场景下容易出问题。
  • 虽然共享Driver会让测试之间产生依赖,但对于必须登录才能执行的测试来说,这是合理的折中方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 00:54:55