selenium学习笔记

1.浏览器操作
from selenium import webdriver
from selenium.webdriver.common.by import By
(1)
driver = webdriver.Chrome()
#启动chromedriver服务,连接chromedriver服务
打开一个浏览器。开启与浏览器的会话。
(2)访问 网站
driver.get(“http://www.baidu.com”) # 第一个页面
(3)最大化窗口,最小化窗口
driver.maximize_window() # 大
driver.minimize_window() # 小
(4)设置窗口大小
driver.set_window_size()
(5)重新加载页面 - F5
driver.refresh()
(6)回到上一个页面,前进
driver.back()
(7)回到下一个页面,后退
driver.forward()
(8)关闭当前窗口
driver.close() # 只是关闭当前窗口。会话仍然存在。
(9)关闭这个会话
driver.quit() # 所有事情干完之后,应该当,关闭这个会话。关闭chromedriver服务。
#--------------------------------------------------------------------------------------------------#
2.元素定位8大定位
# 第1类:靠元素的单一属性找元素。 6种定位方法:
# 第2类:组合属性来定位元素。— 男生/定居北京/高富帅 2种定位方法:xpath、css选择器。
# 1、id - 身份证。动态的id: # 找元素
# 定位策略:id 值:kw
# 找元素:DOM树。
# 获取元素的属性。
# 元素可选:radio、checkbox
# 元素可用(is_enabled):按钮 - 天生就是可点击。如果是不可击的状态(disabled),表示按钮不可用。
# 输入框:- 天生就是让用户输入信息的。如果是只读状态不可编辑(readonly属性),表示输入框不可用。
# 8种方式查找子元素:在自己的后代元素里查找子元素。
# send_keys :输入操作
# click: 点击操作
# is_displayed:元素在页面中是否可见。
# 元素的三种状态:元素存在(find) < 元素可见 < 元素可用
(1)id定位
element = driver.find_element_by_id(“kw”) # WebElement对象,封装你对元素想干的事情。
print(element.tag_name)
eels2 = driver.find_element(“id”,“kw”)
ele2 = driver.find_element(By.ID,“kw”)
print(ele2.tag_name)
(2)tag_name 标签名定位。
el = driver.find_element_by_tag_name(“input”)
# driver.find_element(By.TAG_NAME,“input”)
# 返回第一个匹配到的元素。
els = driver.find_elements_by_tag_name(“input”)
# driver.find_elements(By.TAG_NAME,“input”)
# 返回所有匹配到的元素。==列表,列表都是WebElement对象pri

(3)元素name属性定位
driver.find_element_by_name("")
driver.find_elements_by_name("")
(4)class属性定位
driver.find_element_by_class_name("bg")  # 参数只能是一种装修风格,只能是一个class值。
driver.find_elements_by_class_name("bg")

(5)(6)a元素-链接。
driver.find_element_by_link_text("hao123")
driver.find_element_by_partial_link_text("hao")
# 返回第一个匹配到的元素。
driver.find_elements_by_link_text("")
driver.find_elements_by_partial_link_text("")
# 返回所有匹配到的元素。==列表
(7)xpath定位:
	# 绝对定位
	/html/body/div[2]/div/form/div[1]/input  # 按照路径一级一级定位
	
	# 相对定位元素的相对位置,按照类型做筛选
	
	# 基本用法:
	//标签名[@属性名称=值]
	
	# 逻辑运算:
	//标签名[@属性名称=值 and/or @属性名称=值]

	# 文本定位,不变动的属性或者文件。
	//标签名[contains(@属性/text(),要包含的内容)]

	# 层级定位,通过祖宗限定范围后,再找自己。
	# //div[@id="u1"]//a[@name="tj_login"]
(8)xpath轴定位

	# 轴运算:
	ancestor:祖先结点 包括父
	parent:父结点   给g
	preceding: 当前元素节点标签之前的所有结点。(html页面先后顺序)
	preceding-sibling: 当前元素节点标签之前的所有兄弟结点
	following: 当前元素节点标签之后的所有结点。(html页面先后顺序)
	following-sibling:当前元素节点标签之后的所有兄弟结点

	# 使用语法:
	已知的元素/轴名称::标签名称[@属性=值]
	例://div//table//td//preceding::td
	//dd[@data-val="张芝波"]/following-sibling::dd[contains(@class,"batscore")]/span
	driver.find_element_by_xpath(' //div[@id="u1"]//a[@name="tj_login"]')

#--------------------------------------------------------------------------------------------------#
3.等待时间
(1)强制等待
time.sleep(3) # 强制等待
(2)隐性等待
driver.implicitly_wait(30) # 隐性等待,智能等待,元素存在
(3)显性等待
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

driver = webdriver.Chrome() # 会话的起始标志。
driver.implicitly_wait(30)
driver.get("http://www.baidu.com")

driver.find_element_by_xpath('//div[@id="u1"]//a[@name="tj_login"]').click()
# 弹出了登陆框 - 页面的变化 默认0.5秒
# WebDriverWait(driver,等待上限,轮询周期).until(条件)
loc = (By.ID,"TANGRAM__PSP_10__footerULoginBtn")
WebDriverWait(driver,10).until(EC.visibility_of_element_located(loc))
# EC.visibility_of_element_located(loc)
# 元素可见   visibility_of_element_located EC.visibility_of_element_located(loc)
# 元素们可见    EC.visibility_of_all_elements_located
time.sleep(1)
driver.find_element(*loc).click()

#--------------------------------------------------------------------------------------------------#

4.切换句柄
from selenium import webdriver
driver = webdriver.Chrome() # 会话的起始标志。
driver.get(“http://www.baidu.com”)

# 搜索 柠檬班,点击柠檬班第一个结果。
driver.find_element_by_id("kw").send_keys("柠檬班")
driver.find_element_by_id("su").click()
# 要等待结果出现,搜索结果当中,选第一个
loc = (By.XPATH,'//a[text()="腾讯课堂 - 机构主页"]')
WebDriverWait(driver,20).until(EC.visibility_of_element_located(loc))
driver.find_element(*loc).click()
# 导致新的窗口出现了。
# 等待有新的窗口出现,我再去切换窗口。
time.sleep(0.5)

(1)获取所有窗口的句柄
wins = driver.window_handles
print("所有窗口句柄:",wins)

(2)获取当前窗口的句柄
cur_win = driver.current_window_handle
print("当前的窗口句柄是:",cur_win)

(3)windows切换,切换到最新打开的窗口
driver.switch_to.window(wins[-1])
# 新的窗口
loc = (By.XPATH,'//ul[@id="js-tab"]//h2[contains(text(),"老师")]')
WebDriverWait(driver,20).until(EC.visibility_of_element_located(loc))
driver.find_element(*loc).click()
# EC.new_window_is_opened

(4)iframe切换
driver.switch_to.frame("login_frame_qq")  #name
driver.switch_to.frame(2)  # 下标
driver.switch_to.frame(driver.find_element_by_name('login_frame_qq'))  # webElement对象
# 切换完成之后,就直接是新的html页面里定位。
# 切出来,直接切换到默认的主页面
driver.switch_to.default_content()
# 切到上一个iframe
driver.switch_to.parent_frame()

(5)alert切换
from selenium import webdriver
driver = webdriver.Chrome()   # 会话的起始标志。
driver.get(r"D:\Pychram-Workspace\py22-Web-Study\web_1122\xj_demo.html")
# 做一动作,非html弹出框出现
driver.find_element_by_id("press").click()
time.sleep(1)
# 切换
al = driver.switch_to.alert
# 关掉这个弹出框
al.dismiss()  # 取消
# al.accept()  # 确定
print(al.text)  # 获取弹出框的文本

(6)总结
"""
1、显性等待:WebdriverWait等待\expected_condition条件
		WebdriverWait(driver,20).until(EC.条件)
   辅助等待:sleep

2、3大切换 
   windows切换
   iframe切换
   alert切换
   1)动作:导致窗口,iframe,alert出现。
   2)找到你要切换的它:窗口(先得到所有句柄,再切换到窗口句柄)、
					  iframe(name、下标、webelement对象)
					  alert
   3) 切换:driver.switch_to.window/frame/alert
   4) 关闭alert
"""

#--------------------------------------------------------------------------------------------------#
5.pytest

(1)与unittest的区别
	1)用例的编写?支持函数
	2)用例的识别?自动化识别。识别规则?目录-文件名-用例名  pytest命令行(pytest.main())
	3)用例的断言?assert 表达式(结果为True,False) - 逻辑/比较/函数返回值。 unittest:self.assertXXXX
	4)用例的报告?unitest/pytest --html。但是  pytest是可以集成第三方报告工具-allure
	   pytest有非常丰富的插件:700+

