UI自动化测试保姆级教程①

欢迎来到阿妮莫的学习小屋
慢也好,步子小也好,在往前走就好

目录

自动化测试

简介

作用

分类

优缺点

优点

缺点(误区)

UI自动化测试

自动化测试使用场景

自动化测试实现时间

Selenium框架

特点

Web自动化测试环境部署

Selenium包安装

浏览器驱动获取

获取谷歌浏览器版本

​编辑获取对应的驱动程序

第一个Web自动化脚本

元素定位

方法1:直接获取信息

方法2:启动开发者工具再获取信息

元素定位方法✨

id方法

name方法

class_name方法

 tag_name方法

 定位超链接元素方法

 XPath定位方法

路径策略

元素属性策略

属性与逻辑结合策略

层级与属性结合策略

其他策略

CSS定位方法

四种策略

层级选择器

其他策略


自动化测试

简介

自动化测试就是 利用[工具][代码]替代人工完成对软件项目的[测试过程]

作用

自动化测试主要用于以下几个方面

  1. 回归测试: 重复性高/执行频率高
  2. 压力测试: 多用户/手工测试不好实现
  3. 兼容性测试: 测试条件多/手工执行效率差

总的来说: 自动化测试的目的就是 "提高测试效率, 保证软件产品的质量".

分类

  1. 接口自动化
  2. 性能自动化
  3. UI自动化(Web项目/APP项目)
  4. 单元测试自动化

优缺点

优点

  1. 较少的时间内运行更多的测试用例;
  2. 自动化脚本可以重复执行;
  3. 减少人为的错误;
  4. 克服手工测试的局限性(例如压力测试这种场景);

缺点(误区)

1. 自动化测试可以完全替代手工测试? 

  • 自动化测试的脚本实现步骤依赖于手工测试
  • 对于需求变更频繁的软件, 测试脚本的维护和设计比较空难.

2. 自动化测试一定比手工测试厉害?

  •  只是存在一定的入门门槛导致的, 自动化测试和手工测试的本质都是为了发现更多的bug.

3. 自动化测试可以发现更多的BUG?

  •  对于界面布局和系统奔溃等现象, 手工测试往往更加容易发现.

4. 自动化测试适用于所有测试场景?

  •   功能测试逻辑复杂/涉及第三方交互的都不适合自动化测试实现

UI自动化测试

UI自动化测试就是 通过[代码]和[工具]对软件项目的[界面]进行测试的过程

分类: Web自动化和APP自动化

自动化测试使用场景

  1. 需求相对稳定, 不会频繁变更
  2. 项目开发周期长
  3. 需要频繁实现回归测试(UI 自动化测试最大的应用场景)

什么是回归测试?

回归测试是软件测试的一种, 主要目的是在软件发生变更之后, 确保这些变更没有引入新的缺陷, 并且原有的功能仍然正常工作.

自动化测试实现时间

  1. 功能测试结束
  2. 可以与功能测试同步实现; 前提: 公司有自动化测试组, 那么可以先部署自动化测试环境/分析需求/编写自动化测试用例.

Selenium框架

常见的UI自动化测试工具有: QTP, Selenium, Robot framework; 本文以Selenium作为教学工具进行讲解.

Selenium是一个用于Web应用程序的自动化测试工具

特点

  1. 开源: 可以根据项目需求进行二次开发
  2. 跨平台: Windows/macOS/Linux 都可以使用
  3. 支持多语言: Python/Java
  4. 支持常见的浏览器: 谷歌浏览器/火狐浏览器/Safari浏览器

Web自动化测试环境部署

本文使用Python语言编写自动化测试脚本, 并且使用谷歌浏览器进行测试.

安装Python环境:

Python入门(小白友好)icon-default.png?t=O83Ahttps://blog.csdn.net/m0_70094411/article/details/136811671?fromshare=blogdetail&sharetype=blogdetail&sharerId=136811671&sharerefer=PC&sharesource=m0_70094411&sharefrom=from_link安装谷歌浏览器:Chrome 官方下载 | 谷歌浏览器中文版官网icon-default.png?t=O83Ahttps://www.chrome.net.cn/

Selenium包安装

#安装selenium包, 可能会比较慢
pip install selenium 
#镜像源下载, 速度较快
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple selenium
#卸载
pip uninstall selenium
#查看是否安装以及版本号
pip list

动图演示:

浏览器驱动获取

不同版本的谷歌浏览器是需要对应不同的浏览器驱动的, 因此需要先获取谷歌浏览器的版本.

获取谷歌浏览器版本

获取对应的驱动程序

谷歌各版本浏览器驱动获取icon-default.png?t=O83Ahttps://www.cnblogs.com/aiyablog/articles/17948703

 将下载好的浏览器驱动程序解压缩, 并且置于Python解释器根目录下即可.

