1.背景
目前公司业务比较稳定,但是日常更新需求需要大量的重复的回归的测试,占用部分时间。为了提高效率可使用UI自动化来减少一部分人员手工执行投入以提高效率,也可以作为日常线上环境主流程功能的回归。
2. 什么类型的项目适合自动化
- 需求不会频繁变动:因为需求频繁变动,页面的功能就会频繁变动
- UI比较稳定:因为UI自动化就是基于UI
- 项目周期较长
- 大量的回归测试任务:大量的重复的回归的测试任务,不断的迭代,需要回归老功能。
- 冒烟测试:针对本次迭代的新功能(核心的、主干的功能,大概10%~20%)进-行冒烟测试。
- 回归测试:对老功能进行回归测试
3. 自动化测试场景
场景列如:
- 打开网站(比如:打开淘宝网站)
- 定位元素(比如:定位到搜索输入框)
- 操作元素(比如:在搜索框中输入秋装,点击搜索)
- 模拟页面动作(比如:下拉、上滑等)
- 断言结果:预期结果与实际结果比对,判断是否通过测试。
- 生成报告
4.UI自动化工具选择
4.1 Seldom VS Macaca
对比结果:
seldom相比较Macaca,seldom支持web/app/api 测试,是一个全功能的测试框架,而且提供脚手架快速创建自动化项目,也集成了测试报告及报告发送的多种方式,最主要有群提供技术支持,便于问题解决。由于Macaca目前用户较少官方不再维护,社区已不再活跃,故目前web端测试方案选择seldom。
4.2 seldom框架
4.2.1.介绍
seldom 基于 unittest 单元测试框架开发,并集成了web/app/api测试库,可进行web UI及APP UI自动化测试以及接口测试
seldom特点
- 支持测试类型(web/app/api)
- 丰富的断言
- 生成随机测试数据
- 用例依赖
- 用例分类标签
- 支持发送(邮件、钉钉、飞书、企微)消息等
- 日志打印
- 缓存cache
- 命令行工具
- 强大的数据驱动(JSON/YAML/CSV/EXCEL)
- HTML/XML报告
- 失败重跑&截图
- 数据库操作(MySQL/sqlite3/Mongodb)
- 支持平台化
4.2.2 安装
pip install seldom
随时体验最新的代码,可以使用下面的命令
pip install -U git+https://github.com/defnngj/seldom.git@master
4.2.3 项目创建
seldom -P mypro
目录结构:
mypro/
├── test_dir/
│ ├── __init__.py
│ ├── test_web_sample.py
│ ├── test_api_sample.py
├── test_data/
│ ├── data.json
├── reports/
└── confrun.py
test_dir/
测试用例目录。test_data/
测试数据文件目录。reports/
测试报告目录。confrun.py
运行测试用例配置文件
4.2.4 用例创建
根据自己的需求编写Web UI
or HTTP
接口自动化测试
用例编写规则 :
- 一个脚本是一个完整的场景,从用户登陆操作到用户退出系统关闭浏览器
- 一个脚本脚本只验证一个功能点,不要试图用户登陆后把所有的功能都进行验证再退出系统
- 尽量只做功能中正向逻辑的验证,不要考虑太多逆向逻辑的验证,逆向逻辑的情况很多
- 脚本之间尽量不要产生关联性
- 用例从手工测试当中选取,尽量选择简单且需要反复回归,稳定且不会经常变化,优先覆盖核心功能
4.2.5 运行测试
seldom 的运行有三种方式:
- main() 方法:在.py 文件中使用seldom.main() 方法。
- seldom 命令:通过sedom 命令指定要运行的目录&文件&类&方法。
- pycharm右键执行:这种方式无法读取到配置,有严重缺陷。
a. main()方法运行测试
创建 test_sample.py
文件,在测试文件中使用main()
方法,如下:
# test_sample.py
import seldom
from seldom import data
class YouTest(seldom.TestCase):
def test_case(self):
"""a simple test case """
self.assertEqual(1+1, 2)
@data([
("case1", "seldom"),
("case2", "XTestRunner"),
])
def test_ddt(self, name, search):
""" ddt case """
print(f"name: {name}, search_key: {search}")
if __name__ == '__main__':
# 指定运行其他目录&文件
seldom.main(path="./") # 指定当前文件所在目录下面的用例。
seldom.main(path="./test_dir/") # 指定当前目录下面的test_dir/ 目录下面的用例。
seldom.main(path="./test_dir/test_sample.py") # 指定测试文件中的用例。
seldom.main(path="D:/seldom_sample/test_dir/test_sample.py") # 指定文件的绝对路径。
# 运行当前文件中的用例
seldom.main() # 默认运行当前文件中所有用例
seldom.main(case="test_sample") # 指定当前文件
seldom.main(case="test_sample.TestCase") # 指定测试类
seldom.main(case="test_sample.TestCase.test_case") # 指定测试用例
# 使用参数化的用例
seldom.main(case="test_sample.TestCase.test_ddt") # 错误用法
seldom.main(case="test_sample.TestCase.test_ddt_0_case1") # 正确用例
b.seldom命令执行
> cd mypro/ # 进入项目根目录
> seldom -p test_dir # 运行目录
> seldom -p test_dir/test_sample.py # 运行文件
> seldom -m test_dir.test_sample # 运行文件
> seldom -m test_dir.test_sample.SampleTest # 运行 SampleTest 测试类
> seldom -m test_dir.test_sample.SampleTest.test_case # 运行 test_case 测试方法
4.2.6 测试报告
seldom 默认生成HTML测试报告,在运行测试文件下自动创建reports目录
定义测试报告
seldom.main(path='testadminLoginTest.py',
title="运营后台登录页面UI测试报告",
description="admin登录",
report="adminlogintest.html",
tester="xxx",
language='zh-CN'
)
- report: 配置报告名称和路径。
- title: 自定义报告的标题。
- tester: 指定自动化测试工程师名字。
- description: 添加报告信息
接入钉钉机器人
- 钉钉uitest群机器人:
- 签名:xxxx
- access_token:xxxx
import seldom
from seldom import DingTalk
# ...
if __name__ == '__main__':
seldom.main()
ding = DingTalk(
access_token="xxxx",
key="",
app_secret="xxxxx",
at_mobiles=[13700000000, 13800000000],
is_at_all=False,
)
ding.sender()
参数说明:
- access_token: 钉钉机器人的 access_token
- key: 如果钉钉机器人安全设置了关键字,则需要传入对应的关键字。
- app_secret: 如果钉钉机器人安全设置了签名,则需要传入对应的密钥。
- at_mobiles: 发送通知钉钉中要@人的手机号列表,如:[137xxx, 188xxx]。
- is_at_all: 是否@所有人,默认为 False, 设为 True 则会@所有人
发送邮件
import seldom
from seldom import SMTP
# ...
if __name__ == '__main__':
report_path = "/you/path/report.html"
seldom.main(report=report_path)
smtp = SMTP(user="[email protected]", password="abc123", host="smtp.126.com")
smtp.sendmail(to="[email protected]", subject="Email title", attachments=report_path, delete=False)
- subject: 邮件标题,默认:Seldom Test Report。
- to: 添加收件人,支持多个收件人: [“[email protected]”, “[email protected]”]。
- attachments: 设置附件,默认发送 HTML 测试报告。
- delete: 是否删除报告&日志。(在服务器上运行自动化,每次都会产生一份报告和日志,手动删除比较麻烦
4.2.7 元素定位
seldom 提供了8中定位方式,与Selenium保持一致。
- id_
- name
- class_name
- tag
- link_text
- partial_link_text
- css
- xpath
self.type(id_="kw", text="seldom")
self.type(name="wd", text="seldom")
self.type(class_name="s_ipt", text="seldom")
self.type(tag="input", text="seldom")
self.type(xpath="//input[@id='kw']", text="seldom")
self.type(css="#kw", text="seldom")
self.click(link_text="hao123")
self.click(partial_link_text="hao")
使用优先级:
ID>Name>CSS>XPath
优先级最高:id ,但id有时是变的,如果id是不变的,可用它来定位
优先级其次:name
优先级更次:css
优先级更次:xpath
使用注意点 :
-
如果 HTML 的 id 是可用的、唯一的,那么它就是在页面上定位元素的首选方法
-
如果没有唯一的 id或name,那则使用XPath 和 CSS 定位, XPath 选择器运行速度较慢
3.尽量让开发把关键元素加上id或name属性,减少不合理的页面元素
4.2.8 断言
# 断言标题是否等于"title"
self.assertTitle("title")
# 断言标题是否包含"title"
self.assertInTitle("title")
# 断言URL是否等于
self.assertUrl("url")
# 断言URL是否包含
self.assertInUrl("url")
# 断言页面包含“text”
self.assertText("text")
# 断言页面不包含“text”
self.assertNotText("text")
# 断言警告是否存在"text" 提示信息
self.assertAlertText("text")
# 断言元素是否存在
self.assertElement(css="#kw")
# 断言元素是否不存在
self.assertNotElement(css="#kwasdfasdfa")
4.2.9 Page Objects设计模式
seldom API 的设计理念是将元素操作和元素定位放到一起写的,需要结合poium 一起使用 ,
> pip install poium==1.1.6
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# author: HuJun
# datetime: 2023/3/3 16:55
# -*-coding:utf-8-*-
# 用于登录页元素定位
from models import Url
from poium import Page, Element
class login(Page):
""" 项目用户登录、退出定位元素"""
'用户名输入框'
username_input_loc = Element(class_name="el-input__inner")
'密码输入框'
password_inpput_loc = Element(xpath="/html/body/section/div/div[2]/form/div[4]/div/div/input")
'登录按钮'
loginButonClick_loc = Element(class_name="action-group")
'验证码输入框'
verificationCode_loc = Element(xpath="/html/body/section/div/div[2]/form/div[7]/div/div[1]/input")
'退出系统按钮'
# 操作方法封装
def username_input(self,key):
self.username_input_loc.clear()
self.username_input_loc.send_keys(key)
def passWord_input(self,key):
self.password_inpput_loc.clear()
self.password_inpput_loc.send_keys(key)
def loginButon_click(self):
self.loginButonClick_loc.click()
def verificationCode_input(self,key):
self.verificationCode_loc.send_keys(key)
def login_all(self):
self.username_input_loc.clear()
self.username_input_loc.send_keys("admin")
self.password_inpput_loc.clear()
self.password_inpput_loc.send_keys("ngmmsupermanager")
self.loginButonClick_loc.click()
最后: 为了回馈铁杆粉丝们,我给大家整理了完整的软件测试视频学习教程,朋友们如果需要可以自行免费领取 【保证100%免费】
软件测试面试文档
我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
全套资料获取方式: