测试中使用定位搜索框搜索内容_测开系列Selenium Webdriver Python(21)--元素定位1...

测试中使用定位搜索框搜索内容_测开系列Selenium Webdriver Python(21)--元素定位1..._第1张图片

元素定位 转帖请注明出处!谢谢

在做自动化的过程中只要掌握四步操作:获取元素,操作元素,获取返回结果,断言(返回结果与期望结果是否一致),最后自动出测试报告。所以在UI层面的自动化测试开发中,元素的定位与操作是基础。

find_element_by_id()

作用:通过标签属性id查找元素

实例:

import time
from selenium import webdriver #加载selenium库
from selenium.webdriver.common.keys import Keys #加载selenium键盘定义库
def get_webdriver(url):
	# get_webdriver代码实现在本书第一个webdriver脚本中
def login_discuz(driver,str_user,str_pwd):
	#登录代码的实现在本书第一个webdriver脚本
def open_my_prompt(dirver):
    time.sleep(2)
    my_prompt=dirver.find_element_by_id('myprompt')
    print(my_prompt)
    my_prompt.click()

if __name__ == '__main__':
    #用变量存储用户名,密码
    str_user="admin"
    str_pwd="admin"
    discuz_url=r'http://192.168.0.110/discuz/forum.php'
    wb=get_webdriver(discuz_url)
    login_discuz(wb,str_user,str_pwd)
    open_my_prompt(dirver)

技术解释:登录discuz后,用webdriver的find_element_by_id方法定位到页面‘提醒‘元素,该函数的参数id是HTML代码中的id属性。为了获得id属性,在打开的网页上鼠标点选要获得的元素右键,出现菜单后,点击“使用filebug查看该元素”,得到提醒代码,该元素有id为myprompt,把它作为参数传给webdriver脚本find_element_by_id方法。

find_element_by_name()

作用:标签属性name查找元素

实例:登录discuz论坛,测试搜索框功能,搜索关键字"最漂亮的模版"

import time
from selenium import webdriver #加载selenium库
from selenium.webdriver.common.keys import Keys #加载selenium键盘定义库

def get_webdriver(url):
	# get_webdriver代码实现在本书第一个webdriver脚本中
def login_discuz(driver,str_user,str_pwd):
	#登录代码的实现在本书第一个webdriver脚本

def search_function(driver,kkeyword):
    ctxt_search = driver.find_element_by_name('srchtxt')
    ctxt_search.clear()
    ctxt_search.send_keys(kkeyword)
    btn_sumbit_search = driver.find_element_by_name('searchsubmit')
    btn_sumbit_search.click()

    search_winhadle=driver.window_handles[1]
    driver.switch_to.window(search_winhadle)
    print('窗体标题:'+driver.title)
    if driver.title=='搜索 - Discuz! Board - Powered by Discuz!':
        print('搜索页面窗口打开正确')
    else:
        print('搜索页面窗口打开错误')

if __name__ == '__main__':
    #用变量存储用户名,密码
    str_user="admin"
    str_pwd="admin"
    discuz_url=r'http://192.168.0.110/discuz/forum.php'
    wb=get_webdriver(discuz_url)
    login_discuz(wb,str_user,str_pwd)
    time.sleep(2)
    search(wb,'最漂亮的模版')

技术解释:登录discuz后,用webdriver的driver.find_element_by_name方法定位到页面搜索框元素,该函数的参数name是HTML代码中的input的name属性。打开的discuz首页鼠标点选要获得的元素搜索框元素右键,出现菜单点击“使用filebug查看该元素”,得到HTML代码,元素name属性值为srchtxt,把它作为参数传给webdriver脚本find_element_by_name。

find_element_by_class_name()

作用:通过标签的class属性查找元素

实例: 获得当前网站的在线用户数据

import time
from selenium import webdriver #加载selenium库
from selenium.webdriver.common.keys import Keys #加载selenium键盘定义库
def get_webdriver(url):
	# get_webdriver代码实现在本书第一个webdriver脚本中
def login_discuz(driver,str_user,str_pwd):
	#登录代码的实现在本书第一个webdriver脚本

def get_online_data(driver):
    online_data = driver.find_element_by_class_name('xs1')
    print(online_data.text)
    str_data = online_data.text
    data_list = str_data.split(',')
    online_user = data_list[0].split('-')
    online_user_start = online_user[1].index(' ')
    online_user_end = online_user[1].index('人')
    online_user_data = online_user[1][online_user_start + 1:online_user_end - 1]
    print('在线用户:' + online_user_data)
    member_start = online_user[2].index(' ')
    member_end = online_user[2].index('会')
    member_data = online_user[2][member_start + 1:member_end - 1]
    print('会员用户:' + member_data)
    visitor_list = data_list[1].split('-')
    visitor_start = data_list[1].index(' ')
    visitor_end = data_list[1].index('位')
    visitor_data = visitor_list[0][visitor_start + 1:visitor_end - 1]
    print('有游客:' + visitor_data)

