3、Selenium + Python 实现 UI 自动化测试-元素定位

实施自动化第一步,定位元素,看似简单,实则困难。

莫慌,咱们一起搞定它!

一、总览

先来看一下,webdriver 提供的定位元素的方法,注意蓝色框中的elements,是复数,带s的;而红色框中是element,不带s的。前面那个粉色圆圈中的m代表的是method,方法的意思(调用方法有括号)。下方图是pycharm的提示信息截图,这也是我为什么上来就推荐大家使用pycharm的原因。

3、Selenium + Python 实现 UI 自动化测试-元素定位

3、Selenium + Python 实现 UI 自动化测试-元素定位


二、先来看element的

稍微整理了一下,共9种:


find_element_by_id(self, id_)
find_element_by_name(self, name)
find_element_by_tag_name(self, name)
find_element_by_class_name(self, name)
find_element_by_link_text(self, link_text)
find_element_by_partial_link_text(self, link_text)
find_element_by_xpath(self, xpath)
find_element_by_css_selector(self, css_selector)

find_element(self, by , value)

接下来一条条的看

1、find_element_by_id()

以百度输入框为例,Chrome浏览器,使用开发者工具查看元素

3、Selenium + Python 实现 UI 自动化测试-元素定位

可以看到该输入框元素有个id=‘kw’,那么定位该元素,就可以使用find_element_by_id('kw)

测试代码:找到百度输入框,输入“storm啊”,等待2秒,关闭浏览器

#导入webdriver包
from selenium import webdriver
from time import sleep

#实例化一个driver
driver = webdriver.Chrome()
#打开百度,注意前面的http://不能省略
driver.get("http://www.baidu.com")
#定位百度搜索框
myinput = driver.find_element_by_id('kw')
#对其进行操作,输入“storm啊”
myinput.send_keys("storm啊")
#等待2秒钟,让你看到输入框确实输入内容了
sleep(2)
#释放浏览器,关闭浏览器
driver.quit()

2、find_element_by_name

请使用下面定位方式替换id定位方式

myinput = driver.find_element_by_name('wd')

3、find_element_by_tag_name

大部分实际项目中应该用不到tag_name来定位一个元素,因为一个页面中tag name太容易重复了,比如我们可以用下面的语句统计下,百度首页,这个简单的页面,tag_name="input" 的有15个。

myinput = driver.find_elements_by_tag_name('input')
print(len(myinput))
3、Selenium + Python 实现 UI 自动化测试-元素定位


4、find_element_by_class_name()

myinput = driver.find_element_by_class_name("s_ipt")

5、find_element_by_link_text()

3、Selenium + Python 实现 UI 自动化测试-元素定位

#导入webdriver包
from selenium import webdriver
from time import sleep

#实例化一个driver
driver = webdriver.Chrome()
#打开百度,注意前面的http://不能省略
driver.get("http://www.baidu.com")
# 点击百度首页上右上角,“新闻”链接
driver.find_element_by_link_text("新闻").click()
sleep(2)
#释放浏览器,关闭浏览器
driver.quit()

6、find_element_by_partial_link_text(self, link_text)

本来link text = “把百度设为主页”,我用partial link text,就可以使用“把百度设为”。

driver.find_element_by_partial_link_text("把百度设为").click()
3、Selenium + Python 实现 UI 自动化测试-元素定位


7、find_element_by_xpath(self, xpath)

同上,点击“把百度设为主页”

driver.find_element_by_xpath('//*[@id="setf"]').click()

8、find_element_by_css_selector(self, css_selector)

driver.find_element_by_css_selector('#setf').click()

9、find_element(self, by , value)

很多教程都没讲清楚该语句的真正用法,有的教程,甚至直接忽略不提。我们暂时说两点:

driver.find_element("id","setf").click()
(1)你可以看到我们可以用该方法代替上面的8种用法;

(2)以后我们将会使用该语句做数据驱动测试;


小结:

(1)上面的9种方法,看似很简单,只不过碰巧你运气好,先泼你盆冷水,实际项目中,大部分情况你会遇到“龙潭虎穴”。

(2)xpath 和css两个用法,只是简单了摆在了那里(事实上,以后项目中,你会经常和他们打交道),不过请相信我,我可不会只是交你怎么用浏览器插件copy一下xpath或css,然后粘贴到那里(我现在甚至都没告诉你怎么copy。。。),我会单独花两篇文章来详细讲讲xpath和css。



三、再来看elements的

同样整理下,一样9种:

find_elements(self, by , value)
find_elements_by_id(self, id_)
find_elements_by_name(self, name)
find_elements_by_tag_name()
find_elements_by_class_name(self, name)
find_elements_by_link_text(self, link_text)
find_elements_by_partial_link_text(self, link_text)
find_elements_by_xpath(self, xpath)
find_elements_by_css_selector(self, css_selector)

既然是复数,那么我们先来看看element和elements,获取到的元素有什么不同吧

res1 = driver.find_element("id","setf")
res2 = driver.find_elements("id","setf")
print(type(res1))
print(res1)
print(type(res2))
print(res2)
<class 'selenium.webdriver.remote.webelement.WebElement'>
<selenium.webdriver.remote.webelement.WebElement (session="7884e8e6f9e0297d44e1d15c08273316", element="0.8834893461171229-1")>
<class 'list'>
[<selenium.webdriver.remote.webelement.WebElement (session="7884e8e6f9e0297d44e1d15c08273316", element="0.8834893461171229-1")>]

注意看,res1是一个web element 对象,res2是一个list对象。

前面也说了,一个网页中tag name很容易重复,这个时候就是elements 立功的时候了。事实上,除了id是唯一的外,其它name,class name,tag name,link text,partial link text都有可能重复,更不幸的时候,很多元素还没有id,哈哈。

1、find_elements_by_tag_name()

find_element_by_tag_name()不经常用,但是find_elements_by_tag_name()还是可以用用的。比如我们想通过tag name定位百度输入框,然后输入“storm啊”,怎么办?前面我们说了tag name = ‘input’的元素有15个,如果你可以数一数,输入框是第8个input,在列表中第8个元素,就是list[7],有点变态吗?

driver.find_elements_by_tag_name('input')[7].send_keys('storm啊')


那换个例子来让你觉得这是正常的,下面是一个bug管理系统,redmine,如果我们现在要对该页面进行测试,要求进入该页面后,点击全选复选框后,判断下面的所有bug是否被选中,首先用开发者工具看看复选框,没id,还不错有name,好吧,看看另一个复选框,我擦,也有name,但是值一样,换个方式?用xpath或css来定位?该页面显示多少条bug,你就复制多少条xpath,如果你真有这种想法的话,那么,(⊙o⊙)…,别天真了,做自动化就是要将懒进行到底的好嘛。。。

3、Selenium + Python 实现 UI 自动化测试-元素定位

lsts = driver.find_elements_by_name("ids[]")
for lst in lsts:
    if lst.is_selected():
        print('pass')
    else:
        print('fail')
先通过elements,找到所有的复选框,放到一个列表,然后循环读取列表元素,进行判断,即可。有木有,elements,简直太有用了。


2、其它的find_elements_by_link_text,等等就不讲了吧,一样的。

一样的吗?稍等,可是一个页面的id要么没有,要么值就是唯一的,要find_elements_by_id干什么?xpath和css好像也是唯一的,很多教程都说,如果定位不到的时候就用xpath、css,万能的,看起来这3条好像没有用吧,真的是这样吗?咱们后面讲



最后:

突然想说一句:使用Python自带的IDLE,适合学习Python;使用pycharm 适合学习Selenium。

如果你对Python一点不了解的话,建议先看看Python,再来看Selenium