Pytest测试类含__init__构造方法报收集警告及后续报错如何解决
问题根源梳理
你遇到的所有报错都是对pytest收集规则、webdriver API使用不熟悉导致的,对应问题如下:
- 初始的收集警告:pytest默认会自动收集名称以Test开头的类作为测试类,但如果类自定义了
__init__构造方法,pytest无法完成自动实例化,就会抛出PytestCollectionWarning警告 - 后续的
TypeError: 'WebDriver' object is not callable:Selenium的WebDriver实例不是可调用对象,打开URL需要调用.get()方法,不能直接写browser(URL) - 补充.get()后的AttributeError:你直接手动实例化
TestCase_AddStar()没有传入依赖参数,且类内部的fixture不会被手动实例化的对象触发加载,导致属性缺失
推荐解决方案(两种可选)
方案1:将TestCase_AddStar作为业务逻辑封装类,不被pytest收集
适合需要统一在test_web.py中调度所有用例的场景,修改点如下:
- 修改
TestCase_AddStar.py,标记类不被pytest收集、修正方法命名和API调用:
from selenium.webdriver.common.by import By from selenium.webdriver.common.alert import Alert from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC class Tags: starSysButton = '//li[button][1]' addStarButton = "//button[contains(text(), 'Add Star')]" starNameField = "//input[1]" modalAddButton = f"(//button[contains(text(), 'Add')])[2]" starPath = f"//td[contains(text(),'Bob')]" modalClose = "//button[@class='btn-close']" class TestCase_AddStar(): # 标记该类不是测试类,禁止pytest收集 __test__ = False URL = 'http://localhost:4200' def __init__(self, browser): self.browser = browser def load(self): # 修正webdriver打开URL的API self.browser.get(self.URL) # 方法名不要以test开头,避免被pytest识别为测试用例 def run_add_star_test(self): starElement = WebDriverWait(self.browser, 10).until(EC.element_to_be_clickable((By.XPATH, Tags.starSysButton))) starElement.click() newStarElement = WebDriverWait(self.browser, 10).until(EC.element_to_be_clickable((By.XPATH, Tags.addStarButton))) newStarElement.click() enterStarName = WebDriverWait(self.browser, 10).until(EC.element_to_be_clickable((By.XPATH, Tags.starNameField))) enterStarName.send_keys("Bob") clickAddButton = WebDriverWait(self.browser, 10).until(EC.element_to_be_clickable((By.XPATH, Tags.modalAddButton))) clickAddButton.click() WebDriverWait(self.browser, 5).until(EC.alert_is_present()) alert = Alert(self.browser) alert.accept() closeModal = WebDriverWait(self.browser, 10).until(EC.element_to_be_clickable((By.XPATH, Tags.modalClose))) closeModal.click() results = WebDriverWait(self.browser, 10).until(EC.presence_of_element_located((By.XPATH, Tags.starPath))) assert results
- 修改
test_web.py,正确调用封装的用例逻辑:
import pytest from TestCases.TestCase_AddStar import TestCase_AddStar from selenium.webdriver import Firefox @pytest.fixture def browser(): driver = Firefox() driver.implicitly_wait(10) yield driver driver.quit() def basic_test(browser): add_star = TestCase_AddStar(browser) add_star.load() add_star.run_add_star_test()
方案2:直接将TestCase_AddStar改造为标准pytest测试类(更推荐)
符合pytest的原生设计,不需要额外的驱动文件,pytest可以自动识别运行所有用例:
- 将
TestCase_AddStar.py重命名为符合pytest收集规则的名称,比如test_add_star.py,修改代码如下:
import pytest from selenium.webdriver.common.by import By from selenium.webdriver.common.alert import Alert from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC class Tags: starSysButton = '//li[button][1]' addStarButton = "//button[contains(text(), 'Add Star')]" starNameField = "//input[1]" modalAddButton = f"(//button[contains(text(), 'Add')])[2]" starPath = f"//td[contains(text(),'Bob')]" modalClose = "//button[@class='btn-close']" # 不需要自定义__init__,fixture会自动注入 class TestAddStar: URL = 'http://localhost:4200' def test_add_star(self, browser): # 打开目标页面 browser.get(self.URL) starElement = WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.XPATH, Tags.starSysButton))) starElement.click() newStarElement = WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.XPATH, Tags.addStarButton))) newStarElement.click() enterStarName = WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.XPATH, Tags.starNameField))) enterStarName.send_keys("Bob") clickAddButton = WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.XPATH, Tags.modalAddButton))) clickAddButton.click() WebDriverWait(browser, 5).until(EC.alert_is_present()) alert = Alert(browser) alert.accept() closeModal = WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.XPATH, Tags.modalClose))) closeModal.click() results = WebDriverWait(browser, 10).until(EC.presence_of_element_located((By.XPATH, Tags.starPath))) assert results
- 直接在项目根目录运行
pytest TestCases/test_add_star.py -v即可执行该用例,不需要保留原来的test_web.py作为驱动,如果你有多个用例文件,pytest会自动全部收集运行。
内容的提问来源于stack exchange,提问作者Trevor
相关产品推荐
相关产品推荐