if __name__ == '__main__':
    #用变量存储用户名,密码
    str_user="admin"
    str_pwd="admin"
    discuz_url=r'http://192.168.0.110/discuz/forum.php'
    wb=get_webdriver(discuz_url)
    login_discuz(wb,str_user,str_pwd)
    time.sleep(2)
    get_online_data(wb)

技术解释:online_data = driver.find_element_by_class_name('xs1')主要是获取discuz论坛下方的在线用户信息。通过firebug获得HTML展示信息用的页面标签是,该标签属性只有一个class,值是xs1,获得的信息字符串是str_data =['- 1 人在线 - 1 会员(0 隐身)', ' 0 位游客 - 最高记录是 4 于 2017-11-12.'],用data_list = str_data.split(',')代码把字符串按照逗号分开成一个列表,用online_user分别保存'- 1 人在线 - 1 会员(0 隐身)'和' 0 位游客 - 最高记录是 4 于 2017-11-12.'。再次用slipit按照‘-’字符分解online_user[0]和online_user[1]。online_user[0]保存列表['', ' 1 人在线 ', ' 1 会员(0 隐身)'],分别截取字符online_user[0][1], online_user[0][2]中的在线人数和在会员人数。同理截取online_user[1]中要获得的数据。

find_element_by_tag_name()

作用:通过标签名tagname查找元素,find_element_by_tag_name查找到的是第一个标签的tag_name

实例:获取discuz站点会员统计数据(只有管理员才能见到站点统计链接)

import time
from selenium import webdriver #加载selenium库
from selenium.webdriver.common.keys import Keys #加载selenium键盘定义库

def get_webdriver(url):
	# get_webdriver代码实现在本书第一个webdriver脚本中
def login_discuz(driver,str_user,str_pwd):
	#登录代码的实现在本书第一个webdriver脚本

def get_member_statistics(driver):
    link_site_statistics = driver.find_element_by_link_text('站点统计')
    link_site_statistics.click()
    time.sleep(2)
    table_site_statistics = driver.find_element_by_class_name('dt')  # 获得会员统计表格元素
    # print(table_site_statistics)
    table_rows = table_site_statistics.find_elements_by_tag_name('tr')  # 获得会员统计表格元素中的tr元素,tr标签代表的是行

    for irow in range(0, len(table_rows)):
        table_cols_head = table_rows[irow].find_elements_by_tag_name('th')
        table_cols_content = table_rows[irow].find_elements_by_tag_name('td')
        for icol in range(0, len(table_cols_content)):
            print(table_cols_head[icol].text + ':' + table_cols_content[icol].text)

技术解释:登陆discuz论坛后点击页面下方的站点统计链接,打开站点统计页面,在站点统计页面右侧是两个表格,分别是会员统计和站点统计:

测试中使用定位搜索框搜索内容_测开系列Selenium Webdriver Python(21)--元素定位1..._第2张图片

代码解析会员统计表格,先执行代码wb.find_element_by_class_name('dt')获得会员表格元素,通过firebug得到会员统计表格元素的HTML代码是

,class的名字是带有空格的名称,前面HTML的储备知识章节中在核心属性的Class属性学习中提到过,它们是并列关系,所以find_element_by_class_name传入dt,bm,mbw任何一个都可以定位到该元素。HTML代码中表格由 table 元素以及一个或多个 tr、th 或 td 元素组成,tr 元素定义表格行,th 元素定义表头,td 元素定义表格单元。find_elements_by_tag_name通过tag定位元素,tage是HTML定义的标签名。给find_elements_by_tag_name传入tr参数,返回行对象,遍历行对象,在行对象内继续用find_elements_by_tag_name定位th和td,获得内部的数据。

if __name__ == '__main__':
    #用变量存储用户名,密码
    str_user="admin"
    str_pwd="admin"
    discuz_url=r'http://192.168.0.110/discuz/forum.php'
    wb=get_webdriver(discuz_url)
    login_discuz(wb,str_user,str_pwd)
    time.sleep(2)
    get_member_statistics(wb)

技术解释:本例的数据统计结果都是从后台获取,前台显示,所以验证会员统计功能要读取数据库数据再比对前台结果,功能实现参考前面学的python和数据库一章技术。

find_element_by_link_text() 

