在pythonUI自动化中:常用的定位方法有哪些
id,name,class,js,xpath,css
一、Selenium介绍
1、Selenium是一个应用于web应用程序的测试工具,支持多平台,多浏览器,多语言去实现ui自动化测试,我们现在讲的Selenium版本其实是Selenium2版本Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。
支持的浏览器包括IE,Firefox,Safari,Google Chrome等。
selenium 是一套完整的web应用程序测试系统,包含了测试的录制(seleniumIDE),编写及运行(Selenium Remote Control)和测试的并行处理(SeleniumGrid)
2、使用selenium的优点
1、工具免费
2、安装简单,小巧,selenium其实就是一个包
3、支持多语言( java,python)+selenium完成自动化测试
4、支持多平台(window,linux)
5、支持多浏览器 (ie,firefox,chrome)
二、Selenium工具原理
Selenium2的核心是webdriver
webdriver是按照 client-server设计原理设计(c/s架构)
client(客户端):简单来说就是我们写的代码,以http请求的方式发送给server端,server
端接收请求,执行相应操作,并返回给client端。
server(服务器):客户端的脚本启动后,被控制的浏览器就是server端,职责就是等待client端发送请求并作出响应。
使用的协议:
JSON Wire protocol(作用是可以让同一个浏览器驱动处理不同编程语言的脚本)
三、Selenium安装
1、在dos窗口用pip命令安装selenium(Python3用pip3)
命令:pip3 install selenium
安装失败解决办法:
在实际开发中, 可能要大量使用第三方模块(包), 更换至国内下载源, 可大幅提升下载速度
1、采用国内源,加速下载模块的速度
2、常用pip源:
-- 豆瓣:https://pypi.douban.com/simple
-- 阿里:https://mirrors.aliyun.com/pypi/simple
3、加速安装的命令:
-- >: pip install -i https://pypi.douban.com/simple 模块名
永久配置安装源
Windows
1、文件管理器文件路径地址栏敲:%APPDATA% 回车,快速进入 C:\Users\电脑用户\AppData\Roaming 文件夹中
2、新建 pip 文件夹并在文件夹中新建 pip.ini 配置文件
3、新增 pip.ini 配置文件内容
配置文件内容:
[global]
index-url = http://pypi.douban.com/simple
[install]
use-mirrors =true
mirrors =http://pypi.douban.com/simple/
trusted-host =pypi.douban.com
2、配置谷歌驱动文件
把chromedriver.exe放置在C:\Python37\Scripts目录下面
四、Selenium中元素定位方法
要实现UI自动化,就必须学会定位web页面元素,Selenium核心
webdriver模块提供了9种定位元素方法:
[img=569,0]D:\Program Files\youdao\qqBB50C1FE2114E5C44D1308C346CB041D\5d2b50b55ca641249422ea4745b929fe\9m]zx@pn7fa3d)jfvtzt@m8.png[/img]
1、webdriver基本语法
from selenium import webdriver
#调用selenium模块的webdriver方法
driver =webdriver.Chrome()
# 创建一个drvier对象用来调用打开浏览器,对浏览器实现操作
通过调用webdrvier.来引用对应的浏览器,生成一个浏览器对象
注意事项:webdrvier. 点后面的浏览器名称不要自己输入用联想
还有自己添加一个英文的小括号() 小括号的作用是:把它声明成为一个匿名对象 那么当前的drvier就是一个浏览器驱动对象,可以用它来对对应的浏览器实现操作的动作'''
# UI自动化所有的调用都必须在最前面加上一个drvier对象
# 通过对象来打开谷歌浏览器且输入网址
driver.get('http://www.baidu.com')
# 通过对象调用get方法来打开一个网站URL
from selenium import webdriver
import time #时间模块 sleep()线程等待
driver =webdriver.Chrome()
driver.get('http://www.baidu.com') #直接打开
url ='http://www.baidu.com'
driver.get(url) #通过引用变量来进入百度
time.sleep(2)# ''' 线程等待:不要什么地方都加'''
# driver.maximize_window() #窗口实现最大化显示100%
# '''用处:让元素定位更加的准确'''
在PythonUI自动化中:常用的定位方法哪些??
# id,name,xpath,css,class,js
# 有id优先考虑id没有id有限考虑name 如id和name都没有则考虑其它定位方法
# 所有的方法都不是唯一的:动态id name ,id name没有具体元素、、
2、常用的定位方法:
1、id定位 百度输入框的ID属性:id="kw"
drvier.find_element_by_id('kw').send_keys('多测师')
'''在百度的页面找到一个id=kw的元素然后在通过 send_keys方法
在当前元素的位置输入:多测师
在Python3当中可以直接输入中无序转译
在Python2当中如输入的中文则需要在前面加上一个u'多测师'
a =drvier.find_element_by_id('kw')
a.send_keys('你好呀!!!')
2、name定位:百度输入框的name属性:name="wd"
drvier.find_element_by_name('wd').send_keys('多测师')
a =drvier.find_element_by_name('wd')
a.send_keys('你好呀!!')
3、class定位:百度中的class元素class="s_ipt"
drvier.find_element_by_class_name('s_ipt').send_keys('多测师')
a =drvier.find_element_by_class_name('s_ipt')
a.send_keys('你好呀!!')
4、xpath定位://*[@id="kw"] 这个路径是直接复制的百度输入框的xpath路径
1.第一种直接复制的方法:
drvier.find_element_by_xpath('//*[@id="kw"]').send_keys('多测师')
a =drvier.find_element_by_xpath('//*[@id="kw"]')
a.send_keys('你好呀!!!')
2.第二种直接手写且引用当前标签中已有的元素
①通过name来实现 a.find_element_by_xpath('//*[@name="wd"]').send_keys(‘多测师’)
②通过class来实现a.find_element_by_xpath('//*[@class="s_ipt"]').send_keys(‘多测师’)
③通过id来实现a.find_element_by_xpath('//*[@id="kw"]').send_keys(‘多测师’)
④通过标签名称来实现a.find_element_by_xpath('//input[@id="kw" and @name="wd"]').send_keys('dcs')
⑤通过and来实现同上④
⑥找父级的方法(通过标签找到定位的元素)
定位标签为input
父级标签为span
父级的父级标签为form
定位原理是:找id=form的爷爷级标签然后爷爷及标签下面的第一个span标签下面的第一个input标签
a.find_element_by_xpath('//*[@id="form"]/span[1]/input[1]').send_keys('多测师')
5、css定位:结合百度输入框中的class
1.class="s_ipt"
①drvier.find_element_by_css_selector('.s_ipt').send_keys('多测师')
a =drvier.find_element_by_css_selector('.s_ipt')
a.send_keys('你好呀!!!')
②drvier.find_element_by_css_selector('[class=s_ipt]').send_keys('多测师')
2.name定位同上
3.id定位同上
4.其他元素定位方式同上
5.用and
a.find_element_by_css_selector('[name=wd][class=s_ipt]').send_keys('dcs')
6.~是否包含
a.find_element_by_css_selector('[id ~=kw]').send_keys('dcs')
7.找上级(span为input上级)
a.find_element_by_css_selector('span>input').send_keys('dcs')
8.找上上级
a.find_element_by_css_selector('form>span>input').send_keys('dcs')
6、 js语法定位:
js ='document.getElementById("kw").value="多测师"'
drvier.execute_script(js)
7、link定位
# link:链接的作用
# 通过文本点击
driver.find_element_by_link_text('hao123').click()
# click()=点击按钮
l =driver.find_element_by_link_text('hao123')
l.click()
8、partial link定位
partial_link_text=模糊匹配
driver.find_element_by_partial_link_text('ao').click()
l =driver.find_element_by_partial_link_text('ao')
l.click()
9、tag定位
from selenium import webdriver
from time import sleep
a =webdriver.Chrome()
a.get('http://www.baidu.com')
a.maximize_window()
sleep(2)
b =a.find_elements_by_tag_name('input')
for i in b:
if i.get_attribute('name')=='wd':
i.send_keys('多测师')
10.复选框定位
①普通定位
②通过索引来点击索引位的复选框a.find_elements_by_css_selector('[type=checkbox]')[0].click()
③遍历的方法
b =a.find_elements_by_css_selector('[type=checkbox]')
for i in b:
i.click()全选
for i in b:
i.click()全部取消
11.通过元素来获取当前元素对应的文本
a.find_element_by_xpath('//*[@id="s-usersetting-top"]').text
获取到元素后面加.text就可以
12.通过get方法来获取到对应元素他的值
a.find_element_by_id('kw').get_attribute('class')
13.断言:
①最常用的断言方法if
b =a.find_element_by_xpath('//*[@id="s-usersetting-top"]').text
print(b)登录
if b =='登录‘
print(’ok)
else:
print('no')
②python中自带的断言方法
assert b =='登录‘
if与assert的区别:if会出打印结果,assert相符的话不会有任何结果,不相符报错,报断言错误
Python+Selenium 实现UI自动化元素定位总结
在这9种常用的定位方法中,优先顺序
1)有id优先使用id定位
2)没有id,考虑使用name或者class定位。
3)如果没有id,name,class再考虑用xpath,css定位。
4)如果是链接可以考虑使用link_text,partial_link_text 定位。
5)tag_name和JavaScript还是用的比较少的。 我们根据实际情况,具体问题具体分析
3.新开窗口:b =’window.open("网址")‘
对象.execute_script(b)
4.获取当前窗口的标题文本
print(a.title)
5.获取当前窗口的句柄
print(a.current_window_handle)
②获取所有窗口的句柄
b =a.window_handles
print(b)
如果超过两个窗口,则句柄对应的窗口会发生相对应的改变(索引位置)
③通过句柄切换窗口(switch_to)
a.switch_to.window(b[-1])
6.窗口刷新
方法:refresh()
例子: 句柄.refresh()
7.返回上一步
方法: back()
例子: driver.back()
8.获取窗口的尺寸
方法:get_window_size()
例子:句柄.get_window_size()
9.关闭当前title的浏览器
方法:close()
例子: 句柄.close()
10.关闭所有的浏览器
方法: quit()
例子: 句柄.quit()
11.获取下拉框选项
引入类:Select()
from selenium.webdriver.support.select import Select
实战网址:https://www.ctrip.com/
1)select(元素位置).select_by_index() #通过下标定位下拉选项(索引)
2)select_by_value() #通过value属性值定位下拉选项
3)select_by_visible_text() #通过下拉文本内容内容
12.第一种定位被覆盖的元素两种方法:
# k=driver.find_element_by_css_selector('[id=HD_Btn]')
# driver.execute_script('arguments[0].click()', k)
第二种:js ='document.getElementById("HD_Btn").click()'
driver.execute_script(js)
13.传文件
b =r'C:\Users\60275\Desktop\study.txt'
# a.find_element_by_id('file').send_keys(b)
13.清空
.clear
14.携程的练习题
15、弹框处理
三种弹框的处理方法:警告型,确认型,输入型弹框
t = driver.switch_to.alert #切换进入alert()弹框
t.text() # 获取弹框的上面的文本
t.accept() #点击确定按钮
t.dismiss() #点击取消按钮
send_keys() #输入型弹框可以在弹框上面进行文本输入
练习:输入型弹框的格式
from selenium import webdriver
from time import sleep
driver =webdriver.Chrome()
driver.get('file:///E:/%E5%A4%9A%E6%B5%8B%E5%B8%88%E8%AF%BE%E4%BB%B6/prompt.html')
driver.maximize_window()
sleep(2)
driver.find_element_by_xpath('/html/body/div[2]/input').click()
a =driver.switch_to.alert
a.send_keys('http://www.baidu.com')
a.accept()
16.iframe框处理
有些元素换了很多种方法无法定位到,此时查看是否为iframe框
为iframe框时,首先要进入到iframe框中,然后再进行元素定位
切换到iframe框有三种方式:
1.通过定位iframe框,然后再switch_to
例如:iframe =driver.find_element_by_id('ptlogin_iframe')
driver.switch_to.frame(iframe)
driver.find_element_by_xpath('//*[@id="img_out_602751207"]').click()
2.通过索引去直接切换:
例如:driver.switch_to.frame(0)
3.通过tag element的方式切换到iframe框中
例如:driver.switch_to.frame(driver.find_element_by_tag_name('iframe'))
退出iframe框:
driver.switch_to.default_content()
17.selenium中的三种等待方式
1)强制等待:设置固定的线程休眠时间为5秒
time.sleep(5)
2)隐式等待
driver.implicitly_wait(5)
隐式等待是全局的针对所有元素,设置等待时间如5秒,如果5秒内出现,则继续向下,
否则抛异常。可理解为在5秒内,不停刷新看元素是否加载出来
3)显式等待:默认初始值为0.5秒是单独针对某个元素,设置一个等待时间如5秒,每隔0.5秒检查一次是否出现,如果在5秒之前任何时候出现,则继续向下,超过5秒尚未出现则抛异常
WebDriverWait(driver,5,0.5).until(EC.presence_of_element_located(By.ID,'kw'))
.sendkeys(u'多测师')
导入显示等待模块:from selenium.webdriver.support.wait import WebDriverWait #导入模块
三种等待方式的区别:
18.滚动条定位
滚动条是由js代码编写的
1.方法:execute_script()
代码如下:
js1=window.scrollTo(0,20000) #向下滚动20000px
driver.execute_script(js1)
js2=window.scrollTo(0,0) #从底部滚动到顶部
driver.execute_script(js2)
2.通过Java语法:var设置变量的方式去滑动
滚动距离1000:js ='var d=document.documentElement.scrollTop=1000‘
driver.execute_script(js)
返回顶部:js ='var d=document.documentElement.scrollTop=0‘
driver.execute_script(js)
19.鼠标移动到某个元素上并确认点击
1)定位百度首页的设置按钮
2)定位下拉的高级搜索按钮,先把鼠标移动到设置按钮上,再点击高级搜索按钮
代码如下:
先引入这个类:from selenium.webdriver.common.action_chains import ActionChains
ActionChains(driver).move_to_element(元素).perform()
方法:
1)move_to_element() #移动鼠标到某个网页元素上
2)perform() #为鼠标移动后的确认
20.Keys类
先导入这个类:from selenium.webdriver.common.keys import Keys
driver.find_element_by_id('kw').send_keys(Keys.CONTROL,'a')
删除单个字符:Keys.BACK_SPACE
全选:Keys.CONTROL,'a'
剪切:Keys.CONTROL,'x'
粘贴:Keys.CONTROL,'v'
点击确定:Keys.ENTER
可以对以上类进行封装:
def find_element(locator,*value):
'''封装一个函数'''find_element为函数名
return driver.find_element_by_id(locator).send_keys(*value)
if __name__ == '__main__':
find_element('kw','duoceshii')
find_element('kw',Keys.BACK_SPACE)
find_element('kw',(Keys.CONTROL,'a'))
find_element('kw',(Keys.CONTROL,'x'))
练习:
1、将论坛的登录还有点击模块管理 通过类来进行封装(给实参)
2、将论坛的登录还有点击模块管理 用例封装(给形参)且通过类的传递完成调用
加一个断言
'''
# from selenium import webdriver
# from time import sleep
# class Discuz: #定义一个类
# def __init__(self):
# self.drvier=webdriver.Chrome()
# self.drvier.get('http://192.168.254.129/bbs/forum.php')
# self.drvier.maximize_window()
# self.drvier.implicitly_wait(10)
# def login(self,name,pwd): #登录模块
# self.drvier.find_element_by_id('ls_username').send_keys(name)
# self.drvier.find_element_by_id('ls_password').send_keys(pwd)
# sleep(2)
# self.drvier.find_element_by_css_selector('.pn').click()
# def mk_login(self): #模块管理
# self.login('admin','123456')
# self.drvier.find_element_by_link_text('模块管理').click()
# sleep(2)
# title=self.drvier.title
# # print(title)
# if title=='门户 - Discuz! Board - Powered by Discuz!':
# print('模块管理中心OK') #模块管理中心OK
# else:
# print('NO')
# sleep(4)
# self.drvier.close()
# if __name__ == '__main__':
# D=Discuz()
# # D.login()
# D.mk_login()
自己的思路:
from selenium import webdriver
from time import sleep
driver=webdriver.Chrome()
class Luntan:
def __init__(self,username,password):
self.username=username
self.password=password
def login(self):
driver.get('http://192.168.238.128/bbs')
driver.maximize_window()
driver.find_element_by_name('username').send_keys(self.username)
driver.find_element_by_name('password').send_keys(self.password)
driver.find_element_by_xpath('//*[@id="lsform"]/div/div/table/tbody/tr[2]/td[3]tton/em').click()
# driver.find_element_by_link_text('模块管理').click()
sleep(2)
driver.find_element_by_xpath('//*[@id="um"]/p[1]/a[5]').click()
tl=driver.title
if tl=='门户 - Discuz! Board - Powered by Discuz!':
print('ok!')
else:
print('not ok')
d=Luntan('admin','123456')
d.login()
四.unisttest框架
书写格式:一.导入框架:import unittest
import unittest
class A(unittest.TestCase):——定义一个类继承unittest框架里面的Testcase类
@classmethod
def setUpClass(cls):——类的开始
print('我是大佬')
@classmethod
def tearDownClass(cls):——类的结束——关闭当前窗口释放资源
self.driver.close()——也可以直接添加关闭当前窗口
print('大佬是我')
def setUp(self):——方法的开始
print('我就是大佬')
def tearDown(self):——方法的结束
print('woshidalao')
def test01(self):——用例的名称命名要以test开头,要按照字母或数字顺序写
print('zheshidiyitiao')
if __name__ == '__main__':
1.unittest.main()——main函数在框架中的作用执行所有的用例(当前类中)
类的开始和结束,方法的开始和结束可写可不写,需要的时候就写,不写也不影响代码运行
2.在用例文件中执行选择的部分用例:需要引入testsuit类
suit = unittest.TestSuite() 构造TestSuite类对象赋予变量suit
suit.addTest(usecases('test1')) 调用addTest()添加单个用例用于执行suit.addTests(usecases('test1'),usecases('test2')) 调用addTests()添加多个用例用于执行
ru_n = unittest.TextTestRunner() 构造TextTestRunner类对象赋予变量ru_n
ru_n.run(suit) 调用润run()执行用例,
3.生成测试报告:先导入HTMLTestRunner3模块中的HTMLTestRunner类
①获取本文件所在目录的绝对路径
m_path = path.split(path.realpath(__file__))[0]
②获取当前时间,以固定字符串格式'%Y%m%d-%H%M%S'输出
time_e = strftime('%Y%m%d-%H%M%S')
③路径拼接,以获取生成的测试报告的绝对路径
repot_path = path.join(m_path,time_e+'-repot.html')
④open()打开生成的报告文件以便进行内容写入
f = open(r''+repot_path,'wb')
⑤构造HTMLTestRunner对象,传入参数:stream >> 写入文件的路径 title >> 报告标题
description >> 报告描述
runner = HTMLTestRunner(stream=f,title='百度测试用例',description='用例执行情况如下')
⑥调用对象中的run(),用来执行用例,runsome()返回的是需执行的用例列表
runner.run(runsome())
⑦关闭报告文件
f.close()
4.利用自动搜索功能执行匹配到的文件的用例
需要调用unittest.defaultTestLoader.discover():此方法会匹配与传入的文件名格式相符合的用例文件
- 读取ini文件
[progect]
project_path=E:\pythonProject\yxr-----当前包的绝对路径
①首先要导入Configparser类
import configparser
封装一个类,读取ini的文件还有文件中的路径
class readconfigini:
def __init__(self,findname) :
self.cf =configparser.ConfigParser()
self.cf.read((findname))#读取ini文件的绝对路径
def read_confing(self,find,name):
valer =self.cf.get(find,name)----传参,需要两个参数
return valer #读取ini文件里面的project以及project_path
获取文件的绝对路径:
rom Utils import readconfigini
# import os
# read_path =os.path.split(os.path.realpath(__file__))[0]
# print(read_path)
# path =os.path.join(read_path,'confing.ini') path=path_1
# path_1 =os.path.realpath('confing.ini')
# print(path_1)
#ini_path等于对象 这个对象为当前ini文件的绝对路径
# ini_path =readconfigini.readconfigini(path)
# config_path =ini_path.read_confing('project','project_path')
# print(config_path)