(2)语言写用例的用例框架共性:
	1)写用例: 前置、步骤、断言、后置。 pytest如何表达前置后置?
	2)运行用例:unitest、pytest    .main()
	3)生成报告:
	4)组织用例:筛选用例的功能?
	5)运行用例时的配置:用例失败重试(unittest不自带、pytest自带)
	6)数据驱动支持:unitest:ddt    pytest:参数化

(3)pytest前置后置:(不可以与unittest、ddt共存)
	pytest: fixture - 前置&后置。
    级别:1、用例会话(session)级别:接口自动化当的数据库连接。
         2、模块(.py/module)级别:
         3、测试类(class)级别
         4、测试用例(def/function)级别

    定义:一个函数包含前置和后置。
         0) 确定级别:夹心饼干到底夹什么。
         1)怎么区分前和后? 银河:yield
         2)函数名称可以随便定义,如何识别为前置后置?
            函数前面@pytest.fixture
         3) 如果用例要使用 前置当中的变量,怎么办?
            返回用例要使用的变量。yield 返回值。
            用例调用的时候, fixture的函数名称作为用例的参数,接收它的返回值

    调用(与测试用例关联用例):
    用例级别:
    类前面,@pytest.mark.usefixtures("fixture的函数名称")
    测试函数前面,@pytest.mark.usefixtures("fixture的函数名称")

    # conftest.py  -- 前置后置全局共享
    作用域:仅限于当前目录以及它的子孙后代目录当中的用例。
    定义各个级别的 fixture
    fixture可以继承fixture: ????

    # module \ session ???


	参数化: 实现数据驱动   @pytest.mark.parametrize("case",LD.wrong_datas)

	筛选用例 :给用例打标记。
	93个人 -- 93个用例
	运行:全是妹纸! -- 40个   标记:女
	1步:向pytest注册你的标记。  pytest.ini
	2步:在需要标记的用例上面,打上标记。
		 用例上面:@pytest.mark.标记名
	3步:运行 已标记 的用例。 pytest参数:-m 标签名
	