作用:通过标签中的元素文本链接查找元素

实例: 获取discuz站点会员列表

import time
from selenium import webdriver #加载selenium库
from selenium.webdriver.common.keys import Keys #加载selenium键盘定义库

def get_webdriver(url):
	# get_webdriver代码实现在本书第一个webdriver脚本中
def login_discuz(driver,str_user,str_pwd):
	#登录代码的实现在本书第一个webdriver脚本

def get_member_list(driver):
    member_list=[]
    link_site_statistics = driver.find_element_by_link_text('站点统计')
    link_site_statistics.click()
    time.sleep(2)
    link_member_list=driver.find_element_by_link_text('会员列表')
    link_member_list.click()
    table_site_statistics = driver.find_element_by_class_name('dt')
    table_rows = table_site_statistics.find_elements_by_tag_name('tr')
    table_cols_head = table_rows[0].find_elements_by_tag_name('th')
    for icol in range(0, len(table_cols_head)):
        member_list.append(table_cols_head[icol].text)
 
	for irow in range(0, len(table_rows)):
        table_cols_content = table_rows[irow].find_elements_by_tag_name('td')
        for icol in range(0, len(table_cols_content)):
            print(member_list[icol]+':'+table_cols_content[icol].text)

if __name__ == '__main__':
    #用变量存储用户名,密码
    str_user="admin"
    str_pwd="admin"
    discuz_url=r'http://192.168.0.110/discuz/forum.php'
    wb=get_webdriver(discuz_url)
    login_discuz(wb,str_user,str_pwd)
    time.sleep(2)
    # get_member_statistics(wb)
    get_member_list(wb)

技术解释:该脚本功能实现管理员用户通过站点统计功能获取会员列表信息,进入会员列表信息是在首页底部的站点统计链接进入站点统计页面,点击左侧栏目表中会员列表链接,右侧显示所要会员列表信息。站点统计链接以及会员列表链接的定位都是是用webdriver的find_element_by_link_text方法实现的。在开发脚本中页面跳转一定要注意,因为系统,网络等原因,每个页面加载的时间会延长,所以要用time.sleep让脚本延迟执行来确保元素加载到页面完成。

find_element_by_partial_link_text()

作用:通过标签中的元素链接部分文字查找元素

实例:点击打开Discuz!-程序发布,Discuz!-安装使用,Discuz!- BUG反馈

import time
from selenium import webdriver  # 加载selenium库
if __name__ == '__main__':
    discuz_url = r'http://192.168.0.110/discuz/forum.php'
    wb=webdriver.Firefox()
    wb.get(discuz_url)
    time.sleep(2)
    link_test=wb.find_element_by_partial_link_text('程序发布')
    link_test.click()
    wb.back()
    time.sleep(2)
    link_test =wb.find_element_by_partial_link_text('安装使用')
    link_test.click()
    wb.back()
    time.sleep(2)
    link_test =  wb.find_element_by_partial_link_text('BUG反馈')
    link_test.click()

技术解释:通过find_element_by_partial_link_text()定位元素与find_element_by_link_text()方法类似,都是通过给出的链接文本去定位,这个链接文本只要包含在整个文本中即可。这种方式很不稳定,不建议使用,因为很难确定页面链接中没有相同文字存在。

find_element_by_xpath()

作用:通过标签XPath路径查找元素

实例:登录discuz论坛,使用快速导航的搜索论坛名功能

import time
from selenium import webdriver  # 加载selenium库
from selenium.webdriver.common.keys import Keys #加载selenium键盘定义库
def get_webdriver(url):
	# get_webdriver代码实现在本书第一个webdriver脚本中
def login_discuz(driver,str_user,str_pwd):
	#登录代码的实现在本书第一个webdriver脚本

def quick_navigation(driver,search_key):
    menu_quick_navigation = driver.find_element_by_xpath('.//*[@id='qmenu']')
    menu_quick_navigation.click()
    time.sleep(1)
    search_quick_navigation=driver.find_element_by_xpath('.//*[@id='flsrchdiv']/div/input')
    search_quick_navigation.send_keys(search_key)

if __name__ == '__main__':
    # 用变量存储用户名,密码
    str_user = "admin"
    str_pwd = "admin"
    discuz_url = r'http://192.168.0.110/discuz/forum.php'
    wb = get_webdriver(discuz_url)
    login_discuz(wb, str_user, str_pwd)
    time.sleep(2)
    quick_navigation(wb,'Discuz! 程序发布')