注意:浏览器会自动更新, 原低版本的驱动会出现不适配问题, 需要重新下载对应版本的驱动程序.

第一个Web自动化脚本

  自动化脚本测试步骤: 打开百度网页, 输入你想要查询的内容, 点击百度一下;

'''
Web 自动化测试代码
'''
from time import sleep

# 1.导入selenium模块
from selenium import webdriver
from selenium.webdriver.common.by import By

# 2.实例化浏览器对象
driver = webdriver.Chrome() # 创建谷歌浏览器对象

# 3.打开网页: 必须包含 https协议头
driver.get("https://www.baidu.com")

# 在输入框输入内容,并且点击 "百度一下"
driver.find_element(By.ID,'kw').send_keys('疯狂动物城')
driver.find_element(By.ID,'su').click()
# 5.暂停3s, 观察效果
sleep(3)

# 6.关闭网页: 不要使用close
driver.quit()

动图演示效果:

元素定位

计算机无法像人一样, 通过肉眼来识别页面中的信息元素(输入框, 点击按钮); 而是通过页面内元素对应的代码特征来定位及操作元素的

元素特征: 标签名/id值/属性和属性值等

 

方法1:直接获取信息

方法2:启动开发者工具再获取信息

元素定位方法✨

Selenium框架中一共提供了八大类元素定位方法; 只要能够定位目标元素, 使用哪一种方法都可以.

注意:当页面中有多个元素的特征值是相同的时候, 定位元素的方法执行时, 默认只会获取第一个符合要求的元素. 因此, 定位元素时需要尽量保证使用的特征值可以保证目标元素在页面中的唯一性!

为了更好的进行讲解演示, 本文使用本地的html文件以及百度首页进行操作演示, 注册页面html源码如下, 小伙伴们自动保存并修改文件后缀为.html 

