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

使用Python unittest执行Selenium用例时出现no such session错误求解决

解决unittest + Selenium 遇到的「no such session」错误

嗨,我来帮你排查并解决这个问题。先拆解下问题根源,再给你两种可行的修复方案:

问题根源拆解

你的代码触发这个错误,核心是没摸透unittest框架的执行逻辑:

  • 每个test_开头的方法都是独立测试用例:unittest会把所有以test_命名的方法当作单独的测试用例执行,而且每个用例执行完毕后都会调用tearDown()方法。你的test_globe执行完后,tearDown()直接关闭了浏览器driver,后面的test_login、test_home再调用driver时,会话已经不存在了。
  • 全局变量driver的误用:用global管理WebDriver实例完全不适合unittest,因为每个测试用例的实例是相互隔离的,而且测试方法的执行顺序不一定是你写的顺序(unittest默认按方法名的ASCII码排序),搞不好test_login会先于test_globe执行,直接导致driver未初始化就报错。
  • 初始化方法用错了地方:把driver的初始化放在test_globe这个测试方法里不合理,unittest专门提供了setUp()(每个用例执行前跑一次)和setUpClass()(整个测试类只跑一次)来做初始化操作。

修复方案

方案1:每个测试用例用独立的浏览器实例

适合测试用例之间没有依赖的场景,每个用例都会打开新浏览器,执行完就关闭:

import unittest
from selenium import webdriver
from selenium.webdriver.common.keys import Keys

class KenLogin(unittest.TestCase):
    def setUp(self):
        # 每个测试用例执行前初始化driver
        self.driver = webdriver.Chrome(executable_path='E:\Learning\chromedriver.exe')
        self.driver.maximize_window()
        self.driver.implicitly_wait(10)  # 注意:这里参数是秒!你之前写2000是2000秒,这明显不对

    def test_login(self):
        self.driver.get("http://qa.kenzen.com")
        username = self.driver.find_element_by_xpath("/html/body/div[1]/div/div[2]/div/div[2]/form/div[1]/input")
        password = self.driver.find_element_by_xpath("/html/body/div[1]/div/div[2]/div/div[2]/form/div[2]/input")
        username.send_keys("pardeepk@clovity.com")
        password.send_keys("Kenzen@123")
        button = self.driver.find_element_by_xpath("/html/body/div[1]/div/div[2]/div/div[2]/form/button")
        button.send_keys(Keys.ENTER)
        print("Login Pass")

    def test_home(self):
        # 因为是独立实例,所以需要先完成登录操作
        self.driver.get("http://qa.kenzen.com")
        # 复用登录代码
        username = self.driver.find_element_by_xpath("/html/body/div[1]/div/div[2]/div/div[2]/form/div[1]/input")
        password = self.driver.find_element_by_xpath("/html/body/div[1]/div/div[2]/div/div[2]/form/div[2]/input")
        username.send_keys("pardeepk@clovity.com")
        password.send_keys("Kenzen@123")
        self.driver.find_element_by_xpath("/html/body/div[1]/div/div[2]/div/div[2]/form/button").send_keys(Keys.ENTER)
        
        teamsummary = self.driver.find_element_by_id("teamsummary")
        teamsummary.click()
        print("Home Pass")

    def test_newteam(self):
        # 同样需要先登录
        self.driver.get("http://qa.kenzen.com")
        username = self.driver.find_element_by_xpath("/html/body/div[1]/div/div[2]/div/div[2]/form/div[1]/input")
        password = self.driver.find_element_by_xpath("/html/body/div[1]/div/div[2]/div/div[2]/form/div[2]/input")
        username.send_keys("pardeepk@clovity.com")
        password.send_keys("Kenzen@123")
        self.driver.find_element_by_xpath("/html/body/div[1]/div/div[2]/div/div[2]/form/button").send_keys(Keys.ENTER)
        
        addteam = self.driver.find_element_by_xpath("/html/body/div[1]/div/div[2]/div/div/div[1]/ul[2]/li/button")
        addteam.click()
        teamname = self.driver.find_element_by_xpath("/html/body/div[1]/div/div[2]/div/div/div[2]/div/div[1]/input")
        admin = self.driver.find_element_by_id("administrator")
        admin.send_keys("qa@kenzen.com,qa1@kenzen.com")
        addteambutton = self.driver.find_element_by_xpath("/html/body/div[1]/div/div[2]/div/div/div[2]/div/div[6]/button")
        addteambutton.click()
        print("Team Added")

    def tearDown(self):
        # 每个用例执行后关闭浏览器,quit()比close()更彻底,会销毁整个会话
        self.driver.quit()

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

方案2:所有测试用例共享同一个浏览器实例

如果你的测试用例是有依赖顺序的(比如必须先登录,再操作首页,再创建团队),用这个方案,整个测试类只初始化一次浏览器:

import unittest
from selenium import webdriver
from selenium.webdriver.common.keys import Keys

class KenLogin(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        # 整个测试类执行前只初始化一次driver
        cls.driver = webdriver.Chrome(executable_path='E:\Learning\chromedriver.exe')
        cls.driver.maximize_window()
        cls.driver.implicitly_wait(10)  # 修正为秒级参数

    def test_login(self):
        self.driver.get("http://qa.kenzen.com")
        username = self.driver.find_element_by_xpath("/html/body/div[1]/div/div[2]/div/div[2]/form/div[1]/input")
        password = self.driver.find_element_by_xpath("/html/body/div[1]/div/div[2]/div/div[2]/form/div[2]/input")
        username.send_keys("pardeepk@clovity.com")
        password.send_keys("Kenzen@123")
        button = self.driver.find_element_by_xpath("/html/body/div[1]/div/div[2]/div/div[2]/form/button")
        button.send_keys(Keys.ENTER)
        print("Login Pass")

    def test_home(self):
        # 直接复用之前的登录会话
        teamsummary = self.driver.find_element_by_id("teamsummary")
        teamsummary.click()
        print("Home Pass")

    def test_newteam(self):
        # 继续复用会话
        addteam = self.driver.find_element_by_xpath("/html/body/div[1]/div/div[2]/div/div/div[1]/ul[2]/li/button")
        addteam.click()
        teamname = self.driver.find_element_by_xpath("/html/body/div[1]/div/div[2]/div/div/div[2]/div/div[1]/input")
        admin = self.driver.find_element_by_id("administrator")
        admin.send_keys("qa@kenzen.com,qa1@kenzen.com")
        addteambutton = self.driver.find_element_by_xpath("/html/body/div[1]/div/div[2]/div/div/div[2]/div/div[6]/button")
        addteambutton.click()
        print("Team Added")

    @classmethod
    def tearDownClass(cls):
        # 整个测试类执行完后再关闭浏览器
        cls.driver.quit()

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

额外要注意的细节

  • implicitly_wait的参数:你之前写的2000是错误的,这个方法接收的是秒数,不是毫秒!2000秒等于30多分钟,会导致测试无意义地等待很久,改成10秒左右就合适。
  • 测试方法的执行顺序:unittest默认会按方法名的ASCII码排序执行,如果你需要严格按登录→首页→创建团队的顺序执行,可以把方法名改成test_01_login、test_02_home、test_03_newteam,或者用第三方库unittest-ordering来指定顺序。
  • 尽量不用全局变量:在unittest里,用实例变量(self.driver)或类变量(cls.driver)管理WebDriver是更规范的做法,能避免会话混乱的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:47:04