如何在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
相关产品推荐
相关产品推荐