<!DOCTYPE html>
<html lang="zh-cn">
<head>
	<meta charset="UTF-8">
	<title>注册A</title>
	<style type="text/css">
		body{background: #fdfcfc}
		.zc{width: 500px;padding: 10px;margin-top: 20px;margin-left: 30%}
		fieldset{background: #7ed6e2;}
		input{padding: 5px;background: #f8f8f8}
		button{padding: 8px; background: #fcfcfc;border-radius: 5px}
		button:hover{padding: 10px; background: #0a1010}
		input:focus{background: #ffffff}
		span{display: none}
		.ball{border: 1px solid #e54724;}
	</style>
	<script type="text/javascript">
		function al(){
			alert('我被点击啦!')
			//var ret = confirm('确定要删除吗?');
			//alert(ret)
		}
	</script>
</head>
<body>
	<div class="zc">
		<fieldset>
			<legend>注册用户A</legend>
			<form>
				<p id="pa">
					<label for="userA">账号:</label>
					<input type="text" name="userA" id="userA" placeholder="请输入用户名" />
				</p>
				<p>
					<label for="passwordA">密码:</label>		
					<input type="password" name="passwordA" id="passwordA" placeholder="请输入密码" />
				</p>
				<p>
					<label for="telA">电话号码:</label>
					<input type="text" name="telA" id="telA" class="telA" placeholder="请输入电话号码" />				
				</p>
				<p>
					<label>电子邮箱:</label>
					<input type="email" name="emailA" class="emailA dzyxA" placeholder="请输入电子邮箱" />
				</p>
				<p>
					<button>注&nbsp;&nbsp;册</button>
					<span name="sp1">我隐身了</span>
					<hr>
				</p>
				<p>
					当前窗口打开:<a href="http://www.sina.com.cn">新浪</a>
					&nbsp;&nbsp;&nbsp;&nbsp;
					新窗口打开:<a href="http://www.sina.com.cn" id="fw" target="_blank">访问 新浪 网站</a>
					<hr>
				</p>
				<p>
					<input type="reset" value="取消" disabled="disabled" id="cancelA">
					&nbsp;&nbsp;&nbsp;&nbsp;
					<input type="button" value="alert" id="alerta" onclick="alert('我被点击啦!')">
					<input type="button" value="confirm" id="confirma" onclick="confirm('确定要删除吗?')">
					<input type="button" value="prompt" id="prompta" onclick="prompt('请输入用户名:')">
					<hr>
				</p>
				<p>
					所在地:
					<select name="selecta" id="selectA">
						<option value="bj">北京</option>
						<option value="sh">上海</option>
						<option value="gz">广州</option>
						<option value="sz">深圳</option>
						<option value="zj">浙江</option>
						<option value="sd">山东</option>
					</select>
				</p>
				<hr>
				<p>
					喜欢的水果:
					<label for="pga"><input type="radio" name="fruit" value="pga" id="pga">苹果</label>
					<label for="jza"><input type="radio" name="fruit" value="jza" id="jza">橘子</label>
					<label for="xja"><input type="radio" name="fruit" value="xja" id="xja">香蕉</label>
					<label for="lia"><input type="radio" name="fruit" value="lia" id="lia" checked="checked">梨</label>
					<label for="xga"><input type="radio" name="fruit" value="xga" id="xga">西瓜</label>
				</p>
				<hr>
				<p>
					日常爱好:
					<input type="checkbox" name="hobby" value="阅读" id="yuedu">阅读
					<input type="checkbox" name="hobby" value="旅游" id="lvyou">旅游
					<input type="checkbox" name="hobby" value="打游戏" id="game" checked="checked">打游戏
					<input type="checkbox" name="hobby" value="听音乐" id="music">听音乐<br>
				</p>
				<hr>
				<div>
					<input type="file" name="upfilea" />
				</div>
			</form>
		</fieldset>
		<div style="background: #7ed6e2;margin-top: 20px; padding: 10px">
			<div>
				<p id="p1">
					<label>test1:</label>
					<input type="text" name="user" class="login"/>
				</p>
				<p id="p2">
					<label>test2:</label>
					<input type="text" name="user" class="login-test"/>
				</p>
				<p id="p3">
					<label>test3:</label>
					<input type="text"  name="user-test" class="login-test"/>
				</p>
				<p id="p4">
					<label>test4:</label>
					<input type="text"  name="user-test" class="login"/>
				</p>
			</div>
			<a href="http://www.baidu.com">打开百度</a>
		</div>
	</div>
</body>

<script type="text/javascript">
	// window.scrollTo(0, 100);

</script>
</html>

id方法

#在selenium4.0.0中该方法已过期,可使用但不建议
浏览器对象.find_element_by_id('元素id值') 
#推荐使用
浏览器对象.find_element(By.ID, '元素id值') 

  代码示例: 打开注册页面--根据id值定位元素--输入用户名user001--输入密码12345

'''
Web自动化基本代码
'''
from time import sleep

# 1.导入模块
from selenium import webdriver
from selenium.webdriver.common.by import By

# 2.创建浏览器对象
driver = webdriver.Chrome()

# 3.打开网页
'''
[这个文件地址是根据你自己html存放的目录而定的]
双击html文件--在浏览器中打开--复制浏览器上方的URL
'''

driver.get("file:///D:/%E6%B3%A8%E5%86%8C%E9%A1%B5%E9%9D%A2.html")
# 实现需求
# 1) 使用id定位, 输入用户名:user001
# username = driver.find_element_by_id('userA')
username = driver.find_element(By.ID, 'userA')

# 输入方法: 元素对象.send_keys('内容')
username.send_keys('user001')

# 2) 使用id定位, 输入密码: 12345
# passwd = driver.find_element_by_id('passwordA')
passwd = driver.find_element(By.ID, 'passwordA')
passwd.send_keys('12345')

# 4.观察浏览器
sleep(3)

# 5.关闭浏览器
driver.quit()

动图演示效果: 

name方法

#在selenium4.0.0中该方法已过期,可使用但不建议
浏览器对象.find_element_by_name('元素name值') 
#推荐使用
浏览器对象.find_element(By.NAME, '元素name值') 

1. 由于元素的name属性值可能会存在重复, 必须先确定其唯一性之后, 才可以使用.

2. 如果页面内有多个元素的特征值是相同的时候, 定位元素的方法执行时, 默认只会获取第一个符合要求的

代码示例: 打开注册页面--根据name值定位元素--输入用户名admin--输入密码123456

'''
Web自动化基本代码
'''
from time import sleep

# 1.导入模块
from selenium import webdriver
from selenium.webdriver.common.by import By

# 2.创建浏览器对象
driver=webdriver.Chrome()

# 3.打开网页
driver.get("file:///D:/%E6%B3%A8%E5%86%8C%E9%A1%B5%E9%9D%A2.html")

# 需求根据name定位元素
username=driver.find_element(By.NAME,'userA')
username.send_keys('admin')

passwd=driver.find_element(By.NAME,'passwordA')

passwd.send_keys('123456')

# 4.观察网页
sleep(2)

# 5.关闭网页
driver.quit()

动图演示效果: 

class_name方法

#不建议使用
浏览器对象.find_element_by_class_name('元素class_name值') 
#推荐使用
浏览器对象.find_element(By.CLASS_NAME, '元素class_name值') 

注意:

1.元素的class属性值可能会存在重复, 必须确定其能够代表目标元素唯一性之后, 方可使用.

2.如果元素的class属性值存在多个值, 在class_name方法使用时, 只能使用其中的任意一个.

代码示例: 打开注册页面--根据class_name值定位元素--输入电话号码12345678901--输入邮箱123@qq.com

"""
Web 自动化基本代码
"""
# 1. 导入模块
from time import sleep

from selenium import webdriver

# 2. 实例化浏览器对象: 类名()
driver = webdriver.Chrome()  # 谷歌浏览器

# 3. 打开网页: 必须包含协议头
driver.get('file:///D:/%E6%B3%A8%E5%86%8C%E9%A1%B5%E9%9D%A2.html')


# class_name 方法: 由于元素的 class 属性值可能存在重复, 必须确定其能够代表目标元素唯一性之后, 方可使用
'''
注意
1. 方法名是 class_name, 但要找元素的 class 属性值
2. 如果元素的 class 属性值存在多个值, 在 class_name 方法使用时, 只能使用其中的任意一个
'''

# 1).通过class_name定位电话号码A,并输入:18611111111
tel = driver.find_element_by_class_name('telA')
tel.send_keys('12345678901')

# 2).通过class_name定位电子邮箱A,并输入:123@qq.com
'''
mail = driver.find_element_by_class_name('emailA dzyxA')  # 错误样例
mail = driver.find_element_by_class_name('emailA')  # 正确样例
'''
mail = driver.find_element_by_class_name('dzyxA')  # 正确样例
mail.send_keys('123@qq.com')

# 3).3秒后关闭浏览器窗口

# 4. 观察效果
sleep(3)

# 5. 关闭页面
driver.quit()

动图演示效果:

 tag_name方法

#可使用但不建议
浏览器对象.find_element_by_tag_name('元素标签值') 
#推荐使用
浏览器对象.find_element(By.TAG_NAME, '元素标签值') 

注意: 由于标签名的重复性过高, 一般做精确定位时, 都不会选择tag_name方法

代码示例: 打开页面--根据tag_name方法定位元素--输入用户名admin

"""
Web 自动化基本代码
"""
# 1. 导入模块
from time import sleep

from selenium import webdriver

# 2. 实例化浏览器对象: 类名()
driver = webdriver.Chrome()  # 谷歌浏览器

# 3. 打开网页: 必须包含协议头
driver.get('file:///D:/%E6%B3%A8%E5%86%8C%E9%A1%B5%E9%9D%A2.html')

# 实现需求
'''
注意: 由于标签名的重复性过高, 一般做精确定位时, 都不会选择 tag_name 方法
'''

# 使用tag_name定位用户名输入框,并输入:admin
'''
定位元素再填写信息
username = driver.find_element_by_tag_name('input')
username.send_keys('admin')
'''

# 说明: 如果目标元素对象在后续的代码中只使用一次, 也可以直接在定位元素结束后, 直接调用输入方法实现操作
driver.find_element_by_tag_name('input').send_keys('admin')

'''
以下为错误样例: 不能使用对象变量接收元素操作方法的结果!!!
element = driver.find_element_by_tag_name('input').send_keys('admin')
'''


# 4. 观察效果
sleep(3)

# 5. 关闭页面
driver.quit()

动图演示效果: 

 定位超链接元素方法

selenium提供了两种专门定位超链接的方法: link_textpartial_link_text

'''
前者的超链接文本信息必须写全, 后者只需要写一部分, 但是也要保证其唯一性!
'''
浏览器对象.find_element(By.LINK_TEXT,'超链接文本信息')
浏览器对象.find_element(By.PARTIAL_LINK_TEXT,'部分超链接文本信息')

代码示例: 打开百度首页--通过partial_link_text定位某个热点新闻并打开--通过link_text定位"新闻"并打开

'''
Web自动化基本代码
'''
from time import sleep

# 1.导入模块
from selenium import webdriver
from selenium.webdriver.common.by import By

# 2.创建浏览器对象
driver = webdriver.Chrome()

# 3.打开网页
driver.get('https://www.baidu.com')

# 需求根据partial_link_test定位元素: 公安部网安局|打击加油机作弊
sleep(1)
driver.find_element(By.PARTIAL_LINK_TEXT,'公安部').click()

# 需求根据link_test定位元素: 新闻
sleep(1)
driver.find_element(By.LINK_TEXT,'新闻').click()

# 4.观察网页
sleep(3)

# 5.关闭网页
driver.quit()

动图演示效果:

 XPath定位方法

  1. XPath是XML Path的简写, 它是一门在XML文档中查找元素信息的语言.
  2. HTML可以看作是XML的一种实现, 所以Selenium用户可以使用这种强大的语言在Web页面中定位元素.
  3. XPath定位元素的策略有很多种, 但是定位方法都是同一个:find_element_by_xpath('XPath策略')
浏览器对象.find_element(By.XPATH,'XPath策略')

# 可用, 但不推荐
浏览器对象.find_element_by_xpath('XPath策略')

路径策略

说明:


绝对路径: 从最外层元素到指定元素之间所有经过元素层级的路径
1.绝对路径以/htm1根节点开始,使用/来分隔元素层级;
如:/html/body/div/fieldset./p[1]/input
2.绝对路径对页面结构要求比较严格,不建议使用


相对路径: 匹配任意层级的元素,不限制元素的位置
1.相对路径以//开始
如://input (页面中所有input标签下的部分) 或者 //* (当前页面)

路径值获取方法

注意: 使用相对路径时, 需要注意方法参数的内外引号嵌套问题(参数用单引号框住)

代码示例: 打开注册登陆页面--使用XPath路径策略定位--输入用户名admin(绝对路径)--输入密码123(相对路径)

"""
XPath:路径策略
"""
# 1. 导入模块
from time import sleep

from selenium import webdriver
from selenium.webdriver.common.by import By

# 2. 实例化浏览器对象
driver = webdriver.Chrome()
# 3. 打开页面
driver.get('file:///D:/%E6%B3%A8%E5%86%8C%E9%A1%B5%E9%9D%A2.html')

# 需求:打开注册A.html页面,完成以下操作
# 1).使用绝对路径定位用户名输入框,并输入:admin
driver.find_element(By.XPATH,'/html/body/div/fieldset/form/p[1]/input').send_keys('admin')
# 2).暂停2秒
sleep(1)
# 3).使用相对路径定位密码输入框,并输入:123
'''
注意: 使用相对路径时, 需要注意方法参数的内外引号嵌套问题
'''

driver.find_element(By.XPATH, '//*[@id="passwordA"]').send_keys('123')

# 4. 展示效果
sleep(3)
# 5. 退出浏览器
driver.quit()

动图演示效果:

元素属性策略

//标签名[@属性名='属性值'] #语法1
//*[@属性名='属性值']      #语法2

注意:

1. 目标元素的有些属性和属性值, 可能存在多个相同特征的元素, 需要注意其唯一性

2. 如果元素的class属性值有多个, 则需要传入全部的属性值!!

代码示例:打开注册页面--使用属性策略定位元素--输入用户名admin--输入邮箱123@qq.com

"""
XPath:利用元素属性策略注意事项
"""
# 1. 导入模块
from time import sleep

from selenium import webdriver
from selenium.webdriver.common.by import By

# 2. 实例化浏览器对象
driver = webdriver.Chrome()
# 3. 打开页面
driver.get('file:///D:/%E6%B3%A8%E5%86%8C%E9%A1%B5%E9%9D%A2.html')


# //*[@属性名='属性值']
# 说明: (// 任意层级) (* 任意标签名)

'''
注意: 目标元素的有些属性和属性值, 可能存在多个相同特征的元素, 需要注意唯一性.
'''
driver.find_element(By.XPATH,'//*[@type="text"]').send_keys('admin')

'''
注意: 与 class_name 方法不同的是, 如果使用具有多个值的 class 属性, 则需要传入全部的属性值!
'''
driver.find_element(By.XPATH,'//*[@class="emailA dzyxA"]').send_keys('123@qq.com')

# 4. 展示效果
sleep(3)
# 5. 退出浏览器
driver.quit()

动图演示效果:

属性与逻辑结合策略

//*[@属性1="属性值1" and @属性2="属性值2"] #语法

注意: 多个属性值由 and 连接, 每一个属性都要以@开头, 可以根据需求使用更多的属性值.

代码示例: 打开注册页面--使用属性与逻辑结合的策略--在test1输入框中输入"软件测试001"

"""
XPath: 属性和逻辑结合
"""
# 1. 导入模块
from time import sleep

from selenium import webdriver
from selenium.webdriver.common.by import By

# 2. 实例化浏览器对象
driver = webdriver.Chrome()
# 3. 打开页面
driver.get('file:///D:/%E6%B3%A8%E5%86%8C%E9%A1%B5%E9%9D%A2.html')

'''
属性和逻辑集合: 解决目标元素单个属性和属性值无法定位为一个元素的问题时使用
语法: //*[@属性1="属性值1" and @属性2="属性值2"]
注意: 多个属性值由 and 连接, 每一个属性都要由@开头, 可以根据需求使用更多属性值
'''

# 使用属性与逻辑结合定位策略,在test1对应的输入框里输入:admin
driver.find_element(By.XPATH,'//*[@name="user" and @class="login"]').send_keys('软件测试001')

# 4. 展示效果
sleep(3)
# 5. 退出浏览器
driver.quit()

动图演示效果:

层级与属性结合策略

目标元素无法直接定位, 可以考虑先定位其父层级或祖辈层级, 再获取目标元素.

父层级定位策略/目标元素定位策略

代码示例:打开注册页面--使用层级与属性结合的策略--在test1输入框中输入"软件测试001"

"""
XPath 策略:层级与属性结合
"""
# 1. 导入模块
from time import sleep

from selenium import webdriver
from selenium.webdriver.common.by import By

# 2. 实例化浏览器对象
driver = webdriver.Chrome()
# 3. 打开页面
driver.get('file:///D:/%E6%B3%A8%E5%86%8C%E9%A1%B5%E9%9D%A2.html')

'''
层级与属性结合: 目标元素无法直接定位, 可以考虑先定位其父层级或祖辈层级, 再获取目标元素
语法: 父层级定位策略/目标元素定位策略
'''

# 使用层级与属性结合定位策略,在test1对应的输入框里输入:admin
driver.find_element(By.XPATH,'//*[@id="p1"]/input').send_keys('软件测试001')

# 4. 展示效果
sleep(3)
# 5. 退出浏览器
driver.quit()

动图演示效果:

其他策略

#通过给定属性值的任意部分内容进行元素定位
//*[contains(@属性名,'属性值的部分内容')] 
#通过给定属性值的开头部分内容进行元素定位
//*[starts-with(@属性名,'属性值的开头部分内容')] 
#通过全部文本信息进行元素定位
//*[text()="文本信息"]

CSS定位方法

  1. 通过CSS的选择器语法定位元素
  2. Selenium框架官方推荐使用CSS, 其定位效率远高于XPath
  3. CSS选择策略有很多, 但都用同一个定位方法: find_element_by_css_selector('CSS策略')
浏览器对象.find_element(By.CSS_SELECTOR,'选择器策略')

# 可用, 但不推荐
浏览器对象.find_element_by_css_selector('选择器策略')

四种策略

CSS策略:id选择器/class选择器/标签选择器/属性选择器

#id属性值

.class属性值

[属性名='属性值']
标签名[属性名='属性值']

标签名

代码示例:分别用以上方法定位用户名, 密码, 电话号码. 输入恰当的值; 并点击注册.

"""
CSS 策略: 四种
"""
# 1. 导入模块
from time import sleep

from selenium import webdriver
from selenium.webdriver.common.by import By

# 2. 实例化浏览器对象
driver = webdriver.Chrome()
# 3. 打开页面
driver.get('file:///D:/%E6%B3%A8%E5%86%8C%E9%A1%B5%E9%9D%A2.html')

# 1).使用CSS定位方式中id选择器定位用户名输入框,并输入:admin
# 语法: #id属性值
driver.find_element(By.CSS_SELECTOR,'#userA').send_keys('admin')

# 2).使用CSS定位方式中属性选择器定位密码输入框,并输入:123456
# 语法 1: [属性名="属性值"]
# 语法 2: 标签名[属性名="属性值"]
# driver.find_element_by_css_selector('input[placeholder="请输入密码"]').send_keys('123456')
driver.find_element(By.CSS_SELECTOR,'[placeholder="请输入密码"]').send_keys('123456')

# 3).使用CSS定位方式中class选择器定位电话号码输入框,并输入:18600000000
# 语法: .class属性值
driver.find_element(By.CSS_SELECTOR,'.telA').send_keys('18600000000')
sleep(2)

# 4).使用CSS定位方式中元素选择器定位注册按钮,并点击
# 说明: 元素选择器又名标签选择器
# 语法: 标签名
driver.find_element(By.CSS_SELECTOR,'button').click()

# 4. 展示效果
sleep(3)
# 5. 退出浏览器
driver.quit()

动图演示效果:

层级选择器

父层级策略>子层级策略  #父子层级关系
祖辈策略 后代策略 #祖辈后代层级关系
#父子层级关系也可以使用空格表示

代码示例: 分别用以上方法定位用户名,输入admin

"""
CSS 策略:层级选择器
"""
# 1. 导入模块
from time import sleep

from selenium import webdriver
from selenium.webdriver.common.by import By

# 2. 实例化浏览器对象
driver = webdriver.Chrome()
# 3. 打开页面
driver.get('file:///D:/%E6%B3%A8%E5%86%8C%E9%A1%B5%E9%9D%A2.html')

# 需求:打开注册A.html页面,完成以下操作
# 1).使用CSS定位方式中的层级选择器定位用户名输入框,并输入:admin

# 层级选择器
# 父子层级关系: 父层级策略>子层级策略
# driver.find_element(By.CSS_SELECTOR,'#pa>input').send_keys('admin')

# 祖辈后代层级关系: 祖辈策略 后代策略
driver.find_element(By.CSS_SELECTOR,'form [placeholder="请输入用户名"]').send_keys('admin')

# 注意: 父子层级关系中也可以使用空格连接上下层级策略
'''
扩展: XPath 祖辈和后代关系: 只需要使用//连接祖辈和后代元素即可
driver.find_element(By.XPATH,'//form//*[@id="userA"]').send_keys('admin')
'''

# 4. 展示效果
sleep(3)
# 5. 退出浏览器
driver.quit()

动图演示效果:

其他策略

标签名[属性名*="属性值任意部分内容"] #根据给出的属性值任意部分内容定位元素

标签名[属性名$="属性值结尾部分内容"] #根据给出的属性值结尾部分内容定位元素

标签名[属性名^="属性值开头部分内容"] #根据给出的属性值开头部分内容定位元素

本篇文章就暂告一段落了; 对于UI自动化测试, 本篇文章是基础, 同时也是重中之重, 希望能够对铁子们有所帮助; 如果可以的话可以给我一个小小的赞吗~笔芯💓

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/952473.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux 下信号的保存和处理

信号的几个状态 信号抵达: 当接收到的信号被处理时, 此时就成为信号的抵达信号的未决: 从信号的产生到信号抵达这个时间段之间, 称为信号未决信号阻塞: 当进程设置了某个信号为阻塞后, 这个进程就不会在接收到这个信号信号忽略: 将信号设置为忽略后, 接收到这个信号, 对这个信…

IntelliJ IDEA中Maven项目的配置、创建与导入全攻略

大家好&#xff0c;我是袁庭新。 IntelliJ IDEA是当前最流行的Java IDE&#xff08;集成开发环境&#xff09;之一&#xff0c;也是业界公认最好用的Java开发工具之一。IntelliJ IDEA支持Maven的全部功能&#xff0c;通过它我们可以很轻松地实现创建Maven项目、导入Maven项目、…

深度学习笔记11-优化器对比实验(Tensorflow)

&#x1f368; 本文为&#x1f517;365天深度学习训练营中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 目录 一、导入数据并检查 二、配置数据集 三、数据可视化 四、构建模型 五、训练模型 六、模型对比评估 七、总结 一、导入数据并检查 import pathlib,…

JavaEE之定时器及自我实现

在生活当中&#xff0c;有很多事情&#xff0c;我们不是立马就去做&#xff0c;而是在规定了时间之后&#xff0c;在到该时间时&#xff0c;再去执行&#xff0c;比如&#xff1a;闹钟、定时关机等等&#xff0c;在程序的世界中&#xff0c;有些代码也不是立刻执行&#xff0c;…

Qt学习笔记第81到90讲

第81讲 串口调试助手实现自动发送 为这个名叫“定时发送”的QCheckBox编写槽函数。 想要做出定时发送的效果&#xff0c;必须引入QT框架下的毫秒级定时器QTimer&#xff0c;查阅手册了解详情。 在widget.h内添加新的私有成员变量&#xff1a; QTimer *timer; 在widget类的构造…

【LeetCode】力扣刷题热题100道(16-20题)附源码 容器 子数组 数组 连续序列 三数之和(C++)

目录 1.盛最多水的容器 2.和为K的子数组 3.最大子数组和 4.最长连续序列 5.三数之和 1.盛最多水的容器 给定一个长度为 n 的整数数组 height 。有 n 条垂线&#xff0c;第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线&#xff0c;使得它们与 x 轴…

AI多模态技术介绍:视觉语言模型(VLMs)指南

本文作者&#xff1a;AIGCmagic社区 刘一手 AI多模态全栈学习路线 在本文中&#xff0c;我们将探讨用于开发视觉语言模型&#xff08;Vision Language Models&#xff0c;以下简称VLMs&#xff09;的架构、评估策略和主流数据集&#xff0c;以及该领域的关键挑战和未来趋势。通…

jenkins入门13--pipeline

Jenkins-pipeline(1)-基础 为什么要使用pipeline 代码&#xff1a;pipeline 以代码的形式实现&#xff0c;通过被捡入源代码控制&#xff0c; 使团队能够编译&#xff0c;审查和迭代其cd流程 可连续性&#xff1a;jenkins 重启 或者中断后都不会影响pipeline job 停顿&#x…

【线性代数】通俗理解特征向量与特征值

这一块在线性代数中属于重点且较难理解的内容&#xff0c;下面仅个人学习过程中的体会&#xff0c;错误之处欢迎指出&#xff0c;有更简洁易懂的理解方式也欢迎留言学习。 文章目录 概念计算几何直观理解意义PS.适用 概念 矩阵本身就是一个线性变换&#xff0c;对一个空间中的…

SQL多表联查、自定义函数(字符串分割split)、xml格式输出

记录一个报表的统计&#xff0c;大概内容如下&#xff1a; 多表联查涉及的报表有&#xff1a;房间表、买家表、合同表、交易表、费用表、修改记录表 注意&#xff1a;本项目数据库使用的是sqlserver&#xff08;mssql&#xff09;&#xff0c;非mysql。 难点1:业主信息&#…

python学opencv|读取图像(三十)使用cv2.getAffineTransform()函数倾斜拉伸图像

【1】引言 前序已经学习了如何平移和旋转缩放图像&#xff0c;相关文章链接为&#xff1a; python学opencv|读取图像&#xff08;二十七&#xff09;使用cv2.warpAffine&#xff08;&#xff09;函数平移图像-CSDN博客 python学opencv|读取图像&#xff08;二十八&#xff0…

C语言数据结构与算法(排序)详细版

大家好&#xff0c;欢迎来到“干货”小仓库&#xff01;&#xff01; 很高兴在CSDN这个大家庭与大家相识&#xff0c;希望能在这里与大家共同进步&#xff0c;共同收获更好的自己&#xff01;&#xff01;无人扶我青云志&#xff0c;我自踏雪至山巅&#xff01;&#xff01;&am…

【竞技宝】CS2:HLTV2024选手排名TOP4-NiKo

北京时间2025年1月11日,HLTV年度选手排名正在持续公布中,今日凌晨正式公布了今年的TOP4选手为G2(目前已转为至Falcons)战队的NiKo。 选手简介 NiKo是一名来自波黑的CS职业选手,现年26岁。作为DOTA2饱负盛名的职业选手,NiKo在CS1.6时代就已经开始征战职业赛场。2012年,年仅15岁…

IOS界面传值-OC

1、页面跳转 由 ViewController 页面跳转至 NextViewController 页面 &#xff08;1&#xff09;ViewController ViewController.h #import <UIKit/UIKit.h>interface ViewController : UIViewControllerend ViewController.m #import "ViewController.h" …

树的模拟实现

一.链式前向星 所谓链式前向星&#xff0c;就是用链表的方式实现树。其中的链表是用数组模拟实现的链表。 首先我们需要创建一个足够大的数组h&#xff0c;作为所有结点的哨兵位。创建两个足够大的数组e和ne&#xff0c;一个作为数据域&#xff0c;一个作为指针域。创建一个变…

【ArcGIS微课1000例】0138:ArcGIS栅格数据每个像元值转为Excel文本进行统计分析、做图表

本文讲述在ArcGIS中,以globeland30数据为例,将栅格数据每个像元值转为Excel文本,便于在Excel中进行统计分析。 文章目录 一、加载globeland30数据二、栅格转点三、像元值提取至点四、Excel打开一、加载globeland30数据 打开配套实验数据包中的0138.rar中的tif格式栅格土地覆…

Redis集群模式下主从复制和哨兵模式

Redis主从复制是由一个Redis服务器或实例(主节点)来控制一个Redis服务器或实例(从节点),从节点从主节点获取数据更新数据 集群模式下主从数据复制过程 从服务器连接到主服务器,发送SYNC命令。主服务器接收到SYNC命令后,开始执行BGSAVE命令生成RDB文件。主服务器BGSAVE执…

高难度下的一闪---白金ACT游戏设计思想的一点体会

1、以前光环的开发者好像提出过一个理论&#xff0c;大意是游戏要让玩家保持30秒的循环&#xff0c; 持续下去。大意跟后来的心流接近。 2、根据我自身的开发体会&#xff0c;想要保持正回路&#xff0c;并不容易。 一个是要保持适当的挑战性&#xff0c;毫无难度的低幼式玩法…

页面滚动下拉时,元素变为fixed浮动,上拉到顶部时恢复原状,js代码以视频示例

页面滚动下拉时,元素变为fixed浮动js代码 以视频示例 <style>video{width:100%;height:auto}.div2,#float1{position:fixed;_position:absolute;top:45px;right:0; z-index:250;}button{float:right;display:block;margin:5px} </style><section id"abou…

算法题(32):三数之和

审题&#xff1a; 需要我们找到满足以下三个条件的所有三元组&#xff0c;并存在二维数组中返回 1.三个元素相加为0 2.三个元素的下标不可相同 3.三元组的元素不可完全相同 思路&#xff1a; 混乱的数据不利于进行操作&#xff0c;所以我们先进行排序 我们可以采取枚举的方法进…