软件测试元素定位

#用CV工程师的方式逃离CV#从开发到测试的文明退化史

1. ID元素定位

  • 基于元素属性中唯一的id值定位(动态ID除外),是首选定位方式
driver.find_element_by_id('id')
driver.find_element(By.ID, 'id')

2. name元素定位

  • 基于元素属性中的name值定位(可能出现重名)
driver.find_element_by_name('name')
driver.find_element(By.NAME, 'name')

3. class_name元素定位

  • 基于元素class样式定位(易重复)
  • 参数只能是一个class值(多个class需选其一)
driver.find_element_by_class_name('class_name')
driver.find_element(By.CLASS_NAME, 'class_name')

4. tag_name元素定位

  • 通过元素标签名定位(重复度高,需二次筛选)
driver.find_element_by_tag_name('tag_name')
driver.find_element(By.TAG_NAME, 'tag_name')

5. css_selector元素定位

  • 支持多种定位方式:id/class/属性/子元素/后代元素/index/兄弟元素等

5.1 通过ID定位

driver.find_element_by_css_selector('div#kw')
driver.find_element(By.CSS_SELECTOR, 'div#kw')

5.2 通过class定位

driver.find_element_by_css_selector('input.is_put')
driver.find_element(By.CSS_SELECTOR, 'input.is_put')

5.3 通过属性定位

driver.find_element_by_css_selector('input[name=kw]')
driver.find_element(By.CSS_SELECTOR, 'input[name=kw]')

5.4 通过子元素定位

  • CSS使用 > 表示子元素
driver.find_element_by_css_selector('div#kw > input')
driver.find_element(By.CSS_SELECTOR, 'div#kw > input')

5.5 通过后代元素定位

driver.find_element_by_css_selector('div#kw input')
driver.find_element(By.CSS_SELECTOR, 'div#kw input')

5.6 通过index定位

driver.find_element_by_css_selector('div#kw > input:nth-child(1)')
driver.find_element(By.CSS_SELECTOR, 'div#kw > input:nth-child(1)')

5.7 通过兄弟元素定位

  • 仅定位下方第一个兄弟元素
driver.find_element_by_css_selector('span#kw + input')
driver.find_element(By.CSS_SELECTOR, 'span#kw + input')

5.8 CSS常见语法一览表

语法 说明 示例
* 通用元素选择器 *
E 标签选择器 input
.info class选择器 .is_put
#footer id选择器 #kw
E,F 多元素选择器 div, span
E F 后代元素选择器 div input
E > F 子元素选择器 div > input
E + F 毗邻元素选择器(第一个兄弟) span + input
E ~ F 同级元素选择器(所有后续兄弟) span ~ input
E[att='val'] 属性精确匹配 input[name='kw']
E[att^='val'] 属性值开头匹配 a[href^='https']
E[att$='val'] 属性值结尾匹配 img[src$='.png']
E[att*='val'] 属性值包含匹配 div[class*='nav']
E:contains() 内容包含匹配 p:contains('Hello')
E:not(s) 反向选择器 input:not([disabled])

6. link_text元素定位

  • 基于超链接的完整文本定位(仅限<a>标签)
driver.find_element_by_link_text('link_text')
driver.find_element(By.LINK_TEXT, 'link_text')

7. partial_link_text元素定位

  • 基于超链接的部分文本模糊匹配(仅限<a>标签)
driver.find_element_by_partial_link_text('part_text')
driver.find_element(By.PARTIAL_LINK_TEXT, 'part_text')

8. xpath元素定位

  • 通过XML路径语法定位HTML元素

8.1 绝对路径定位(不推荐)

driver.find_element_by_xpath('/html/body/div[4]/div[1]/a')
driver.find_element(By.XPATH, '/html/body/div[4]/div[1]/a')

8.2 相对路径定位

driver.find_element_by_xpath('//form/span')
driver.find_element(By.XPATH, '//form/span')

8.3 元素属性定位

单属性:

