当前位置: 首页 > news >正文

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 sleepfrom 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 sleepfrom 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 sleepfrom 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 sleepfrom 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 sleepfrom 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 sleepfrom 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 sleepfrom 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 sleepfrom 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自动化测试, 本篇文章是基础, 同时也是重中之重, 希望能够对铁子们有所帮助; 如果可以的话可以给我一个小小的赞吗~笔芯💓

相关文章:

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

欢迎来到阿妮莫的学习小屋慢也好&#xff0c;步子小也好&#xff0c;在往前走就好 目录 自动化测试 简介 作用 分类 优缺点 优点 缺点(误区) UI自动化测试 自动化测试使用场景 自动化测试实现时间 Selenium框架 特点 Web自动化测试环境部署 Selenium包安装 浏览…...

多行输入模式(dquote> 提示符)double quote(双引号)

文章目录 1、引号不匹配具体原因解决办法如何避免此问题 2、double quote&#xff08;双引号&#xff09;出现原因解决办法预防措施 ~/Downloads/productqualification-develop git:[main] git commit -m "漏添加到暂存区的代码“ dgqdgqdeMac-mini productqualification-…...

【Uniapp-Vue3】原生事件监听及组件内置事件处理

如果我们想给元素添加一个事件就要使用到v-on&#xff0c;也可以简写为&#xff1a; <标签名 v-on:事件名"函数"></标签名> 或简写为 <标签名 事件名"函数"></标签名> 比如我们想要实现点击一下元素&#xff0c;num就1&#xff0c…...

微软 2024 最新技术全景洞察

亲爱的小伙伴们&#x1f618;&#xff0c;在求知的漫漫旅途中&#xff0c;若你对深度学习的奥秘、Java 与 Python 的奇妙世界&#xff0c;亦或是读研论文的撰写攻略有所探寻&#x1f9d0;&#xff0c;那不妨给我一个小小的关注吧&#x1f970;。我会精心筹备&#xff0c;在未来…...

PHP语言的并发编程

PHP语言的并发编程 引言 随着互联网技术的迅速发展&#xff0c;Web 应用的复杂性和用户并发请求的增加&#xff0c;要求开发者在构建高性能应用时考虑并发编程。并发编程允许程序在同一时间执行多个任务&#xff0c;这对于处理高流量网站、API 和实时应用程序至关重要。虽然 …...

Nginx 解析漏洞复现

漏洞原理 该漏洞与Nginx、php版本无关&#xff0c;属于用户配置不当造成的解析漏洞。主要是由于下面两个配置的错误&#xff1a; cgi.fix_pathinfo1&#xff0c;该配置项的作用是如果访问的.php文件不存在&#xff0c;则采用上层路径&#xff0c;例如访问/test.png/.php,一般…...

使用XAML语言仿写BiliBil登录界面

实现步骤 实现左右布局 使用了Grid两列的网格布局&#xff0c;第一列宽度占35%&#xff0c;第二列宽度占65%。使用容器布局Border包裹左右布局内容&#xff0c;设置背景色、设置圆角 <!-- 定义两列--> <Grid.ColumnDefinitions><ColumnDefinition Width &quo…...

Kubernetes Gateway API-4-TCPRoute和GRPCRoute

1 TCPRoute 目前 TCP routing 还处于实验阶段。 Gateway API 被设计为与多个协议一起工作&#xff0c;TCPRoute 就是这样一个允许管理TCP流量的路由。 在这个例子中&#xff0c;我们有一个 Gateway 资源和两个 TCPRoute 资源&#xff0c;它们按照以下规则分配流量&#xff1…...

【C++动态规划 前缀和】3250. 单调数组对的数目 I|1897

本文涉及知识点 C动态规划 C算法&#xff1a;前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 LeetCode3250. 单调数组对的数目 I 给你一个长度为 n 的 正 整数数组 nums 。 如果两个 非负 整数数组 (arr1, arr2) 满足以下条件&#xff0c;我们称它们是 单调…...

【机器学习:五、使梯度下降法更快收敛的技巧】

