如何解决 PyTest 中的陈旧元素异常
How to work around stale element exception in PyTest
在下面的测试中,我点击了 this link 上的每张卡片并查看标题文本是否匹配。我 运行 进入 StaleElementReferenceException 我的假设是 internships
变量在点击卡片后变得陈旧,即使我使用 self.driver.back()
到 return 到我点击的页面.
是否有解决此类问题的方法?还是我需要为每张卡创建单独的测试?如果是这样,PyTest 是否有一个 built-in 模块可以让我们轻松创建单独的测试?
def test_internship_links(self):
num_title_mismatch = 0
title_mismatches = {}
internships_xpath = (
"//div[@id='related_projects']//div[@class='project-description']/h3"
)
internships = self.driver.find_elements(By.XPATH, internships_xpath)
for internship in internships:
outer_title = internship.text
internship.click()
inner_title = self.driver.find_element(
By.XPATH, "//div[@class='primary']//h1"
).text
if inner_title != outer_title:
num_title_mismatch += 1
title_mismatches[outer_title] = inner_title
self.driver.back()
assert (
num_title_mismatch == 0
), f"\n{num_title_mismatch} title mismatch(es) found:\n{title_mismatches}"
错误回溯:
________________________________________________________________________ TestSearchInterships.test_internship_links ________________________________________________________________________
self = <test_search_internships.TestSearchInterships object at 0x1081bfe90>
def test_internship_links(self):
num_title_mismatch = 0
title_mismatches = {}
internships_xpath = (
"//div[@id='related_projects']//div[@class='project-description']/h3"
)
internships = self.driver.find_elements(By.XPATH, internships_xpath)
for internship in internships:
> outer_title = internship.text
tests/test_search_internships.py:41:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
../../../.local/share/virtualenvs/converge-testing-PXQ7_xev/lib/python3.7/site-packages/selenium/webdriver/remote/webelement.py:81: in text
return self._execute(Command.GET_ELEMENT_TEXT)['value']
../../../.local/share/virtualenvs/converge-testing-PXQ7_xev/lib/python3.7/site-packages/selenium/webdriver/remote/webelement.py:693: in _execute
return self._parent.execute(command, params)
../../../.local/share/virtualenvs/converge-testing-PXQ7_xev/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py:338: in execute
self.error_handler.check_response(response)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
如果页面上的 DOM(文档对象模型)操作暂时导致元素无法访问,则可能会发生此问题。
我可以看到 2 种可能的解决方法来解决您的问题。
1) 您可以再次导航到 link,而不是使用 self.driver.back()
到 return 的页面。例如:driver.get('your_url')
2) 在最终抛出异常之前,您可以尝试在循环中多次访问该元素。您可以查看 Darrel Grainger 的解决方案 here.
如果对我有帮助请点赞=)
计算元素的数量并使用范围而不是遍历元素本身对我来说是个窍门。下面是工作代码。
def test_internship_links(self):
num_title_mismatch, title_mismatches = 0, {}
internships = self.driver.find_elements(
By.XPATH, "//div[@id='related_projects']//a"
)
# xpath is indexed from 1, not 0
for int_num in range(1, len(internships) + 1):
internship_xpath = f"//div[@id='related_projects']//a[{int_num}]//div[@class='project-description']//h3"
internship = self.driver.find_element(By.XPATH, internship_xpath)
outer_title = internship.text
internship.click()
inner_title_xpath = "//div[@class='primary']//h1"
inner_title = self.driver.find_element(By.XPATH, inner_title_xpath).text
if inner_title != outer_title:
num_title_mismatch += 1
title_mismatches[outer_title] = inner_title
self.driver.back()
assert_str = (
f"\n{num_title_mismatch} title mismatch(es) found:\n{title_mismatches}"
)
assert num_title_mismatch == 0, assert_string
在下面的测试中,我点击了 this link 上的每张卡片并查看标题文本是否匹配。我 运行 进入 StaleElementReferenceException 我的假设是 internships
变量在点击卡片后变得陈旧,即使我使用 self.driver.back()
到 return 到我点击的页面.
是否有解决此类问题的方法?还是我需要为每张卡创建单独的测试?如果是这样,PyTest 是否有一个 built-in 模块可以让我们轻松创建单独的测试?
def test_internship_links(self):
num_title_mismatch = 0
title_mismatches = {}
internships_xpath = (
"//div[@id='related_projects']//div[@class='project-description']/h3"
)
internships = self.driver.find_elements(By.XPATH, internships_xpath)
for internship in internships:
outer_title = internship.text
internship.click()
inner_title = self.driver.find_element(
By.XPATH, "//div[@class='primary']//h1"
).text
if inner_title != outer_title:
num_title_mismatch += 1
title_mismatches[outer_title] = inner_title
self.driver.back()
assert (
num_title_mismatch == 0
), f"\n{num_title_mismatch} title mismatch(es) found:\n{title_mismatches}"
错误回溯:
________________________________________________________________________ TestSearchInterships.test_internship_links ________________________________________________________________________
self = <test_search_internships.TestSearchInterships object at 0x1081bfe90>
def test_internship_links(self):
num_title_mismatch = 0
title_mismatches = {}
internships_xpath = (
"//div[@id='related_projects']//div[@class='project-description']/h3"
)
internships = self.driver.find_elements(By.XPATH, internships_xpath)
for internship in internships:
> outer_title = internship.text
tests/test_search_internships.py:41:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
../../../.local/share/virtualenvs/converge-testing-PXQ7_xev/lib/python3.7/site-packages/selenium/webdriver/remote/webelement.py:81: in text
return self._execute(Command.GET_ELEMENT_TEXT)['value']
../../../.local/share/virtualenvs/converge-testing-PXQ7_xev/lib/python3.7/site-packages/selenium/webdriver/remote/webelement.py:693: in _execute
return self._parent.execute(command, params)
../../../.local/share/virtualenvs/converge-testing-PXQ7_xev/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py:338: in execute
self.error_handler.check_response(response)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
如果页面上的 DOM(文档对象模型)操作暂时导致元素无法访问,则可能会发生此问题。
我可以看到 2 种可能的解决方法来解决您的问题。
1) 您可以再次导航到 link,而不是使用 self.driver.back()
到 return 的页面。例如:driver.get('your_url')
2) 在最终抛出异常之前,您可以尝试在循环中多次访问该元素。您可以查看 Darrel Grainger 的解决方案 here.
如果对我有帮助请点赞=)
计算元素的数量并使用范围而不是遍历元素本身对我来说是个窍门。下面是工作代码。
def test_internship_links(self):
num_title_mismatch, title_mismatches = 0, {}
internships = self.driver.find_elements(
By.XPATH, "//div[@id='related_projects']//a"
)
# xpath is indexed from 1, not 0
for int_num in range(1, len(internships) + 1):
internship_xpath = f"//div[@id='related_projects']//a[{int_num}]//div[@class='project-description']//h3"
internship = self.driver.find_element(By.XPATH, internship_xpath)
outer_title = internship.text
internship.click()
inner_title_xpath = "//div[@class='primary']//h1"
inner_title = self.driver.find_element(By.XPATH, inner_title_xpath).text
if inner_title != outer_title:
num_title_mismatch += 1
title_mismatches[outer_title] = inner_title
self.driver.back()
assert_str = (
f"\n{num_title_mismatch} title mismatch(es) found:\n{title_mismatches}"
)
assert num_title_mismatch == 0, assert_string