(4)数据驱动
@pytest.mark.parametrize
(5)用例打标签
	1)注册标签名:创建一个pytest.ini配置文件 前两行为固定格式,第三行为标记名称
	[pytest]
	markers=
	smoke
	
	2)使用方法1:再用例上方标记,可以再类上方标记(标记类中所有的测试用例),
	也可以单独在测试用例上方标记,一个用例或者类可以重复标记多个。
	@pytest.mark.标签名
	
	3)使用方法2:也可以再用例类下方标记
	标记范圈:测试用例、测试类、模块文件,使用以下申明测试类下,所有用例都被打上该标签)
	class TestClass(object)
	pytestmark = pytest.mark.标签名
	pytestmark= [pytest.mark.标签1,pytest.mark.标签2]#多标签模式

	同理(py文件下,所有测试函数和测试类里的测试函数,都有该标签import pytest
	pytestmark = pytest.mark.webtest
	pytestmark= [pytest.mark.标签1,pytest.mark.标签2]#多标签模式
	
	4)运行
	在命令行下运行:pytest -m 标签名
	在脚本中运行:pytest.main(["-m","标签名"])
(6)测试报告
(7)重复执行
	1)安装重运行插件:pip install pytest-rerunfailures
	2)运行
	在命令行下运行:pytest -m 标签名
	在脚本中运行:pytest.main(["--reruns","2","--reruns-delay","5"]) #重运行两次,间隔5秒

#--------------------------------------------------------------------------------------------------#

上一篇:什么是Pytest及Pytest常用方法


下一篇:pytest学习4-测试用例setup 和teardown