1. 特征缩放 1.1 特征缩放的作用 特征缩放是一种将不同特征值归一化到相似范围的技术&#xff0c;可以显著提高梯度下降法的收敛速度。 作用&#xff1a; 避免数值差异导致的优化困难&#xff1a;当特征值范围差异较大时&#xff0c;代价函数呈现“长而窄”的形状&#xff0…...

系统思考—结构影响行为

托尔斯泰在《安娜卡列尼娜》中说&#xff1a;“幸福的家庭都是相似的&#xff0c;不幸的家庭各有各的不幸。”在企业经营管理中也如此——企业剧本总是相似&#xff0c;只是男女主角不同。 但无论外在表现如何变化&#xff0c;真正决定企业命运的&#xff0c;是系统结构。 企业…...

WorldQuant Settings 配置项名词解释

中文翻译及通俗解释 语言(Language) 解释:BRAIN 平台支持使用快速表达式(Fast Expression)语言。 例子:快速表达式就像写公式,比如 price + volume,简单易懂且高效。更多内容可以参考“可用操作符”。 工具类型(Instrument type) 解释:目前只能使用“股票”作为工…...

mybatisPlus动态sql语句 ${ew.sqlSegment}

mybatis-plus的${ew.sqlSegment}&#xff0c;${ew.sqlSelect}&#xff0c;${ew.customSqlSegment} ew是mapper方法里的Param(Constants.WRAPPER) Wrapper queryWrapper对象 简答介绍&#xff1a; ${ew.sqlSelect}&#xff1a;拼接select SQL主体 Select("select ${ew.…...

ATGM336H-5N71支持多种卫星导航系统的定位模块

ATGM336H-5N7 1是 9.7X10.1尺寸&#xff0c;AT6558芯片&#xff0c;导航模块&#xff0c;GPSBDSGLONASS定位&#xff0c;16.369M晶振&#xff0c;标准输出 &#xff0c;电源2.7V~3.6V, 支持 UART0和UART1接口 . ATGM336H-5N特性&#xff1a; Flash TCXO 天线检测 天线过流保护 …...

Maven中管理SNAPSHOT版本含义及作用

在开发过程中突然产生了一个疑问&#xff1a;IDEA中 maven deploy的依赖包的版本号,比如 1.0.0-SNAPSHOT是在哪配置的&#xff1f;在远程仓库中的版本和这个有关系吗 &#xff1f; 在 Maven 中&#xff0c;-SNAPSHOT 后缀是用于标识项目版本为快照&#xff08;Snapshot&#xf…...

从技术到艺术:探索大模型提示词工程,给您的AI作品去去味

1. 增加互动性元素 请在文章中增加互动性元素&#xff0c;如提问、调查或互动链接&#xff0c;鼓励读者参与和反馈&#xff0c;提高文章的互动性和读者的参与度。 2. 加强视觉元素的应用 请在文章中适当加入图表、图片和其他视觉元素&#xff0c;增强文章的视觉效果&#xff0…...

OSPF - 1类LSA(Router-LSA)

点击返回LSA对照表 1类LSA是OSPF计算最原始的材料&#xff0c;他会泛洪发给所有的路由器 LSA是包含在LSU中的&#xff0c;一条LSU能够携带多条LSA options位所有LSA都会有&#xff0c;用于标记起源于什么类型的区域&#xff0c;具体查看文章【邻居建立】 flags位是一类LSA特…...

HTTP 协议中,GET、PUT、POST、DELETE、OPTIONS 和 PATCH 区别

在 HTTP 协议中&#xff0c;GET、PUT、POST、DELETE、OPTIONS 和 PATCH 是常见的请求方法&#xff08;HTTP Methods&#xff09;&#xff0c;用于定义客户端与服务器之间的交互方式。每种方法都有特定的语义和用途。以下是它们的详细解释&#xff1a; 1. GET 用途: 用于从服务…...

黄仁勋演讲总结(2种显卡,1个开源大模型,1个数据采集平台)

研发算力显卡RTX50系列&#xff0c;PC端显卡GB10&#xff0c;开源大模型Cosmos&#xff08;用于机器人和自动驾驶&#xff09;&#xff0c; Isaac GR00T&#xff08;人形机器人的数据采集平台&#xff09;。 新一代 RTX 50 系列显卡 RTX 50 系列 GPU&#xff0c;相对之前系列&a…...