driver.find_element_by_xpath("//input[@name='pwd']")
driver.find_element(By.XPATH, "//input[@name='pwd']")

多属性:

driver.find_element_by_xpath("//a[@title='tutorial' and @rel='follow']")
driver.find_element(By.XPATH, "//a[@title='tutorial' and @rel='follow']")

8.4 属性模糊匹配

starts-with:

driver.find_element_by_xpath("//label[starts-with(@class,'btn')]")
driver.find_element(By.XPATH, "//label[starts-with(@class,'btn')]")

contains:

driver.find_element_by_xpath("//label[contains(@class,'btn')]")
driver.find_element(By.XPATH, "//label[contains(@class,'btn')]")

8.5 文本定位

精确匹配:

driver.find_element_by_xpath("//span[text()='下一步']")
driver.find_element(By.XPATH, "//span[text()='下一步']")

模糊匹配:

driver.find_element(By.XPATH, "//span[starts-with(text(),'下一步')]")
driver.find_element(By.XPATH, "//span[contains(text(),'下一步')]")

8.6 xpath常见语法

表达式 说明 示例
/ 从根节点开始 /html/div
// 从任意节点开始 //input
. 当前节点 //input/.
.. 父节点 //input/..
@ 属性选择 //input[@name]
* 通配符 //div/*

9. XPATH 和 CSS 基本语法对比

功能 CSS3 语法 XPATH 语法
所有元素 * //*
所有p元素 p //p
所有p元素的子元素 p > * //p/*
根据ID获取元素 #id //*[@id='id']
根据Class获取元素 .class //*[contains(@class,'class')]
拥有某个属性的元素 *[title] //*[@title]
所有p元素的第一个子元素 p > *:first-child //p/*[1]
所有拥有子元素的p元素 //p[a]
下一个兄弟元素 p + * //p/following-sibling::*[1]

10. Selenium 4.0 相对定位器

  • 通过元素间的空间关系定位

10.1 Above(上方)

email_locator = locate_with(By.TAG_NAME, "input").above((By.ID, "password"))

10.2 Below(下方)

password_locator = locate_with(By.TAG_NAME, "input").below((By.ID, "email"))

10.3 Left of(左边)

cancel_locator = locate_with(By.TAG_NAME, "button").to_left_of((By.ID, "submit"))

10.4 Right of(右边)

submit_locator = locate_with(By.TAG_NAME, "button").to_right_of((By.ID, "cancel"))

10.5 Near(附近)

email_locator = locate_with(By.TAG_NAME, "input").near((By.ID, "lbl-email"))

10.6 链式定位

submit_locator = locate_with(By.TAG_NAME, "button")
                .below((By.ID, "email"))
                .to_right_of((By.ID, "cancel"))

11. 特殊定位方式

11.1 匹配所有元素

plants = driver.find_elements(By.TAG_NAME, "li")
for e in plants:
    print(e.text)

11.2 元素内定位

parent = driver.find_element(By.TAG_NAME, 'div')
children = parent.find_elements(By.TAG_NAME, 'p')

11.3 活动元素定位

driver.find_element(By.ID, "kw").send_keys("搜索词")
active_elem = driver.switch_to.active_element
print(active_elem.get_attribute("name"))

12. 元素信息获取

12.1 是否显示

is_visible = driver.find_element(By.NAME, 'login').is_displayed()

12.2 是否被选定

is_checked = driver.find_element(
    By.CSS_SELECTOR, "input[type='checkbox']:first-of-type"
).is_selected()

12.3 获取标签名

tag = driver.find_element(By.CSS_SELECTOR, "h1").tag_name

12.4 获取元素矩形

rect = driver.find_element(By.CSS_SELECTOR, "h1").rect
# 返回值包含: x, y, width, height

12.5 获取CSS值

color = driver.find_element(
    By.LINK_TEXT, "More information..."
).value_of_css_property('color')

12.6 获取文本

text = driver.find_element(By.CSS_SELECTOR, "h1").text




联系方式有缘人请多多交流~

友情链接