技术解释: quick_navigation实现点击快速导航,然后出现浮动窗体,然后在搜索论坛名框中写入要搜索的论坛名字。find_element_by_xpath通过XPath定位元素,要获得元素的XPath,鼠标右键点击你要获取的元素,选择inspect in firepath,就会得到XPath。'.//*[@id='qmenu']'是快速导航的XPath,'.//*[@id='flsrchdiv']/div/input'是论坛名搜索框XPath,但是要记住,快速导航窗体是在点击快速导航链接之后才会出现,在快速导航窗体没有出现前,执行find_element_by_xpath('.//*[@id='flsrchdiv']/div/input')是会报错的,因为无法定位到浮动窗体中的论坛名搜索输入框。

find_element_by_css_selector()

作用:通过CSS定位查找元素

实例:登陆discuz论坛查看个人信息

import time
from selenium import webdriver  # 加载selenium库
from selenium.webdriver.common.keys import Keys #加载selenium键盘定义库
def get_webdriver(url):
	# get_webdriver代码实现在本书第一个webdriver脚本中
def login_discuz(driver,str_user,str_pwd):
	#登录代码的实现在本书第一个webdriver脚本
def get_myinfo(driver):
    member_info=driver.find_element_by_css_selector('.vwmy>a')  #当前用户的链接
    member_info.click()
    time.sleep(2)
    myinfo_window_handle=driver.window_handles[1]
    driver.switch_to.window(myinfo_window_handle)

    myinfo_topic= driver.find_element_by_css_selector('.tb.cl>li>a:first-child ') # 点击主题
    myinfo_topic.click()
    time.sleep(2)
    myinfo_topic_child=driver.find_element_by_css_selector('.tbmu>a:first-child')  #点击主题下面的主题
    myinfo_topic_child.click()
    time.sleep(2)
    myinfo_topic_reply=driver.find_element_by_css_selector('.tbmu>a:last-child') #点击回复
    myinfo_topic_reply.click()

myinfo_personal= driver.find_element_by_css_selector('.tb.cl>li>a:last-child') # 点击个人资料
myinfo_personal. click()

if __name__ == '__main__':
    # 用变量存储用户名,密码
    str_user = "admin"
    str_pwd = "admin"
    discuz_url = r'http://192.168.0.110/discuz/forum.php'
    wb = get_webdriver(discuz_url)
    login_discuz(wb, str_user, str_pwd)
    time.sleep(2)
    get_myinfo(wb)

技术解释:get_myinfo函数功能是实现获得登陆用户的个人信息,登陆discuz页面后,用driver.find_element_by_css_selector定位登陆用户链接,该链接的位置在窗体右上角部分的第一个链接,本次登录用户为admin,该链接文本信息也是admin,如图:

96c68146c6e117fdbedbeaee33f003e6.png

find_element_by_css_selector的参数是CSS选择器,在当前页面鼠标移动到admin链接上点击鼠标右键,选择inspect in firepath,在鼠标点击前设置获得CSS选择器,这时候输入文本框就会出现你要获取的元素CSS选择器。当用firepath用CSS方式获取主题和个人资料两个链接时,发现CSS选择器只能获得.tb.cl>li>a,这句CSS选择器同时定位到两个符合条件的元素,如图:

测试中使用定位搜索框搜索内容_测开系列Selenium Webdriver Python(21)--元素定位1..._第3张图片

这时候就需要利用:first-child和:last-child分别定位到指定的元素,解决定位元素问题。

CSS选择器是在测试工作中经常用到的,被誉为Selenium定位技术的倚天剑,CSS选择器的知识在前面章节已经学习过,下面举例加深印象:

实例一:

通过id 抓取 Webelement,需要用到CSS选择器的ID选择器,find_element_by_css_selector() 在传入的参数为 id属性值前面加上#,此方法与 find_element_by_id() 执行后产生的结果一致。

find_element_by_css_selector("#yho ")
find_element_by_id("yho")

通过classname 获得Webelement,传入的参数为类选择器也就是在class属性前面加上"." , 执行结果和find_element_by_class_name() 一样。

find_element_by_css_selector(".yho")
find_element_by_class_name("yho")

在 class属性里含有多個 class,HTML代码如下:

不管传入 cgl_a 或 cgl_b任何一个作为参数,执行结果都是一样的,原理在前章基础知识中介绍过,class属性有两个甚至多个并列出现,中间空格隔开,是在前端开发中为了解决CSS文件处理页面元素方便,脚本代码如下:

find_element_by_css_selector(".yho_a")
find_element_by_css_selector(".yho_b")

但如果属性值为 “yho_a yho_b" find_element_by_css_selector(“.cgl_a cgl_b") 无法定位到对象,要定位就只能用实例三的方法抓取Webelement。