支持向量机算法(一):像讲故事一样讲明白它的原理及实现奥秘

1、支持向量机算法介绍 支持向量机&#xff08;Support Vector Machine&#xff0c;SVM&#xff09;是一种基于统计学习理论的模式识别方法&#xff0c; 属于有监督学习模型&#xff0c;主要用于解决数据分类问题。SVM将每个样本数据表示为空间中的点&#xff0c;使不同类别的…...

掌握RabbitMQ:全面知识点汇总与实践指南

前言 RabbitMQ 是基于 AMQP 高级消息队列协议的消息队列技术。 特点&#xff1a;它通过发布/订阅模型&#xff0c;实现了服务间的高度解耦。因为消费者不需要确保提供者的存在。 作用&#xff1a;服务间异步通信&#xff1b;顺序消费&#xff1b;定时任务&#xff1b;请求削…...

Ansys Discovery 优化模式:掌握网格划分方法

本篇博客文章介绍了 Ansys Discovery 中高级 CFD 仿真的 Refine 模式下可用的网格划分方法。上一篇文章讨论了 Explore 模式中可用的网格划分技术。 Refine 模式下的高级网格划分技术 使用 Ansys Discovery 时&#xff0c;Refine 模式提供的网格划分技术比 Explore 模式多。这…...

CentOS: RPM安装、YUM安装、编译安装(详细解释+实例分析!!!)

目录 1.什么是RPM 1.1 RPM软件包命名格式 1.2RPM功能 1.3查询已安装的软件&#xff1a;rpm -q 查询已安装软件的信息 1.4 挂载&#xff1a;使用硬件&#xff08;光驱 硬盘 u盘等&#xff09;的方法&#xff08;重点&#xff01;&#xff01;&#xff01;&#xff09; 1…...

(转)rabbitmq怎么保证消息不丢失?

RabbitMQ 可以通过以下多种机制来保证消息不丢失&#xff1a; 生产阶段 - 持久化队列和交换器&#xff1a; - 在声明队列和交换器时&#xff0c;将 durable 参数设置为 true &#xff0c;确保它们是持久化的。这样&#xff0c;即使 RabbitMQ 节点重新启动&#xff0c;队列和交…...

List ---- 模拟实现LIST功能的发现

目录 listlist概念 list 中的迭代器list迭代器知识const迭代器写法list访问自定义类型 附录代码 list list概念 list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代。list的底层是双向链表结构&#xff0c;双向链表中每个元素…...

电力场景输电线覆冰分割数据集labelme格式1227张2类别

数据集格式&#xff1a;labelme格式(不包含mask文件&#xff0c;仅仅包含jpg图片和对应的json文件) 图片数量(jpg文件个数)&#xff1a;1227 标注数量(json文件个数)&#xff1a;1227 标注类别数&#xff1a;2 标注类别名称:["ice","powerline"] 每个…...

springboot 日志实现

日志 日志框架可以分为 日志门面&#xff08;Facade&#xff09; 和 日志实现&#xff08;Implementation&#xff09;&#xff0c;Spring Boot 使用了 SLF4J 作为日志门面&#xff0c;Logback 或 Log4j2 作为日志实现。 日志门面以及日志实现 日志门面 日志门面&#xff0…...

Ubuntu Server安装谷歌浏览器

背景 服务器上跑爬虫服务器需要安装谷歌浏览器 安装 wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb### sudo apt install ./google-chrome-stable_current_amd64.deb...

毕业项目推荐:基于yolov8/yolov5/yolo11的动物检测识别系统(python+卷积神经网络)

文章目录 概要一、整体资源介绍技术要点功能展示&#xff1a;功能1 支持单张图片识别功能2 支持遍历文件夹识别功能3 支持识别视频文件功能4 支持摄像头识别功能5 支持结果文件导出&#xff08;xls格式&#xff09;功能6 支持切换检测到的目标查看 二、数据集三、算法介绍1. YO…...

计算机网路HTTP、TCP详解

HTTP HTTP基本概念 HTTP&#xff08;超文本传输协议&#xff09;&#xff1a;HTTP是在计算机世界中两点之间传输文字、图片、视频等超文本内容数据的约束与规范。 常见状态码&#xff1a; 2xx&#xff1a;报文被收到&#xff0c;已经在正确处理中。 3xx&#xff1a;重定向…...

