自动化搭建环境及基础理论
在dos命令中输入python,在dos命令中输入pip Pip是Python官方推荐的包管理工具,提供了对Python包的查找、下载、安装、卸载的功能,属于python的一部分。 Python3.0以上的版本都是自带pip的,无需再次下载安装。 如需升级pip,有一下两种方式,命令行中输入以下命令:
python -m pip install —upgrade pip 或 easy_install.exe pip,即可升级pip
使用pip安装第三方库,命令行中执行:
pip install xxx
xx 是我们需要安装库的名称。比如安装requests库
UI自动化搭建手册(配置第三方自动化测试工具):
安装python(3.6)最好安装到D盘,记得勾选添加环境变量(add..to path)
安装pycharm
安装selenium 2.53.6指selenium的版本(命令pip install selenium==2.53.6)
安装连接数据库工具的第三方包 pip install pymysql==0.9.3
安装pillow图像处理库 pip install pillow==5.4.1
安装ddt用来实现数据驱动的自动化工具 pip install ddt==1.2.0
安装xlrd库实现读写Excel文件 pip install xlrd==1.2.0
将HTMLTestRunner.py(用来生成自动化测试报告)文件复制到python的Lib目录(配置 文件目录)
pip命令:
Pip install 包名==版本号 安装第三方的库Pip list 查看都安装了哪些第三方的库pip uninstall 包名 卸载第三方库pip download 包名****==****版本号pip download ddt==1.2.0(下载ddt 1.2.0到本地)
UI自动化中
python
语法:
首先通过网页F12定位到我们需要操作的元素的源代码(通过元素的属性值来定位元素) 1. from 第三方库名import驱动名从第三方库引入库里的驱动模块
from selenium import webdriverimport time
变量名*=*驱动名*#*驱动实例化**
driver=webdriver.Firefox()
浏览器驱动*.get*(*’*网址*’*)*#*使用浏览器打开某网页
webdriver.Firefox.get('www.baidu.com’)
输入框使用*.send_keys(“*输入的内容*”)*点击按钮使用**.click()
driver.find_element_by_id('zentao’).click()driver.find_element_by_name('account’).send_keys('admin’)
通过页面元素的属性来定位页面元素的方法 语法:浏览器驱动.find_element_by_属性名('属性值’).click() (1)使用id定位
driver.find_element_by_link_text('开源版’).click()
(2)使用name定位
driver.find_element_by_name('password’).send_keys('123456’)
(3)使用文本属性来定位
link_text(”元素的文本内容”)driver.find_element_by_link_text('开源版’).click()
(4)使用部分文本定位
partial_link_text(”元素的部分文本内容”) #driver.find_element_by_partial_link_text('开源’).click()
(5)使用class_name类名来定位
driver.find_element_by_class_name('us_Submit’).click()
(6)使用xpath来定位 xpath是一个在xml文档里查找的语言 ①通过xpath从根节点/ 逐级定位到元素,需要通过火狐的FirePath插件找路径
driver.find_element_by_xpath('/html/body/div/div/div[1]/div/div/div[2]/a[1]’).click()
②通过xpath从任意节点//利用两个属性值@属性 and @属性 定位到元素,需要通过火狐的FirePath插件找路径
driver.find_element_by_xpath('//a[@target=“_self” and @href=“/zentao/“]’).click()
③通过xpath定位元素,xpath路径直接在火狐F12的HTML中右键单击需要的那个元素对应的代码,然后复制xpath
driver.find_element_by_xpath('//*[@id=“zentao”]’).click()
(7)使用css定位 CSS是一种语言,用来描述html和xml的表现,速度比xpath快 ①id定位用# (#id的属性值)
driver.find_element_by_css_selector('#modulemenu').click()
②class定位用. (.class的属性值)
driver.find_element_by_css_selector('.modulemenu’).click()
③通过href属性值定位用[] (“[href=’/zentao/’]”)
driver.find_element_by_css_selector(“[href=’/zentao/’]”).click()driver.find_element_by_css_selector('[id="m“dulemenu"]”)’click()
④父子定位(使用较少)逐级定位
driver.find_element_by_css_selector('h'ml>body>div>div>div.modal-content>div>div>div.col-xs-8>a#zentao')’click()
或者右击复制html中的CSS路径
driver.find_element_by_css_selector('h'ml body.m-bug-browse header#header nav#mainmenu ul.nav li.active a.active').click()
(8)使用tag_name标签名定位(使用很少,因为标签一般不唯一)
driver.find_element_by_id('s'bmit')’click()
29. 单元测试框架及测试集合 ”'单元测’’’unittest
1.类名随便起,类要继承unittest.TestCase,name前后的__下划线是两个
2.测试用例必须以test开头,测试用例的执行顺序是按照26个英文字母以及阿拉伯数字
3.在执行整个脚本的时候要把光标放在if __name上边否则是以单元测试框架的形式运行的
4.鼠标放在类的:后边代表以单元测试框架形式运行所有的测试用例
5.setUp代表预操作(即一部分需要重复利用的代码,前置条件那些代码) 6.tearDown代表最后一步操作,一般都是关闭浏览器”’
’’’ort unittestclass suit(unittest.TestCase): def setUp(self): print("测试开始"“ ”def test_001(self): print("执行tes“001--case— ”def test_002(self): print("执行tes“002--case— ”def test_003(self): print("执行tes“003--case— ”def tearDown(self): print("测试结束"“if ”_name__ =="__mai“__": ” '''执行类'’’的用例''' ’ # unittest.main() #使用主函数执行所有的测试用例 '''通过建'’’执行类中的部分用例''' ’ su=unittest.TestSuite() #建立测试集合 su.addTest(suit('test_'01')) #向测试集合里添加suit类中对应的第一条测试用例 su.addTest(suit('test_'03')) ’ runner=unittest.TextTestRunner() #生成执行器 runner.run(su) #执行测试集合
30. 以测试报告形式来执行测试集合
#引用unittest类和time类import unittest,time#从HTMLTestRunner文件中引入HTMLTestRunner类from HTMLTestRunner import HTMLTestRunnerclass suit(unittest.TestCase): def setUp(self): print("测试开始"“ ”def test_001(self): print("执行tes“001--case— ”def test_002(self): print("执行tes“002--case— ”def test_003(self): print("执行tes“003--case— ”def tearDown(self): print("测试结束"“if ”_name__ =="__mai“__": ” su=unittest.TestSuite() #建立测试集合 su.addTest(suit('test_'01')) #向测试集合里添加suit类中对应的第一条测试用例 su.addTest(suit('test_'03')) ’ #description描述 stream数据流 w(写入方式)b(二进制),wb即以二进制方式写入 now=time.strftime('%Y-%m'%d %H-%M-%S') #使用当前时间并格式化时间为年月日时分秒 fp=open('../re'ort/'+now+'report.html','wb') #'../report/'+now+'report.html'通过+组合成一个指定路径的文件 runner=HTMLTestRunner(stream=fp,title='自动化测试'告',desc’iption='用例描述'' ’ runner.run(su) fp.close()
31. 以测试报告的形式输出
from selenium import webdriverfrom HTMLTestRunner import HTMLTestRunnerimport timeimport unittesturl='http:'/192.168.2.110/geeknet/user.php'clas’ Test_Login(unittest.TestCase): def setUp(self): self.driver=webdriver.Firefox() self.driver.get(url) time.sleep(1) def test_login(self): self.driver.find_element_by_name("usern“me").sen”_keys('bbb')' ’ self.driver.find_element_by_name("passw“rd").sen”_keys('01234'6') ’ self.driver.find_element_by_id("remem“er").cli”k() time.sleep(1) self.driver.find_element_by_class_name("us_Su“mit").cli”k() def tearDown(self): self.driver.close()if __name__ =="__mai“__": ”su=unittest.TestSuite() su.addTest(Test_Login('test_'ogin')) ’ now=time.strftime("%Y-%m“%d %H-%M-%S") ”fp=open('../re'ort/'+now+'repor’.html','wb'’’ ’runner=HTMLTestRunner(stream=fp,title='自动化测试'告', des’ription='用例描述'' ’runner.run(su) fp.close()
32. 断言
a=self.driver.find_element_by_class_name('f4_b''.tex’ self.assertTrue(a=='lee00'000') ’ # self.assertEqual(a,'lee00’000') ’ # self.assertIn(a,'lee00’000')**案’**from HTMLTestRunner import HTMLTestRunnerurl='http:'/192.168.2.110/geeknet/user.php'clas’ login(unittest.TestCase): def setUp(self): self.driver=webdriver.Firefox() self.driver.get(url) self.driver.maximize_window() def test_login(self): self.driver.find_element_by_name('usern'me').sen’_keys('lee00'000') ’ time.sleep(1) self.driver.find_element_by_name('passw'rd').sen’_keys('00000'') ’ time.sleep(1) self.driver.find_element_by_id("remem“er").cli”k() time.sleep(1) self.driver.find_element_by_class_name("us_Su“mit").cli”k() time.sleep(1) #断言 a=self.driver.find_element_by_class_name('f4_b''.tex’ self.assertTrue(a=='lee00'000') ’ # self.assertEqual(a,'lee00’000') ’ # self.assertIn(a,'lee00’000') ’ def tearDown(self): self.driver.close()
项目:
1. 新建一个项目geek_Auto,在其中新建文件case(存放用例)、common(共用代码存放位置)、data(数据)、pages(存放页面,一个页面一个文件)、report(存放报告)和python文件run_all(存放所有的执行代码) 
2. 在common中新建一个base.py文件,存放基层代码(类,函数)
#基层代码from selenium import webdriverfrom selenium.webdriver.common.by import Byfrom selenium.webdriver.support.wait import WebDriverWaitclass Base(object):#基于selenium进行二次封装 def __init__(self,driver:webdriver.Firefox): #__init__初始化函数,当调用这个类,会直接执行这个初始化函数 self.driver=driver def findelement(self,loc):#以显示等待的方式定位元素#loc是元素的定位方式,比如:(By.ID,'zenta’')*是把loc的2个值分开传入find_element的2个参数中 相当于:find_element(loc[0],loc[1]) print("正在获取元“位置信息:定位方式-->%s,—元素value-->%s"%(loc”0],loc[1])) ele=WebDriverWait(self.driver,5,0.5).until( lambda x:x.find_element(*loc)#匿名函数 ) return ele def sendkeys(self,loc,text): #对findelement函数再次封装,对定位的元素中输入文本 return self.findelement(loc).send_keys(text) def click(self,loc): #对findelement函数再次封装,对定位的元素进行点击 return self.findelement(loc).click() def get_text(self,loc): #对findelement函数再次封装,获取元素位置的文本 try: a= self.findelement(loc).text return a except: print('获取文本失',返回为空') ’ return "" i“”__name__=='__mai'__': ’url="http:“/192.168.2.110/geeknet/user.php" ”river=webdriver.Firefox() driver.get(url) d=Base(driver) loc_user=(By.NAME,'usern’me') ’loc_pwd=(By.NAME,'passw’rd') ’loc_rem=(By.ID,'remem’er') ’loc_login_button=(By.CLASS_NAME,'us_Su’mit') ’loc_login_username=(By.CLASS_NAME,'f4_b'’ ’d.sendkeys(loc_user,'test0’1') ’d.sendkeys(loc_pwd,'test0’1') ’d.click(loc_rem) d.click(loc_login_button) m=d.get_text(loc_login_username) #获取登录后用户名文本 if m=='test0'1': ’ print("登录成功"“
3” 在pages文件夹中新建一个python文件login_page.py,对base.py的代码进行再次封装。
from common.base import * #引入common文件夹中base文件的所有内容import timeclass Login_Page(Base): #将元素赋值给变量 loc_user=(By.NAME,'usern’me') ’loc_pwd=(By.NAME,'passw’rd') ’loc_rem=(By.ID,'remem’er') ’loc_login_button=(By.CLASS_NAME,'us_Su’mit') ’loc_login_username=(By.CLASS_NAME,'f4_b'’ ’#三次封装 def input_user(self,text): #输入用户名 self.sendkeys(self.loc_user,text) def input_pwd(self,text): #输入密码 self.sendkeys(self.loc_pwd,text)time.sleep(3) def click_keep_login(self): #点击保存登录信息 self.click(self.loc_rem) def click_login(self): #点击登录 self.click(self.loc_login_button) #四次封装 def login(self,user,pwd,keep_login=False): #keep_login登录状态默认为假 self.input_user(user) self.input_pwd(pwd) if keep_login==True: #如果给的keep_login的参数为真 self.click_keep_login() self.click_login() def get_login_username(self): #获取登录后的用户名文本 return self.get_text(self.loc_login_username)if __name__=='__main_'': u’l="http://“92.168.2.110/geeknet/user.php" dr”ver=webdriver.Firefox() driver.get(url)#Login_Page继承Base的类,Base类需要传递一个参数(浏览器驱动),所以它也需要传递参数 c=Login_Page(driver) #将Login_Page类实例化为c c.login('test001','test0’1’,True)’ d=c.get_login_username() if d=='test001': ’ print('登录成功')
4’ 编写用例,在case包中新建文件test_login_case
#四次封装from selenium import webdriverimport unittest,timefrom pages.login_page import Login_Pageclass Test_Login(unittest.TestCase,Login_Page): def setUp(self): self.driver=webdriver.Firefox() url='http://'92.168.2.110/geeknet/user.php' ’ self.driver.get(url) # time.sleep(1) self.driver.maximize_window() def login_case(self,user,pwd,expect): self.login(user,pwd,True) #登录并进行断言 result=self.get_login_username() self.assertTrue(result==expect) def test_001(self): self.login_case('test001','test0’1’,'test0’1’) d’f test_002(self): self.login_case('123456'''test0’1’,'') ’ ’’f test_003(self): self.login_case('test001','12345’'’'') ’ ’’f test_004(self): self.login_case('12551','45646’2’','') ’ ’’f tearDown(self): self.driver.close() if __name__=='__main_'': u’ittest.main()
5. 使用ddt框架
#测试数据testdata=[{'user':''est0’1’,'pwd':’t’st0’1’,'expec’'’'test0’1’}, ’ {'user':''est0’1’,'pwd':’1’345’'’'expec’'’''}, ’ ’’ {'user':''3232’'’'pwd':’t’st0’1’,'expec’'’''}, ’ ’’ {'user':''2321’,’pwd':’1’332’'’'expec’'’''}, ’ ’’ {'user':''est0’1’,'pwd':’'’'ex’e’’'’''}, ’ ’’ {'user':'','pw’'’’t’st0’1’,'expec’'’''}, ’ ’’ {'user':''test’0’','pwd':’t’st0’1’,'expec’'’'test0’1’}, ’ {'user':''est ’0’','pwd':’t’st0’1’,'expec’'’''}, ’ ’’ {'user':''est0’1’','pwd':'t’st0’1’,'expec’'’'test0’1’}, ’ ]from selenium import webdriverimport unittest,time,ddtfrom pages.login_page import Login_Page@ddt.ddt #引用ddt数据驱动框 class Test_Login(unittest.TestCase,Login_Page): def setUp(self): self.driver=webdriver.Firefox() url='http://'92.168.2.110/geeknet/user.php' ’ self.driver.get(url) time.sleep(1) self.driver.maximize_window() def login_case(self,user,pwd,expect):#登录并且进行断言 self.login(user,pwd,True) #登录函数 result=self.get_login_username()#获取登录后的用户名 self.assertTrue(result==expect) #断言 @ddt.data(*testdata)#将测试数据传递给测试用例 *指的是将测试用例的元素全部遍历出来 def test_001(self,data):#每次遍历testdata里的元素传给data print(data) self.login_case(data['user'],'ata[’pwd'],d'ta[’expect'') ’ef tearDown(self): self.driver.close()if __name__=='__main_'': u’ittest.main()
6. 在项目的data文件夹中新建一个Excel文件data.xls,**然后将此事用例写入进去,纯数字要在数据前加一个英文单引号如:
****’****11223354**userpwdexpecttest001test001test001test0011223456 1234256test001 21245641232465 test001 test001 test001test001test001test 001test001 test001 test001test001**通过xlrd类导入****Excel****表格**import xlrdclass ExcelUtil(): def __init__(self,excelPath,sheetName="sheet1"“: ” # 打开excel表格 self.data=xlrd.open_workbook(excelPath) # 通过名称获取 self.table=self.data.sheet_by_name(sheetName) #获取第一行作为key值 self.keys=self.table.row_values(0) # 获取总行数 self.rowNum=self.table.nrows # 获取总列数 self.colNum = self.table.ncols def dict_data(self): if self.rowNum<=1: print("总行数小于1"“ ” else: r=[] #空列表 j=1 for i in ranIe(self.rowNum-1): s={} #获取行里的值,以列表的形式存在 values=self.table.row_values(j) for x in range(self.colNum): s[self.keys[x]]=values[x] r.append(s) j=j+1 return rif __name__=="__main_“": ”xcelPath = "../data“data.xls" s”eetName = "Sheet1"“ d”ta = ExcelUtil(excelPath, sheetName) print(data.dict_data())
7. 引用ddt数据驱动框架
from selenium import webdriverimport unittest,time,ddtfrom pages.login_page import Login_Pagefrom common.read_excel import ExcelUtil#测试数据excelPath='D:\pyth'n\geek_Auto\data\data.xls'sheetN’me='Sheet1''data= ’xcelUtil(excelPath, sheetName)testdata=data.dict_data() @ddt.ddt #引用ddt数据驱动框架class Test_Login(unittest.TestCase,Login_Page): def setUp(self): self.driver=webdriver.Firefox() url='http://'92.168.2.110/geeknet/user.php' ’ self.driver.get(url) time.sleep(1) self.driver.maximize_window() def login_case(self,user,pwd,expect):#登录并且进行断言 self.login(user,pwd,True) #登录函数 result=self.get_login_username()#获取登录后的用户名 self.assertTrue(result==expect) #断言 @ddt.data(*testdata)#将测试数据传递给测试用例 *指的是将测试用例的元素全部遍历出来 def test_001(self,data):#每次遍历testdata里的元素传给data print(data) #打印每次传的值 self.login_case(data['user'],'ata[’pwd'],d'ta[’expect'') ’ef tearDown(self): self.driver.close() if __name__=='__main_'': u’ittest.main()
8. 在run_all中运行所有的用例
import unittest,timefrom HTMLTestRunner import HTMLTestRunner#测试的路径test_dir='./case/'a=unit'est.defaultTestLoader.discover(test_dir,pattern='test_lo'in_excel*.py')#通过d’scover方法,去测试用例目录下 查找以test开头的测试用例文件,并将查找到的测试用例组装到测试套件里。if __name__=='__main_'': n’w=time.strftime('%Y-%m-%' %H-%M-%S') f’=open('./repor'/'+now+'r'port.’tml','wb')’ ’ r’nner=HTMLTestRunner(stream=fp,title='geek购物网'动化测试报告',descri’tion='用例描述')' r’nner.run(a)fp.close()
# UI自动化理论
PO/POM你了解吗? 了解,PO/POM就是page object model页面对象设计模式 用到的有:python + selenium +unittest + ddt +POM
2. PO的优势是什么? PO提供了一种在UI层操作,业务流程与验证分离的模式,这使得测试代码变得更加清晰、可读、易维护。对象库与测试用例的分离,使得我们更好的复用对象,甚至能与不同的工具进行深度的结合应用,可复用的代码会变得更加优化。
3. 功能测试和自动化测试各占多少比例? 一般情况下,自动化测试不会超过30%,还是以功能测试为主,即在3:7左右 4. 你会不会搭建自动化测试环境? 会的,我去公司前已经搭建好了,我们那边有个10年自动化测试经验的工程师,他搭建的自动化测试框架。我们有完整的自动化环境搭建手册。我们只需要按照安装手册一步一步安装软件,配置相应的环境变量即可。 比如我们采用的是python + selenium +unittest + ddt 以及PO设计模式来进行自动化测试的,我们先安装python3.6,然后安装selenium,pip,pillow,ddt,pymysql,HTMLTestRunner等第三方库,然后配置相应的环境变量就可以了。
在自动化测试中是怎么组织测试用例(怎么识别那些case的)? 我们的测试用例都放在case目录下,通过单元测试框架里的discover方法,筛选出以test开头的用例,循环添加到测试套件中,让系统全部执行筛选出来的用例。
2. 你们的测试数据怎么进入到测试用例的? 我们首先通过xlrd来封装读取Excel的方法,然后用封装的方法读取data目录下的Excel数据文件,最后将读取的数据放在列表里,通过ddt数据驱动工具,将列表里的数据循环添加到执行的测试用例里。
3. 自动化测试中下拉列表元素是如何处理的? 我们首先引入selenium里的select类,定位下拉列表元素位置并将其赋值给一个变量,然后将元素的位置传到select类里,调用select_by_value的方法或者select_by_visible_text的方法进行下拉列表的选取
4. 自动化中如何截图? 我们是通过get_screenshot_as_file函数进行截图
5. 自动化中怎么截取部分截图? 首先对整个页面进行截图保存,接下来通过location获取要截取图片的左上角坐标,通过size获取元素的尺寸(宽和高),然后就得到了图片的右下角坐标,再通过PIL的Image方法读取保存的图片。最后通过左上角及右下角坐标使用crop进行裁切,最后保存成图片就可以了。
6. 如何处理时间控件? 定位这个时间控件,然后写一段js脚本去除时间控件的只读属性,然后执行js代码,再采用send_keys去输入内容就可以了。
7. 如何处理弹框? 我们通过driver.swith_to.alert,切换到弹框页面上,通过accept点击确定,或者通过dismiss点击取消,或者send_keys向弹框里输入值
8. 定位元素的方式有哪些? 有8种元素定位方式:id定位,name定位,class_name定位,tag_name标签名定位, link_text文本定位,partail_link_text部分文本定位,xpath定位,css定位
9. 自动化是如何生成测试报告的? 首先引入HTMLTestRunner外部文件,先将时间格式化成年月日时分秒的格式来定义测试报告的文件名,然后定位报告的储存路径,通过open函数采用wb的方式打开这个文件,然后采用HTMLTestRunner方法,传入打开的测试报告文件,测试用例的标题,测试用例的描述生成执行器,最后让执行器执行测试套件即可生成测试报告了。
10. 如何提高自动化脚本的稳定性?
11. 不要右键复制Xpath,自己写相对路径,多用id节点查找
12. 保证元素定位没又问题,第二个影响的因素就是等待,少用强制等待与隐式等待
13. 定位元素方法重新封装,结合显示等待,自己定义一套定位元素的方法。
14. Selenium的特点有什么? 开源,免费,API(封装的函数)简单、灵活 多浏览器支持:Firefox chrome ie等 多平台支持:linux macos windows 多语言支持:java python JavaScript PHP ruby等 对页面有良好的支持
16. 什么是*UI*自动化测试? 使用自动化工具来批量自动运行测试用例测试页面
17. 单元自动化测试 单元测试框架 Java:testNG、Junit Python:unittest、pytest C#:Nunit 几乎主流的语言里边都会有单元测试框架
18. 接口自动化(不分*Web*和*App*) 接口测试工具:jmeter、postman、soapUI、loadrunner 代码执行接口自动化:python的requests库 java的httpclient/httpunit
19. UI自动化测试(*web*自动化测试) QTP(最早)、Robot Framework、Selenium(目前最流行的)
20. APP自动化测试 Monkey以及Monkey runner是Android自带的测试工具 Appium(目前市场最流行的)
21. 什么样的项目适合做自动化测试?
(1)如果一个项目频繁做回归测试。
(2)系统界面比较稳定(页面变动少的适合做UI自动化,页面变动多的适合做接口自动化)
(3)软件维护周期比较长,项目进度压力不是太大。
(4)测试人员具备较强的编程能力。
22. 使用*poython*连接*Oracle*数据库 需要用到cx_oracle这个第三方库。首先,先引入cx_oracle,然后准备好连接数据,如:用户名/登录密码@Oracle服务器IP:端口号(:1521)/连接的数据库名。 例如:test001/test001@192.168.2.2:1521/orcl 代码如下:
import os,cx_OracleuserName = 'test001’pwd='test001’ip='192.168.2.2’db='orcl’sql=“select id from student” def get_value_from_db(userName,pwd,ip,db,sql): #建立oracle数据库连接,格式如下:test001/test001@192.168.2.2:1521/orcl conn=cx_Oracle.connect(userName+ '/' + pwd + '@' + ip + ':1521/' + db) #获取指针 cur=conn.cursor() #执行sql语句 cur.execute(sql) #获取执行结果 row=cur.fetchone() #把值返回给函数 return row[0] #关闭指针 cur.close #关闭数据库连接 conn.close AA=get_value_from_db(userName,pwd,ip,db,sql)print(AA)
1.使用句柄切换页面
from selenium import webdriver from selenium.webdriver.common.by import Byfrom common.base import Base driver=webdriver.Firefox() driver.get(' # handle=driver.current_window_handle # print('当前的handle为: ',handle)ba=Base(driver)loc_text=(By.ID,’kw’)loc_cl=(By.ID,’su’)loc=(By.XPATH,’/html/body/div/div[3]/div/div[3]/div[3]/h3/a’)loc_2=(By.XPATH,”.//*[@id='2’]/h3/a”)ba.sendkeys(loc_text,'句柄') ba.click(loc_cl)ba.click(loc)handles=driver.window_handles #将所有窗口的句柄输出到一个列表中print('所有的handle为: ',handles)driver.switch_to.window(handles[0]) #使用切片的方式切换到初始页面# ba.click(loc_2)