赞
踩
什么是selenium自动化?使用ui自动化实现代码模拟人的操作。(点击,输入,滑动,下拉选择,浏览)
pip install selenium==3.14
安装驱动和对应浏览器对应起来。
selenium的定位方法:
id:元素id属性值,如果id 属性唯一,那么就可以定位到,如果id是一串字母或者数值,则不能进行使用。有可能会是动态的id
name 定位:根据name的属性值来定位,但是如果name的属性值在页面不唯一,就无法进行定位。
classname:class 属性对应的值:
tagname:标签名查找,一般使用不了。
link text:模糊定位 ,一般使用不了
xpath: / 代表直接的子节点 , // 后代节点
css selector#根据标签以及标签的属性进行定位
partial link text:一般不要使用
from selenium import webdriver driver=webdriver.Chrome("C:/Users/baocomputer/tools/chromedriver_win32/chromedriver.exe") driver.maximize_window() #打开具体的网页 driver.get("https://www.baidu.com/?tn=65081411_oem_dg") #元素定位,定为搜索框 #driver.find_element_by_css_selector('input[name="wd"]').send_keys("昕诺飞公司") driver.find_element_by_xpath('//*[@id="kw"]').send_keys("昕诺飞公司") driver.find_element_by_xpath("//input[@name='wd']").send_keys("昕诺飞公司") #driver.find_element_by_css_selector('input[value]').click() """ #id定位: driver.find_element_by_id("id 属性的值") #name定位 driver.find_element_by_name("name 属性值") #class name 定位 driver.find_element_by_class_name("class 属性值") # tagname 定位 driver.find_element_by_tag_name("tag 属性值") #link_text定位 driver.find_element_by_link_text("文本查询") #xpath 定位 driver.find_element_by_xpath("基于xpath方法是实现") #css selector 定位 driver.find_element_by_css_selector("css属性") #partial link text driver.find_element_by_partial_link_text("模糊查询") """
1 元素的点击,元素的清除 ,元素的再次输入
元素清除:clear()
元素的输入:send_keys()
元素点击:click()
from selenium import webdriver import time driver= webdriver.Chrome("C:/Users/baocomputer/tools/chromedriver_win32/chromedriver.exe") driver.maximize_window() #设置隐式等待 driver.implicitly_wait(10) #打开浏览器 driver.get("http://www.baidu.com") #id定位属性 search_element = driver.find_element_by_id('kw') search_element.send_keys("九阳真经") time.sleep(2) #先将之前搜索的清除 search_element.clear() time.sleep(1) #再次输入新的内容 search_element.send_keys('前孔达克洛伊') #点击操作 driver.find_element_by_id('su').click()
2 submit提交方法
submit()方法用于提交表单数据,搜索框输入关键字之后的回车操作,就可以用该方法来模拟。
import time from selenium import webdriver driver = webdriver.Chrome() #driver.maximize_window() driver.implicitly_wait(10) url = "https://www.baidu.com" driver.get(url=url) search_element = driver.find_element_by_id('kw') #输入内容 #search_element.send_keys("九阳真经") #对于表单的提交方法:使用sunmit提交 #search_element.submit() #返回搜索框的大小 #print(search_element.size)
2获取文本信息
#获取百度一下文本按钮的文本信息
# time.sleep(2)
# button_element = driver.find_element_by_id("su").text
# print(button_element)
无法进行获取
# #获取hao123文本
# ele = driver.find_element_by_css_selector("a[href='https://www.hao123.com?src=from_pc']").text
# print(ele)
注意:我们获取文本信息的内容,获取标签中间的内容,如果是标签属性的值,使用text无法获取。
3获取标签内部的属性值
获取标签内部的属性值:get_attribute(name):获取属性值
button_selement = driver.find_element_by_id('su').get_attribute("value")
print(button_selement)
4查看页元素是否可见存在
#is_display():设置元素是否可见,在页面上是否显示该元素,如果能看到,返回true,反之false
button_selement = driver.find_element_by_id('su')
print(button_selement.is_displayed())
在webDriver中,关于鼠标操作的方法封装在ActionChains类提供。Actionchains类提供了鼠标操作的常用方法
perform():执行了ActionChains中存储的行为
context_click():右击
double_click():双击
drag_and_drop():拖动
move_to_element():鼠标悬停
""" 鼠标事件 """ from selenium import webdriver import time #导入ActionChains from selenium.webdriver.common.action_chains import ActionChains driver = webdriver.Chrome() driver.maximize_window() driver.implicitly_wait(10) url = "https://www.baidu.com" driver.get(url=url) time.sleep(2) #定位到设置 button_ele = driver.find_element_by_id("s-usersetting-top") #鼠标悬停 #ActionChains(打开的浏览器对象).move_to_element(鼠标到定位的位置).perform() #perform 执行前面的操作 ActionChains(driver).move_to_element(button_ele).perform()
1 模拟键盘事件 删除输入文本的某一个字
需要导入Keys这个类
from selenium import webdriver import time #导入ActionChains #使用keys 这个类去调用键盘 from selenium.webdriver.common.keys import Keys driver = webdriver.Chrome() driver.maximize_window() driver.implicitly_wait(10) url = "https://www.baidu.com" driver.get(url=url) #定位到搜索框 search_ele = driver.find_element_by_id("kw") #输入内容 search_ele.send_keys("seleniumm") time.sleep(1) #删除多余的m,调用删除键 search_ele.send_keys(Keys.BACK_SPACE) search_ele.clear() time.sleep(2) search_ele.send_keys('python') search_ele.send_keys(Keys.ENTER)
常用的键盘操作:
BackSpace 删除键
Space 空格键
Tab 制表键
ESC: 回退键
Enter :回车键
全选:ctrl+A
复制:Ctrl + C
粘贴:ctrl+V
""" 设置元素等待 强制等待:time.sleep() 显示等待:显示等待的加载出来,需要是给每一个元素单独设置。偶尔有一个元素由于业务原因事件比较长,单独设置显示等待。 隐式等待:driver.implicitly_wait() 判断某个元素有没有加载出来,最大时间是10S,如果在第4s就就加载出来,那就往后面继续执行。没有加载 出来就会报错 """ #显示等待:使得WebDriver等到某个元素条件成立时,继续执行,否则在达到最长时间时候抛出异常 from selenium import webdriver #在显示等待的时候,元素定位方式需要使用by加载 from selenium.webdriver.common.by import By #设置显示等待 from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.keys import Keys driver = webdriver.Chrome() driver.maximize_window() #隐式等待 driver.implicitly_wait(10) #显示等待: driver.get("https://www.baidu.com") #定位搜素框 search_box = driver.find_element_by_id('kw') """ WebDriver(浏览器,最大超时时间,轮询时间) presence_of_element_located()#接受的元素定位方式和具体的表达式,使用元组的形式传入 By.ID :值得就是find_element_by_id """ #定位搜索框 search_obj = WebDriverWait(driver, 5, 0.5).until(EC.presence_of_element_located((By.ID, 'kw'))) search_obj.send_keys('shell编程') #使用commit 方法进行提交 #search_obj.submit() #键盘操作调用keys search_obj.send_keys(Keys.ENTER)
关于窗口切换,模拟就是窗户切换,模拟浏览器进行操作。
浏览器打开会有一个叫句柄的概念,是唯一的:
方式一:我们进行页面窗口切换的时候,我们需要保存当前的页面的句柄信息,当打开第二个页面的句柄信息时候
通过driver.window_handles 方法获取当前所有句柄信息,该信息是以列表的形式存储。我们通过循环迭代这个列表,获取我们即将打开的句柄信息,然后模拟浏览器进行新页面的操作。
设置元素等待 强制等待:time.sleep() 显示等待:显示等待的加载出来,需要是给每一个元素单独设置。偶尔有一个元素由于业务原因事件比较长,单独设置显示等待。 隐式等待:driver.implicitly_wait() 判断某个元素有没有加载出来,最大时间是10S,如果在第4s就就加载出来,那就往后面继续执行。没有加载 出来就会报错 #显示等待:使得WebDriver等到某个元素条件成立时,继续执行,否则在达到最长时间时候抛出异常 import time from selenium import webdriver #在显示等待的时候,元素定位方式需要使用by加载 from selenium.webdriver.common.by import By #设置显示等待 from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.keys import Keys driver = webdriver.Chrome() driver.maximize_window() #隐式等待 driver.implicitly_wait(10) #打开网页 driver.get("https://www.baidu.com") #定位搜素框 search_box = driver.find_element_by_id('kw') search_box.send_keys('shell') search_box.send_keys(Keys.ENTER) windowhandle = driver.current_window_handle print(windowhandle) #定位一下百度百科 driver.find_element_by_xpath('//div[@id=3]//h3/a').click() time.sleep(3) #获取当前浏览器所有的句柄 all_handle = driver.window_handles #根据句柄进行切换 for head in all_handle: if head != windowhandle: driver.switch_to.window(head) #在切换后的句柄页面点击新的操作进行保存: driver.find_element_by_xpath('/html/body/div[3]/div[1]/div[2]/div/div[1]/dl/dd/span[2]/a[4]').click()
方式二:
我们利用下标来做窗口切换。
import time from selenium import webdriver #在显示等待的时候,元素定位方式需要使用by加载 from selenium.webdriver.common.keys import Keys driver = webdriver.Chrome() driver.maximize_window() #隐式等待 driver.implicitly_wait(10) #打开网页 driver.get("https://www.baidu.com") #定位搜素框 search_box = driver.find_element_by_id('kw') search_box.send_keys('shell') search_box.send_keys(Keys.ENTER) #定位一下百度百科 driver.find_element_by_xpath('//div[@id=3]//h3/a').click() time.sleep(3) handles = driver.window_handles print(handles) driver.switch_to.window(handles[-1]) #在切换后的句柄页面点击新的操作进行保存: driver.find_element_by_xpath('/html/body/div[3]/div[1]/div[2]/div/div[1]/dl/dd/span[2]/a[4]/em').click() handles_new = driver.window_handles print(handles_new) driver.switch_to.window(handles_new[-1]) driver.find_element_by_xpath("/html/body/div[2]/div[2]/div[2]/div[3]/ul/li[5]/div[1]/a").click()
关于iframe表单的切换
from selenium import webdriver from selenium.webdriver.common.keys import Keys import time #创建对象: driver = webdriver.Chrome() #windows最大化 driver.maximize_window() url = 'https://www.baidu.com' url1 = 'https://mail.163.com/' driver.get(url=url1) #表单切换 """ iframe 标单切换 driver.switch_to.frame() 默认可以写标签iframe 的id和name属性的值,前提是id和name 要唯一,不能是动态变换。 还可以通过其他的定位方式定位到iframe标签,然后定位到iframe 标签对象传入到switch_to.frame()对象中 """ #先通过xpath方法进行定位 iframe = driver.find_element_by_xpath("//div[@id='loginDiv']/iframe") driver.switch_to.frame(iframe) time.sleep(3) #当id是一串无序的字符串或者数字的时候,我们使用id属性定位无法进行定位。 #定位iframe 标签定位:需要解决动态标签问题,同时需要解决iframe 标签定位。 element_email = driver.find_element_by_css_selector('input[name="email"]') element_email.send_keys('baoqiwei0130') element_password = driver.find_element_by_css_selector('input[name="password"]') element_password.send_keys('BQWWNJ11220311') #点击登录按钮: element_login = driver.find_element_by_id('dologin') element_login.click() #由于上面登录时候邮箱密码在内层子页面,,通过iframe 已经切换进去了,需要切换到最外层方法 driver.switch_to.default_content() # 点击vip driver.find_element_by_css_selector("a[href='https://v.mail.163.com/?utm_source=163loginnav']").click()
警告框处理,就是一些弹窗提醒:
from selenium import webdriver import os import time driver = webdriver.Chrome() driver.maximize_window() driver.implicitly_wait(10) #对于静态网页:我们基于os模块获取地址,做一个地址的拼接 file_path = "file:///" + os.path.abspath("弹窗页面.html") driver.get(file_path) #操作普通alert弹窗 #进行元素定位 driver.find_element_by_css_selector('input[onclick="alterbutton()"]').click() #切换到alert弹窗 alert_obj = driver.switch_to.alert #获取弹窗的文本信息 print(alert_obj.text) time.sleep(3) #点击弹窗的确认按钮 alert_obj.accept()
from selenium import webdriver import os import time driver = webdriver.Chrome() driver.maximize_window() driver.implicitly_wait(10) file_path = "file:///" + os.path.abspath("弹窗页面.html") driver.get(file_path) driver.find_element_by_css_selector('input[onclick="confirmButtton()"]').click() #进入alert弹窗 confirm_obj = driver.switch_to.alert print(confirm_obj.text) time.sleep(3) # #点击确定按钮 # confirm_obj.accept() #点击取消 confirm_obj.dismiss()
from selenium import webdriver import os import time driver = webdriver.Chrome() driver.maximize_window() driver.implicitly_wait(10) file_path = "file:///" + os.path.abspath("弹窗页面.html") driver.get(file_path) driver.find_element_by_css_selector('input[onclick="promptButton()"]').click() #进入alert弹窗(需要切到弹窗) prompt_obj = driver.switch_to.alert time.sleep(2) #弹窗输入内容 prompt_obj.send_keys('python') time.sleep(1) #点击确定按钮 prompt_obj.accept()
自己创建一个下拉选择框
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>下拉选择框</title> </head> <body> <select name="myselect"> <!--value属性的值,下拉选择选项一般是唯一的--> <option value="o1">谷歌搜素</option> <option value="o2">百度搜素</option> <option value="o3">搜狗搜素</option> <option value="o4">搜狐搜素</option> <option value="o5">bing搜素</option> <option value="o6">360搜素</option> </select> </body> </html>
定位搜素框,我们需要导入一个包:
下拉选项的定位方式:
索引定位
value属性定位
文本定位
from selenium.webdriver.support.ui import Select
from selenium import webdriver import os from selenium.webdriver.support.ui import Select import time driver = webdriver.Chrome() driver.maximize_window() driver.implicitly_wait(10) file_path = "file:///" + os.path.abspath("下拉选择框.html") driver.get(file_path) #实例化一个对象,将定位的对象传入到实例对象里面 s1 = Select(driver.find_element_by_name('myselect')) #选择具体的选项 选取方式: # #方式1 :索引选择,索引从0 开始 # s1.select_by_index(3) # #方式2 :通过value属性的值: # s1.select_by_value('o4') #方式3 文本定位属性 s1.select_by_visible_text('bing搜索')
关于文件上传操作:
邮箱添加附件这个就是邮件上传最重要的进行元素定位
浏览器的滚动条就是执行js代码实现
from selenium import webdriver
import time
driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
driver.implicitly_wait(10)
driver.maximize_window()
time.sleep(3)
js = "window.scrollTo(100,400);"
driver.execute_script(js)
单元测试经常用到的五个概念
test case:自动化测试用例,一个TestCase的实例就是一个测试用例;
test suite:测试套件,是多个测试用例的集合;
testLoader:加载器,用于加载TestCase到TestSuite中。其中有几个loadTestsFrom__()方法,就是从各个地方寻找TestCase,创建它们的实例,然后add到TestSuite中,再返回一个TestSuite实例;
test runner:执行测试,执行测试用例,并将测试结果保存到TextTestResult实例中,包括运行了多少测试用例,成功了多少,失败了多少等信息;
test fixture:测试夹具,一个测试用例的初始化准备及环境还原,主要包含setUp() 和 setDown()方法;
1 引入unitest 这个模块,创建testcount类继承了testcase类
2 断言的方法assert.Equal方法
3main()函数方法执行上面的所有的测试用例
1 :testcase: 用来写测试用例,相当于实例方法
2:Testsuit 就是将所有的测试用例集合到一起来执行
3 TestRunnner 测试用例的执行,testrunner方法提run()方法来执行testcase/testsuit
4 testfixture 对于一个测试环境的初始化操作,通过覆盖testcase的setuop方法来实现。
四:对测试环境的初始化和清除
setUpModule/tearDownModule:整个模块开始和结束时候执行
setupClasss/ tearDownClass:在测试类开始和结束的时候执行
setUp/tearDown:在测试用例开始或者结束的时候被执行
import unittest from cacl import Count """ 测试用例类需继承unittest.Testcase 测试用例的其实就是一个实例方法 该测试用例方法就是一个必要使用test开头 """ #模块的初始化 def setUpModule(): print("_______setUpModule___________") #模块的清除 def tearDownModule(): print("______tearDownModule___________") class CountTest(unittest.TestCase): @classmethod def setUp(self) -> None: print("_______setUpClass___________") @classmethod def tearDownClass(cls) -> None: print("_______tearDownClass___________") #测试加法 def test_add(self): print("*****************test_add**************") #调用项目代码的加法 #类的实例化 c1 = Count(5,6) res = c1.add() #进行断言 self.assertEqual(res,11) def test_sub(self): print("****************testsub******************") c2 = Count(10,2) res = c2.subtractrion() self.assertEqual(res,8) if __name__ == '__main__': #执行测试用例 CountTest.main()
测试套件类似于测试单,测试用例属于测试套件的,一个测试套件可以有多个测试。
import unittest
from CountTest import CountTest
#创建测试套件对象
suite = unittest.TestSuite()
#使用addTest方法加载testcase到testsuit中,用于少量的测试用例
suite.addTest(CountTest('test_add'))
suite.addTest(CountTest('test_sub'))
#执行测试套件,创建执行器
runner = unittest.TextTestRunner()
#使用执行器执行测试套件
runner.run(suite)
Ran 2 tests in 0.002s
_______setUpModule___________
******用例级别****
*****************test_add**************
*****用例接级别******
******用例级别****
****************testsub******************
*****用例接级别******
_______tearDownClass___________
______tearDownModule___________
我们可以使用一个列表来接受
将测试用例的集合放在一个列表里面。我们将列表传递给给addTests方法中实现多测试用例集合的传递。
import unittest from CountTest import CountTest #创建测试套件对象 suite = unittest.TestSuite() #使用addTest方法加载testcase到testsuit中,用于少量的测试用例 case = [ CountTest('test_add'), CountTest('test_sub') ] # suite.addTest(CountTest('test_add')) # suite.addTest(CountTest('test_sub')) suite.addTests(case) #执行测试套件,创建执行器 runner = unittest.TextTestRunner() #使用执行器执行测试套件 runner.run(suite)
进行模糊匹配
"""
指定模糊匹配
指定模糊匹配规则,自动生成测试过用例
"""
import unittest
casepath = "../day03"
#进行模糊匹配
suitcase = unittest.defaultTestLoader.discover(start_dir=casepath,pattern='Cou*.py')
#创建执行器
runner = unittest.TextTestRunner()
#执行测试用例
runner.run(suitcase)
注意:测试执行的顺序,是按照测试名称ascii顺序执行的。
unittest提供了实现某些需求的装饰器
我们需要在测试用例每一个装饰前面加上@符号
unittest提供了以下的一些方法:
@unittest.skip(reason)#无条件跳过测试用例
@unittest.skipif(条件,reason)#跳过装饰的测试,如果条件为真
@unittest.skipUnless(条件,reason) #跳过装饰的测试,除非条件为真
@unittest.exceptedFailure()#测试标记失败,不管直接结果是否失败,一律标记为失败,但不会抛出异常信息
@unittest.exceptedFailure#如果断言失败,不计入case数目中
import unittest from cacl import Count """ 测试用例类需继承unittest.Testcase 测试用例的其实就是一个实例方法 该测试用例方法就是一个必要使用test开头 """ #模块的初始化 def setUpModule(): print("_______setUpModule___________") #模块的清除 def tearDownModule(): print("______tearDownModule___________") class CountTest(unittest.TestCase): #测试类的初始化 @classmethod def setUp(self) -> None: print("_______setUpClass___________") @classmethod def tearDownClass(cls) -> None: print("_______tearDownClass___________") #用例级别的初始化 def setUp(self) -> None: print("******用例级别****") def tearDown(self) -> None: print("*****用例接级别******") #测试加法 def test_add(self): print("*****************test_add**************") #调用项目代码的加法 #类的实例化 c1 = Count(5,6) res = c1.add() #进行断言 self.assertEqual(res,11) @unittest.skip("该用例的开发未完成") def test_sub(self): print("****************testsub******************") c2 = Count(10,2) res = c2.subtractrion() self.assertEqual(res,8) try: def test_func(self): print("***************执行test_func函数****************") c3 = Count(8,9) res = c3.add() self.assertEqual(res,10) print("***************执行失败********************") except Exception as e: print() if __name__ == '__main__': #执行测试用例 CountTest.main()
借助HTMLRunner ,这是unittcase的一个库,是单元测试框架的一个扩展。它生成易于使用的HTML测试报告。
但是在HTMLRunner是基于python2 进行开发的,对于python3环境而言,对其中的部分内容进行修改。
import unittest import time import os from common.HTMLRunner import HTMLTestRunner from BeautifulReport import BeautifulReport #测试报告的存放地址 report_path = "./report" report_title = "冒烟测试" #测试的描述 report_desc = "冒烟测试" if not os.path .exists(report_path): os.mkdir(report_path) #构建获取时间日期作为报告的名字 get_time = time.strftime("%Y%m%d%H%M%S")#获取当前的时间 #构建测试报告存放路径和名字,这个加上当前的时间做一个拼接,作为报告的名称。 file_path = report_path + f"{get_time}.html" #执行测试,生成测试报告 #指定加载测试用例的路径。指定加载 case_path = "./test_case" #模糊匹配对应的测试用例 suite = unittest.defaultTestLoader.discover(start_dir=case_path, pattern='C*.py') # with open(file_path,'wb') as f1: # #第一个参数指的是生成的测试报告给那个文件写入 # runner = HTMLTestRunner(f1,title=report_title,description=report_desc) # #执行套件 # runner.run(suite) #将测试套件存放到BeautifulReport()里面。 BeautifulReport(suite).report(filename=file_path,description=report_desc,report_dir=report_path) #BeautifulReport(suite).report(filename='测试报告文件名称', # description='测试报告标题', # report_dir='.') # report_dir='.'把report放到当前目录下
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。