小程序未来趋势预测:技术革新与市场前景

一、引言 在数字化转型加速的时代&#xff0c;小程序作为一种轻量级、无需下载安装的应用形式&#xff0c;凭借其快速开发、易于使用的特点&#xff0c;迅速崛起并成为企业和开发者拓展业务的重要工具。随着移动互联网的进一步普及和用户对便捷应用体验的需求增长&#xff0c;…...

JavaEE初阶——计算机工作原理

一、什么是JavaEE JavaEE&#xff08;Java Platform&#xff0c;Enterprise Edition&#xff09;是sun公司&#xff08;2009年4月20日甲骨文将其收购&#xff09;推出的企业级应用程序版本。这个版本以前称为 J2EE。能够帮助我们开发和部署可移植、健壮、可伸缩且安全的服务器…...

Web前端ui框架

文章目录 Element简介 Ant Design vue简介关键特点&#xff1a; iview简介 Element 官网&#xff1a;https://element.eleme.cn/#/zh-CN/component/installation添加链接描述 简介 Elementui 一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库 Ant Design …...

炸弹 (boom.c)

炸弹 (boom.c) 时间限制: 800ms 内存限制: 256000KiB 进度: 57/12406 0.5% 题目描述 出题助教: Sakiyary 验题助教: Corax、XiEn、ErinwithBMQ、runz、MacGuffin、Bob 维多利亚的腐烂荒野上出现了 N 个魔物&#xff0c;你和小维需要抓紧时间调配炸弹对付它们。 荒野可以视…...

【C语言】可移植性陷阱与缺陷(八): 随机数的大小

在C语言编程中&#xff0c;随机数的生成和使用是一个常见的需求。然而&#xff0c;由于不同平台上的C标准库实现可能存在差异&#xff0c;随机数的生成和使用也可能面临可移植性问题。本文将深入探讨C语言中随机数的大小与可移植性相关的陷阱与缺陷&#xff0c;并提供相应的解决…...

SSL VPN

SSL VPN 是什么&#xff1f; 是采用SSL/TLS协议来实现远程接入的一种轻量级 VPN 技术。利用 SSL 协议提供的基于证书的身份认证、数据加密和消息完整性验证机制&#xff0c;可以为应用层之间的通信建立安全连接。因为 SSL 协议内置于浏览器中&#xff0c;使用 SSL VPN 可以免于…...

C语言:函数

目录 1.函数的解释 2.C语言函数的分类 2.1库函数 2.2自定义函数 2.2.1自定义函数的语法格式 2.2.2自定义函数的实践 (1)第一题&#xff1a;欢迎光临 (2)第二题 打印数字的平方 ​编辑 (3)第三题 计算和 3.函数的参数 3.1值传递的表现 --- 形参 3.2地址传递的表现 -…...

Vue 环境配置与项目创建指南

1. 前置要求 在开始配置 Vue 开发环境之前&#xff0c;需要确保以下工具已安装&#xff1a; Node.js&#xff1a;Vue 的构建工具依赖 Node.js。 npm 或 yarn&#xff1a;Node.js 自带 npm 包管理工具&#xff0c;也可以选择安装 yarn。 安装 Node.js 前往 Node.js 官网 下…...

关于物联网的基础知识(三)——物联网技术架构:连接万物的智慧之道!连接未来的万物之网!

成长路上不孤单&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a; 【14后&#x1f60a;///计算机爱好者&#x1f60a;///持续分享所学&#x1f60a;///如有需要欢迎收藏转发///&#x1f60a;】 今日分享关于物联网的基础知识&#xff08;三&a…...

iOS - Tagged Pointer

1. 基本结构 // Tagged Pointer 的内存布局 union TaggedPointer {uintptr_t bits; // 完整的指针值struct {uintptr_t data : 60; // 数据部分uintptr_t tag : 4; // 类型标记};// 扩展类型struct {uintptr_t extData : 52; // 扩展数据uintptr_t extTag : …...

基于SpringBoot的音乐网站与分享平台