通过标签名抓取Webelement,传入标签名称作为参数,效果等同find_element_by_tag_name() 。
find_element_by_css_selector("input")
find_element_by_tag_name("input")

实例二:

要抓取列表项中的第二个标签,HTML代码如下

  • Chrome

  • Firefox

  • 如直接抓取class属性为sub_title 会返回两个Webelement项,分別是第二行和第五行的webelement,脚本目标是获取第五行代码中的Webelement项目。

    目标Webelement 是在li标签內,且li 标签中的webelement的class 名称为st2 ,因此可以用CSS选择器中的层次选择器 通过 “li.st2″ 先获取到父节点,再获取 “h2″ 子节点,脚本代码如下:

    find_element_by_css_selector("li.st2 h2")

    实例三:

    通过Webelement 的属性值定位 element,HTML代码如下:

    抓取Webelement的title 属性值,传入[ ],里面年是个表达式,是判断属性值和目标值是否匹配,脚本代码如下:

    find_element_by_css_selector("a[title='sh']")

    实例四:

    上例中能抓取到属性值匹配的webelement,但有时某些屬性值,以特定字符串为开头或者结尾,以下面HTML代码为例,每個class属性值以cls开始:

    test1

    test2

    test3

    下面代码会获取3个class属性值以clse开头名称的Webelement。

    driver.find_elements_by_css_selector("h1[class^='cls']")
    [class^=’cls’]获取class属性值以"cls" 开头名称的的Webelement
    [class$=’cls’]获取class属性值以"cls" 结尾名称的Webelement
    [class*=’cls’]获取class属性值包含字串 “cls" 的Webelement

    实例五:

    获取特定属性的Webelement,获取第2行链接对象Webelement,HTML代码如下:

    脚本执行目标是获取到含有title、href和class 三个属性的Webelement,脚本代码如下:

    find_element_by_css_selector("a[title][href][class]")

    实例六:

    获取标签中第N个Webelement,HTML代码如下:

    第一 第二 第三

    获取td标签中第一个Webelement,可以用CSS结构性伪类选择器中的:first-child,获取表格标签第一,脚本代码如下:

    find_element_by_css_selector("td:first-child")

    获取td标签中的第三个webelement,用CSS结构性伪类选择器:nth-child(3),口号中传入索引值,就会获取到第三,脚本代码如下:

    find_element_by_css_selector("td:nth-child(3)")

    实例七:

    最后用不同的CSS选择器来抓取同一个Webelement,对比下,HTML代码如下:

    我們欲抓取第 2 行的 input element,可以透過下列方法抓取到 input element,使用者根據不同的結構選擇不同的定位方式。

    find_element_by_css_selector("#testinput")
    find_element_by_css_selector("input")
    find_element_by_css_selector("div input")
    find_element_by_css_selector("div input#testinput")
    find_element_by_css_selector("div.dgl input")
    find_element_by_css_selector("div.dgl input#testinput")
    find_element_by_css_selector("div input[value='sohu']")
    find_element_by_css_selector("div[class='testdiv'] input[value='sohu']
    
    
    find_element()

    作用: 通过参数传递,结合By方法查找元素,声明find_element(self, by, value=None)

    实例:用find_element方法改写discuz论坛登陆代码

    from selenium import webdriver #加载selenium库
    from selenium.webdriver.common.keys import Keys #加载selenium键盘定义库
    from selenium.webdriver.common.by import By
    
    def get_webdriver(url):
        driver=webdriver.Firefox()#创建webdriver的firefox实例
        driver.get(url) #打开bbs项目首页地址:r'http://192.168.0.110/discuz/forum.php'
        return driver
    
    def login_discuz(driver,str_user,str_pwd):
        ctxt_user=driver.find_element(By.ID,'ls_username') #用find_element_by_name方法找到用户名输入框
        ctxt_user.clear()#清空用户名输入框内容
        ctxt_user.send_keys(str_user) #输入用户名
        ctxt_pwd=driver.find_element(By.CSS_SELECTOR, '#ls_password') #用find_element_by_name方法找到密码名输入框
        ctxt_pwd.clear()#清空密码输入框内容
        ctxt_pwd.send_keys(str_pwd) #输入密码
        cbtn_submit=driver.find_element(By.XPATH,'.//*[@id='lsform']/div/div/table/tbody/tr[2]/td[3]/button')
        cbtn_submit.submit()
    
    if __name__ == '__main__':
        #用变量存储用户名,密码
        str_user="admin"
        str_pwd="admin"
        discuz_url=r'http://192.168.0.110/discuz/forum.php'
    wb=get_webdriver(discuz_url)
    time.sleep(2)
        login_discuz(wb,str_user,str_pwd)

    技术解释:find_element()有两个参数第一个参数是By类,第二个参数是选择器字符串,Webdriver在调用find_element定位元素主要是根据By类调用的类型来传递第二个选择器字符串参数。在跟踪find_element_by_xxx方法的实现过程,追踪find_element_by_id源码:

    def find_element_by_id(self, id_):
        """Finds an element by id.
        :Args:
         - id_ - The id of the element to be found.
        :Usage:
            driver.find_element_by_id('foo')
        """
        return self.find_element(by=By.ID, value=id_)
    调用的就是find_element方法,只是传入的By类属性为ID,追踪By类查看源码:
    class By(object):
        ID = "id"
        XPATH = "xpath"
        LINK_TEXT = "link text"
        PARTIAL_LINK_TEXT = "partial link text"
        NAME = "name"
        TAG_NAME = "tag name"
        CLASS_NAME = "class name"
        CSS_SELECTOR = "css selector"

    通过以上追踪,发现find_element就是find_element_by_xxx等方法的最终实现。

    在上面脚本中乃至前面的实例脚本都多次看到time.sleep方法的出现,这是因为学习过程中多次发现SeleniumWebdriver自动化测试脚本运行并不是很稳定。经常会遇到系统明明正常运行,但是测试却失败的情况。在实际工作中,例如测试CRM系统,有一个修改用户拜访信息功能,测试场景是任一销售人员搜索最近一个月拜访的客户,找到最近一次拜访的客户信息,然后修改。在开发这个脚本过程中,脚本经常会失败,出现问题在测试脚本执行每次以销售人员登陆系统后,点击搜索用户信息按钮后,执行失败。因为每次搜索的用户信息结果没有展现在页面之前,Webdriver自动化脚本就开始执行下一步,因为元素定位不到,脚本就会报错,即使加上了除错处理,但是因为找不到元素,导致业务脚本没办法测试该业务功能,也是脚本运行失败。

    出现前面问题的原因有可能是服务器响应速度慢,在页面内容从服务器端返回到客户端的时候,Webdriver就执行了下一行脚本,从而导致测试失败。测试脚本开发人员可能会加上time.sleep方法等待几秒,但是在搜索客户信息的场景中,如果服务器反馈的信息超过了睡眠时间,脚本仍然会报错。因为服务器后台数据处理速度,会因为数据量的规模大小而时间长短不同。后台数据越大,使用的用户越多如更多的销售人员同时检索,服务器端的负载就会越高,造成服务器的响应速度会更慢。所以测试脚本即使用睡眠等待的方法,仍然会有执行失败的情况出现。

    自动化测试工具为了解决脚本执行速度和被测试系统执行速度相匹配的功能提供了同步点的解决办法。Selenium Webdriver提供了处理该类型场景问题的解决办法有两类:一种是隐式等待,一种是显示等待:

    1. 隐式等待:

    如果因某种原因,被测试对象没有出现,Webdriver将等待指定的时间,在等待时间内,它不会去找被测试对象。一旦超过指定的等待时间限制,webdriver将再次在页面中搜索该元素。如果成功,将继续进行执行后续的脚本,但如果失败,它会抛出异常。

    1. 方法一:

    import time

    time.sleep(2) #默认等待2秒

    1. 方法二:

    通过下面代码来设置selenium内置的智能等待时间

    from selenium import webdriver #导入浏览器驱动

    wb.get('http://www.discuz.net/forum.php') #打开bbs项目首页地址

    wb.implicitly_wait(10) #设置智能等待10秒

    time.sleep方法是固定等待时间,该行代码放在需要等待的时间,它的作用是局部的,而implicitly_wait(n秒)方法的功能是不论脚本运行在那一步,webdriver都需要等待xx秒,它是全局的。如果在等待的xx秒内被测试系统完成了Webdriver对应的脚本操作,则webdriver脚本正常继续执行;如果超出了xx秒,被测试系统没有完成Webdriver对应的脚本操作,因为脚本继续执行导致找不到后续的被测试对象,Webdriver会因为脚本运行失败抛出异常。该方法起等待的作用是全局性的,意思是在整个脚本的执行过程中都起作用。这种方式的缺点是,对象有可能在你等待的时间内出现,而你因为要满足隐含的等待时间而延长自动化脚本的执行时间。

    1. 显式等待:

    是一种明确的等待方式,当满足条件后再进一步处理后续的脚本。可以真正做到测试脚本和被测试软件执行的速度相匹配,避免了隐性等待缺点。Webdriver是用WebDriverWait类,辅以until()或until_not()方法来实现,它是根据判断条件进行灵活的同步。如:

    from selenium.webdriver.support.wait import WebDriverWait

    # 使用selenium提供的WebDriverWait方法,每0.5秒检查一次定位的元素,超时设置是2秒

    WebDriverWait(browser, 2).until( lambda driver: driver.find_element_by_tag_name('input'))

    基于以上知识,我们修改搜索功能脚本,添加智能等待:

    import time
    from selenium import webdriver #加载selenium库
    from selenium.webdriver.common.keys import Keys #加载selenium键盘定义库
    from selenium.webdriver.support.ui import WebDriverWait
    
    def get_webdriver(url):
    	# get_webdriver代码实现在本书第一个webdriver脚本中
    def login_discuz(driver,str_user,str_pwd):
    	#登录代码的实现在本书第一个webdriver脚本
    
    def open_my_prompt(dirver):
        time.sleep(2)
        my_prompt=dirver.find_element_by_id('myprompt')
        print(my_prompt)
        my_prompt.click()
    
    def search(driver,kkeyword):
        ctxt_search = driver.find_element_by_name('srchtxt')
        ctxt_search.clear()
        ctxt_search.send_keys(kkeyword)
        btn_sumbit_search = driver.find_element_by_name('searchsubmit')
        btn_sumbit_search.click()
    
        search_winhadle=driver.window_handles[1]
        driver.switch_to.window(search_winhadle)
        WebDriverWait(driver, 2).until(lambda driver: driver.find_element_by_class_name('emfont'))
        print('窗体标题:'+driver.title)
        if driver.title=='搜索 - Discuz! Board - Powered by Discuz!':
            print('搜索页面窗口打开正确')
        else:
            print('搜索页面窗口打开错误')
    
    if __name__ == '__main__':
        #用变量存储用户名,密码
        str_user="admin"
        str_pwd="admin"
        discuz_url=r'http://192.168.0.110/discuz/forum.php'
        wb=get_webdriver(discuz_url)
        login_discuz(wb,str_user,str_pwd)
        time.sleep(2)
        search(wb,'最漂亮的模版')

    元素操作

    在自动化测试过程中要控制元素动作,输入相应数据,验证元素执行结果,这才是完整的测试。Selenium Webdriver有提供了element接口帮助测试人员实现相应的功能。

    1. element.属性值:
    2. element.size:获取元素的尺寸。

    实例:获得discuz论坛官方论坛的logo图标尺寸

    from selenium import webdriver #加载selenium库
    def get_webdriver(url):
        driver=webdriver.Firefox()#创建webdriver的firefox实例
        driver.get(url) #打开bbs项目首页地址:r'http://192.168.0.110/discuz/forum.php'
        return driver
    
    if __name__ == '__main__':
        discuz_url=r'http://192.168.0.110/discuz/forum.php'
        wb=get_webdriver(discuz_url)
        img_forum=wb.find_element_by_xpath('.//*[@id='category_lk']/ul[1]/li/img')
        print(img_forum.size)

    运行结果:

    {'height': 31.0, 'width': 88.0}
    1. element.text:获取元素的文本。

    实例:获取导航栏上的所有外部链接地址的文本内容

    from selenium import webdriver #加载selenium库
    def get_webdriver(url):
        driver=webdriver.Firefox()#创建webdriver的firefox实例
        driver.get(url) #打开bbs项目首页地址:r'http://192.168.0.110/discuz/forum.php'
        return driver
    
    if __name__ == '__main__':
        discuz_url = r'http://192.168.0.110/discuz/forum.php'
        wb = get_webdriver(discuz_url)
        for i in range(1,7):
            link=wb.find_element_by_xpath('.//*[@id='mn_P'+str(i)+'']/a')
            print(link.text)

    运行结果:

    腾讯云主机

    Discuz!实验室

    服务购买

    应用中心

    微社区

    在线体验

    1. element.tag_name:获取标签名称。

    实例:获得主页面的搜索按钮的tagname

    from selenium import webdriver #加载selenium库
    def get_webdriver(url):
        driver=webdriver.Firefox()#创建webdriver的firefox实例
        driver.get(url) '
        return driver
    
    if __name__ == '__main__':
        discuz_url = r'http://192.168.0.110/discuz/forum.php'
        wb = get_webdriver(discuz_url)
        link=wb.find_element_by_xpath('.//*[@id='scbar_btn']')
        print(link.tag_name)
    1. 方法:
    2. element.clear():清除文本。

    实例:打开discuz论坛,在搜索输入框输入“模板”,并清空搜索文本框

    from selenium import webdriver #加载selenium库
    from selenium.webdriver.common.keys import Keys #加载selenium键盘定义库
    def get_webdriver(url):
        driver=webdriver.Firefox()#创建webdriver的firefox实例
        driver.get(url) #打开bbs项目首页地址:r'http://192.168.0.110/discuz/forum.php'
        return driver
    
    if __name__ == '__main__':
        discuz_url=r'http://192.168.0.110/discuz/forum.php'
        wb=get_webdriver(discuz_url)
        ctxt_search = wb.find_element_by_name('srchtxt')
        ctxt_search.send_keys('模板')
        ctxt_search.clear()
    1. element.send_keys(value):输入文字或键盘按键(需导入Keys模块)。

    实例:设置搜索类型为用户类型。就是首页搜索框旁边的下拉列表,选择用户

    import time
    from selenium import webdriver #加载selenium库
    from selenium.webdriver.common.keys import Keys #加载selenium键盘定义库
    def get_webdriver(url):
        driver=webdriver.Firefox()#创建webdriver的firefox实例
        driver.get(url) #打开bbs项目首页地址:r'http://192.168.0.110/discuz/forum.php'
        return driver
    
    if __name__ == '__main__':
        discuz_url=r'http://192.168.0.110/discuz/forum.php'
        wb=get_webdriver(discuz_url)
        link = wb.find_element_by_xpath('.//*[@id='scbar_type']')
        link.click()
        time.sleep(1)
        user = wb.find_element_by_xpath('.//*[@id='scbar_type_menu']/li[2]/a')
        user.click()
    1. element.click():单击元素。

    实例:打开discuz论坛最新回复链接

    from selenium import webdriver #加载selenium库
    from selenium.webdriver.common.keys import Keys #加载selenium键盘定义库
    
    def get_webdriver(url):
        driver=webdriver.Firefox()#创建webdriver的firefox实例
        driver.get(url) #打开bbs项目首页地址:r'http://192.168.0.110/discuz/forum.php'
        return driver
    
    if __name__ == '__main__':
        discuz_url=r'http://192.168.0.110/discuz/forum.php'
        wb=get_webdriver(discuz_url)
        link = wb.find_element_by_xpath('.//*[@id='chart']/div/a')
        link.click()
    1. element.get_attribute(name):获取对象的内容和属性

    实例:获取论坛板块Discuz! 程序发布的链接

    from selenium import webdriver #加载selenium库
    def get_webdriver(url):
        driver=webdriver.Firefox()#创建webdriver的firefox实例
        driver.get(url) #打开bbs项目首页地址:r'http://192.168.0.110/discuz/forum.php'
        return driver
    
    if __name__ == '__main__':
        discuz_url=r'http://192.168.0.110/discuz/forum.php'
        wb=get_webdriver(discuz_url)
        bbs_forum=wb.find_element_by_link_text('Discuz! 程序发布')
        str_href=bbs_forum.get_attribute('href')
        print('论坛链接是:'+str_href)
    1. element.is_displayed():返回元素结果是否可见(True 或 False)

    实例:检查discuz论坛logo是否正常显示

    from selenium import webdriver #加载selenium库
    def get_webdriver(url):
        driver=webdriver.Firefox()#创建webdriver的firefox实例
        driver.get(url) #打开bbs项目首页地址:r'http://192.168.0.110/discuz/forum.php'
        return driver
    
    if __name__ == '__main__':
        discuz_url=r'http://192.168.0.110/discuz/forum.php'
        wb=get_webdriver(discuz_url)
        img_logo=wb.find_element_by_xpath('.//*[@id='hd']/div/div[1]/h2/a/img')
        if img_logo.is_displayed():
            print('logo图片显示正常')
        else:
            print('logo图片没有显示')
    1. element.is_selected():返回元素结果是否被选中(True 或 False)

    实例:选中自动登录选项

    from selenium import webdriver #加载selenium库
    def get_webdriver(url):
        driver=webdriver.Firefox()#创建webdriver的firefox实例
        driver.get(url) #打开bbs项目首页地址:r'http://192.168.0.110/discuz/forum.php'
        return driver
    
    if __name__ == '__main__':
        discuz_url = r'http://192.168.0.110/discuz/forum.php'
    wb = get_webdriver(discuz_url)
    select=wb.find_element_by_xpath('.//*[@id='lsform']/div/div/table/tbody/tr[1]/td[3]/label')
        select.click()
      if select.is_selected():
            print('自动登录已经选中')
        else:
            print('自动登录已经选中')

    你可能感兴趣的:(测试中使用定位搜索框搜索内容)