基于SpringBoot的音乐网站与分享平台 摘要1. 研究背景2.研究内容3.系统功能 3.1前台首页功能模块3.2在线听歌功能模块3.3后台登录功能模块3.4在线听歌管理模块 4.部分功能代码实现5.源码分享(免费获取) 需要源码联系我即可(免费获取)~ ??大家点赞、收藏、关注、评论啦 、查…...

【机器学习篇】 科技异次元的超强 “魔杖”,开启奇幻新程

一起开启这场旅行吧&#xff0c;关注博主&#xff0c;点赞支持不迷路&#xff0c;下面一同欣赏本篇的美妙吧&#xff01;&#xff01; &#xff01; 博主主页&#xff1a; 羑悻的小杀马特.-CSDN博客 在当今科技飞速发展的时代&#xff0c;机器学习宛如一把来自科技异次元的超强…...

opencv CV_TM_SQDIFF未定义标识符

opencv CV_TM_SQDIFF未定义标识符 opencv4部分命名发生变换&#xff0c;将CV_WINDOW_AUTOSIZE改为WINDOW_AUTOSIZE&#xff1b;CV_TM_SQDIFF_NORMED改为TM_SQDIFF_NORMED。...

OneFlow的简单介绍

OneFlow 是北京一流科技有限公司旗下的采用全新架构设计的开源工业级通用深度学习框架。以下是关于 OneFlow 的详细介绍&#xff1a; 本篇文章的目录 特点 功能 应用场景 发展历程 特点 简洁易用的接口&#xff1a;为深度学习相关的算法工程师提供一套简洁易用的用户接口…...

如何配置【Docker镜像】加速器+【Docker镜像】的使用

一、配置Docker镜像加速器 1. 安装/升级容器引擎客户端​ 推荐安装1.11.2以上版本的容器引擎客户端 2. 配置镜像加速器​ 针对容器引擎客户端版本大于1.11.2的用户 以root用户登录容器引擎所在的虚拟机 修改 "/etc/docker/daemon.json" 文件&#xff08;如果没有…...

《OpenCV》——模版匹配

文章目录 什么是模版匹配&#xff1f;函数介绍实例 什么是模版匹配&#xff1f; 模板匹配是在一幅图像中寻找与另一幅模板图像最匹配部分的技术。OpenCV 提供了多种模板匹配的方法&#xff0c;它在目标检测、物体识别等众多计算机视觉任务中有广泛的应用。例如&#xff0c;你有…...

【网络安全技术与应用】(选修)实验3 网络侦察

一、实验目的 培养学生综合运用搜索引擎、Whois数据库等手段对目标站点进行侦查的能力,了解站点查询常用的信息源及搜索工具,熟练掌握常见搜索工具的功能及使用技巧。培养学生使用搜索引擎在互联网查找特定设备的能力,熟悉联网设备搜索引擎的功能,熟练掌握设备搜索引擎的使…...

基于XGBoost的集成学习算法

目录 一、XGBoost原理1.1 提升方法&#xff08;Boosting&#xff09;1.2 提升决策树 &#xff08;BDT&#xff09;1.3 梯度提升决策树 &#xff08;GBDT&#xff09;1.4 极限梯度提升&#xff08;XGBoost&#xff09;1.4.1 XGBoost改进1.4.2 XGBoostcsklearn实现1.4.3 XGBoost回…...

【84键矮轴无线键盘】个人使用经历

推荐&#xff1a; 前行者MK84键&#xff08;理由&#xff1a;价格实惠&#xff0c;键位布局好&#xff0c;其他都是可接受程度&#xff09;K3 max&#xff08;理由&#xff1a;除了短命的续航、脚垫容易脱落&#xff0c;已无明显短板&#xff09; 我需要一把在小巧、舒适的主力…...

基于Arduino的FPV头部追踪相机系统

构建FPV头部追踪相机&#xff1a;让你置身于遥控车辆之中&#xff01; 在遥控车辆和模型飞行器的世界中&#xff0c;第一人称视角&#xff08;FPV&#xff09;体验一直是爱好者们追求的目标。通过FPV头部追踪相机&#xff0c;你可以像坐在车辆或飞行器内部一样&#xff0c;自由…...