Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录
切换导航
U
ubains-module-test
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
郑晓兵
ubains-module-test
Commits
8a3ef6d6
提交
8a3ef6d6
authored
4月 11, 2025
作者:
彭甘宇
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
更新运维自动化测试,调整代码,新增模块功能。
上级
403f3844
隐藏空白字符变更
内嵌
并排
正在显示
13 个修改的文件
包含
583 行增加
和
5 行删除
+583
-5
.gitignore
.gitignore
+1
-1
管理员登录.py
运维集控/项目测试/运维标准版/cases/01登录模块/管理员登录.py
+1
-0
01新增标签.py
运维集控/项目测试/运维标准版/cases/07类型标签/01新增标签.py
+85
-0
02编辑标签.py
运维集控/项目测试/运维标准版/cases/07类型标签/02编辑标签.py
+0
-0
03删除标签.py
运维集控/项目测试/运维标准版/cases/07类型标签/03删除标签.py
+0
-0
01新增设备.py
运维集控/项目测试/运维标准版/cases/08设备管理/01新增设备.py
+109
-0
02编辑设备.py
运维集控/项目测试/运维标准版/cases/08设备管理/02编辑设备.py
+0
-0
03查询设备.py
运维集控/项目测试/运维标准版/cases/08设备管理/03查询设备.py
+0
-0
04删除设备.py
运维集控/项目测试/运维标准版/cases/08设备管理/04删除设备.py
+0
-0
base.py
运维集控/项目测试/运维标准版/lib/base.py
+372
-3
新增标签.csv
运维集控/项目测试/运维标准版/testdata/07类型标签/新增标签.csv
+11
-0
新增设备.csv
运维集控/项目测试/运维标准版/testdata/08设备管理/新增设备.csv
+3
-0
定时任务执行.py
运维集控/项目测试/运维标准版/定时任务执行.py
+1
-1
没有找到文件。
.gitignore
浏览文件 @
8a3ef6d6
/预定系统/log
/预定系统/reports/
/预定系统/reports/imgs/
\ No newline at end of file
/预定系统/reports/imgs/
运维集控/项目测试/运维标准版/cases/01登录模块/管理员登录.py
浏览文件 @
8a3ef6d6
...
...
@@ -42,3 +42,4 @@ class User_Login:
# 截图并保存
SELENIUM_LOG_SCREEN
(
wd
,
"50
%
"
)
wd
.
refresh
()
运维集控/项目测试/运维标准版/cases/07类型标签/01新增标签.py
0 → 100644
浏览文件 @
8a3ef6d6
import
sys
import
os
from
hytest.common
import
SELENIUM_LOG_SCREEN
sys
.
path
.
append
(
os
.
path
.
abspath
(
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
'..'
,
'..'
,
'..'
,
'..'
,
'..'
)))
from
运维集控
.
项目测试
.
运维标准版
.
lib
.
base
import
*
#构建当前项目路径
sys
.
path
.
append
(
os
.
path
.
abspath
(
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
'..'
,
'..'
,
'..'
,
'..'
,
'..'
)))
# 构建 CSV 文件的绝对路径
csv_path
=
os
.
path
.
abspath
(
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
'..'
,
'..'
,
'testdata'
,
'03类型标签'
,
'新增标签.csv'
))
class
AreagroupAdd
:
tag
=
[
'新增类型标签'
]
ddt_cases
=
read_csv_data
(
csv_path
)
def
teststeps
(
self
):
wd
=
GSTORE
[
'wd'
]
# 从self.para中解构出数据
name
=
self
.
name
area_group
,
group_name
,
group_address
,
remark
,
info
=
self
.
para
STEP
(
1
,
'点击新增按钮'
)
areagroup_add
=
WebDriverWait
(
wd
,
10
)
.
until
(
EC
.
element_to_be_clickable
((
By
.
XPATH
,
"//div[@class='company-edmit-right']//span[contains(text(),'新增')]"
))
)
areagroup_add
.
click
()
STEP
(
2
,
f
'查看并选择类型标签:{area_group}'
)
if
area_group
:
area_group_input
=
WebDriverWait
(
wd
,
10
)
.
until
(
EC
.
presence_of_element_located
((
By
.
XPATH
,
"// input[ @ placeholder = '请选择分组']"
))
)
area_group_input
.
clear
()
area_group_input
.
send_keys
(
area_group
)
sleep
(
1
)
#默认选择第一个内容
area_group_select
=
WebDriverWait
(
wd
,
10
)
.
until
(
EC
.
presence_of_element_located
((
By
.
XPATH
,
"//div[@class='el-cascader__suggestion-panel el-scrollbar']//li[1]//span[1]"
))
)
area_group_select
.
click
()
else
:
print
(
"group_name 为空,不执行选择区域分组的操作"
)
STEP
(
3
,
f
'填写标签名称:{group_name}'
)
group_name_input
=
WebDriverWait
(
wd
,
10
)
.
until
(
EC
.
presence_of_element_located
((
By
.
XPATH
,
"//input[@placeholder='长度1-20个字符']"
))
)
group_name_input
.
clear
()
group_name_input
.
send_keys
(
group_name
)
STEP
(
4
,
f
'填写标签排序:{group_address}'
)
group_address_input
=
WebDriverWait
(
wd
,
10
)
.
until
(
EC
.
presence_of_element_located
((
By
.
XPATH
,
"//input[@placeholder='输入地址不能大于50个字符']"
))
)
group_address_input
.
clear
()
group_address_input
.
send_keys
(
group_address
)
STEP
(
5
,
f
'填写分组备注:{remark}'
)
group_remark
=
WebDriverWait
(
wd
,
10
)
.
until
(
EC
.
presence_of_element_located
(
(
By
.
XPATH
,
"//input[@placeholder='请输入备注']"
))
)
group_remark
.
clear
()
group_remark
.
send_keys
(
remark
)
STEP
(
6
,
'点击确认'
)
commit
=
WebDriverWait
(
wd
,
10
)
.
until
(
EC
.
element_to_be_clickable
((
By
.
XPATH
,
"//div[@class='dialog-footer']//span[contains(text(),'确 定')]"
))
)
commit
.
click
()
STEP
(
7
,
'验证是否新增成功'
)
get_menu
=
WebDriverWait
(
wd
,
10
)
.
until
(
EC
.
visibility_of_element_located
((
By
.
XPATH
,
"//p[@class='el-message__content']"
))
)
get_menu1
=
get_menu
.
text
CHECK_POINT
(
'检查是否出现成功提示弹窗'
,
get_menu1
==
info
)
# 截图并保存
SELENIUM_LOG_SCREEN
(
wd
,
"50
%
"
)
sleep
(
1
)
wd
.
refresh
()
运维集控/项目测试/运维标准版/cases/07类型标签/02编辑标签.py
0 → 100644
浏览文件 @
8a3ef6d6
运维集控/项目测试/运维标准版/cases/07类型标签/03删除标签.py
0 → 100644
浏览文件 @
8a3ef6d6
运维集控/项目测试/运维标准版/cases/08设备管理/01新增设备.py
0 → 100644
浏览文件 @
8a3ef6d6
import
sys
import
os
from
hytest.common
import
SELENIUM_LOG_SCREEN
sys
.
path
.
append
(
os
.
path
.
abspath
(
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
'..'
,
'..'
,
'..'
,
'..'
,
'..'
)))
from
运维集控
.
项目测试
.
运维标准版
.
lib
.
base
import
*
# 构建 CSV 文件的绝对路径
csv_path
=
os
.
path
.
abspath
(
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
'..'
,
'..'
,
'testdata'
,
'08设备管理'
,
'新增设备.csv'
))
class
AreafuntionAdd
:
tag
=
[
'新增设备'
]
ddt_cases
=
read_csv_data
(
csv_path
)
def
teststeps
(
self
):
wd
=
GSTORE
[
'wd'
]
#从self.para中解构出数据
name
=
self
.
name
area_group
,
area_type
,
area_name
,
area_ip
,
remark
,
info
=
self
.
para
STEP
(
1
,
'点击新增按钮'
)
areafuntion_add
=
WebDriverWait
(
wd
,
10
)
.
until
(
EC
.
element_to_be_clickable
(
(
By
.
XPATH
,
"//div[@class='company-edmit-right']//span[contains(text(),'新增')]"
))
)
areafuntion_add
.
click
()
sleep
(
1
)
STEP
(
2
,
f
'查找并选择区域分组:{area_group}'
)
if
area_group
:
area_group_input
=
WebDriverWait
(
wd
,
10
)
.
until
(
EC
.
presence_of_element_located
(
(
By
.
XPATH
,
"//div[@class='dialog_input']//input[@placeholder='请选择分组']"
))
)
area_group_input
.
send_keys
(
area_group
)
#默认选择第一个分组
areagroup_select
=
WebDriverWait
(
wd
,
10
)
.
until
(
EC
.
presence_of_element_located
(
(
By
.
XPATH
,
"//li[@class='el-cascader__suggestion-item']"
))
)
sleep
(
1
)
areagroup_select
.
click
()
else
:
print
(
"group_name 为空,不执行选择区域分组的操作"
)
STEP
(
3
,
f
'选择区域类型:{area_type}'
)
if
area_type
:
area_type_input
=
WebDriverWait
(
wd
,
10
)
.
until
(
EC
.
presence_of_element_located
(
(
By
.
XPATH
,
"//div[@class='dialog_input']//input[@placeholder='请选择区域类型']"
))
)
area_type_input
.
send_keys
(
area_type
)
#默认选择第一个区域类型
areatype_select
=
WebDriverWait
(
wd
,
10
)
.
until
(
EC
.
presence_of_element_located
(
(
By
.
XPATH
,
"//div[@x-placement='bottom-start']//ul[@class='el-scrollbar__view el-select-dropdown__list']"
))
)
sleep
(
1
)
areatype_select
.
click
()
else
:
print
(
"area_type 为空,不执行选择区域类型的操作"
)
STEP
(
4
,
f
'输入区域名称:{area_name}'
)
area_name_input
=
WebDriverWait
(
wd
,
10
)
.
until
(
EC
.
presence_of_element_located
(
(
By
.
XPATH
,
"//div[contains(@class,'dialog_input')]//input[contains(@placeholder,'请输入区域名称')]"
))
)
area_name_input
.
clear
()
area_name_input
.
send_keys
(
area_name
)
STEP
(
5
,
f
'填写IP地址:{area_ip}'
)
area_ip_input
=
WebDriverWait
(
wd
,
10
)
.
until
(
EC
.
presence_of_element_located
(
(
By
.
XPATH
,
"//input[@placeholder='IP地址']"
))
)
area_ip_input
.
clear
()
area_ip_input
.
send_keys
(
area_ip
)
STEP
(
6
,
f
'填写备注:{remark}'
)
funtion_remark
=
WebDriverWait
(
wd
,
10
)
.
until
(
EC
.
presence_of_element_located
(
(
By
.
XPATH
,
"//input[@placeholder='备注']"
))
)
funtion_remark
.
clear
()
funtion_remark
.
send_keys
(
remark
)
STEP
(
7
,
'点击确认'
)
commit
=
WebDriverWait
(
wd
,
10
)
.
until
(
EC
.
element_to_be_clickable
(
(
By
.
XPATH
,
"//div[@aria-label='新增']//span[contains(text(),'确 定')]"
))
)
commit
.
click
()
STEP
(
8
,
'验证是否新增成功'
)
get_menu
=
WebDriverWait
(
wd
,
10
)
.
until
(
EC
.
visibility_of_element_located
(
(
By
.
CSS_SELECTOR
,
'.el-message__content'
))
)
get_menu1
=
get_menu
.
text
CHECK_POINT
(
'检查是否出现成功提示弹窗'
,
get_menu1
==
info
)
# 截图并保存
SELENIUM_LOG_SCREEN
(
wd
,
"50
%
"
)
sleep
(
1
)
wd
.
refresh
()
\ No newline at end of file
运维集控/项目测试/运维标准版/cases/08设备管理/02编辑设备.py
0 → 100644
浏览文件 @
8a3ef6d6
运维集控/项目测试/运维标准版/cases/08设备管理/03查询设备.py
0 → 100644
浏览文件 @
8a3ef6d6
运维集控/项目测试/运维标准版/cases/08设备管理/04删除设备.py
0 → 100644
浏览文件 @
8a3ef6d6
运维集控/项目测试/运维标准版/lib/base.py
浏览文件 @
8a3ef6d6
import
openpyxl
import
pandas
as
pd
import
re
import
csv
import
urllib
import
glob
...
...
@@ -22,7 +24,7 @@ from selenium.webdriver.common.by import By
from
selenium.webdriver.edge.options
import
Options
from
selenium.webdriver.support.wait
import
WebDriverWait
from
selenium.webdriver.support
import
expected_conditions
as
EC
from
selenium.common
import
TimeoutException
,
ElementNotInteractable
Exception
from
selenium.common
import
TimeoutException
,
ElementNotInteractableException
,
NoSuchElement
Exception
from
selenium.webdriver.common.keys
import
Keys
from
time
import
sleep
...
...
@@ -44,7 +46,7 @@ def open_browser():
wd
.
maximize_window
()
wd
.
implicitly_wait
(
10
)
# 定义调整屏幕分辨率,仅
内部
环境跑定时任务需要使用。
# 定义调整屏幕分辨率,仅
虚拟机电脑
环境跑定时任务需要使用。
def
change_resolution
(
width
,
height
):
# 获取当前显示器的设备上下文(Device Context, DC)
device
=
win32api
.
EnumDisplayDevices
(
None
,
0
)
...
...
@@ -135,6 +137,19 @@ def main():
except
Exception
as
e
:
print
(
f
"An error occurred: {e}"
)
def
browser_quit
():
"""
退出浏览器并释放资源。
该函数从全局存储中获取浏览器驱动实例,并调用其quit方法来关闭浏览器并释放相关资源。
"""
# 清除浏览器
INFO
(
"清除浏览器"
)
# 从全局存储中获取浏览器驱动实例
wd
=
GSTORE
[
'wd'
]
# 调用浏览器驱动实例的quit方法,关闭浏览器并释放资源
wd
.
quit
()
# 进入后台管理系统页面
def
enter_system
():
wd
=
GSTORE
[
'wd'
]
...
...
@@ -390,6 +405,13 @@ def dingding_send_message(test_report_url, title, mobile, ding_type):
# 记录最终的 Webhook URL
logging
.
info
(
f
"钉钉机器人Webhook URL: {final_webhook_url}"
)
# 调用测试结果获取函数
open_browser
()
wd
=
GSTORE
[
'wd'
]
# print(latest_report)
test_result
=
get_test_result
(
test_report_url
,
wd
)
browser_quit
()
# 构建消息体
headers
=
{
'Content-Type'
:
'application/json'
}
message
=
{
...
...
@@ -397,7 +419,7 @@ def dingding_send_message(test_report_url, title, mobile, ding_type):
'link'
:
{
'title'
:
title
,
'messageUrl'
:
test_report_url
,
'text'
:
test_report_url
'text'
:
f
"通过:{test_result['pass_percent']}"
+
f
"失败:{test_result['fail_percent']}"
+
f
"异常:{test_result['exception_percent']}"
,
},
"at"
:
{
"atMobiles"
:
[
mobile
],
...
...
@@ -537,6 +559,7 @@ def read_csv_data(csv_file_path):
# 返回包含所有测试用例数据的列表
return
ddt_cases
# 定义生成的报告,并且发送钉钉通知
def
run_automation_test
(
report_title
,
report_url_prefix
,
ding_type
):
"""
运行自动化测试并生成报告。
...
...
@@ -578,3 +601,349 @@ def run_automation_test(report_title, report_url_prefix , ding_type):
# 调用回调函数处理后续操作
get_reportfile_send_dingding
(
f
"{report_title}"
,
report_url_prefix
,
ding_type
)
# 获取报告中的通过率、失败率和异常率,用于发送钉钉报告
def
get_test_result
(
latest_report
,
wd
):
"""
获取测试结果页面的通过率、失败率和异常率
:param latest_report: 测试结果页面的URL
:param wd: WebDriver实例,用于访问和操作网页
:return: 包含通过率、失败率和异常率的字典
"""
# 初始化测试结果字典
test_result
=
{
"pass_percent"
:
""
,
"fail_percent"
:
""
,
"exception_percent"
:
""
}
# 访问测试结果页面
wd
.
get
(
latest_report
)
sleep
(
5
)
# 点击简略显示
safe_click
((
By
.
XPATH
,
"//div[@id='display_mode']"
),
wd
)
sleep
(
5
)
# 定义一个函数来获取和解析百分比
def
get_percentage
(
selector
,
wd
):
text
=
elment_get_text
(
selector
,
wd
)
logging
.
info
(
f
"获取的文本:{text}"
)
match
=
re
.
search
(
r'(\d+(\.\d+)?)
%
'
,
text
)
if
match
:
return
match
.
group
(
0
)
else
:
logging
.
error
(
f
"未找到百分比匹配项,文本内容: {text}"
)
return
"0"
# 获取通过率
pass_percent
=
get_percentage
((
By
.
CSS_SELECTOR
,
"div[class='result_barchart'] div:nth-child(1) span:nth-child(1)"
),
wd
)
test_result
[
"pass_percent"
]
=
pass_percent
# 获取失败率
fail_percent
=
get_percentage
(
(
By
.
CSS_SELECTOR
,
"body > div.main_section > div.result > div > div:nth-child(2) > span"
),
wd
)
test_result
[
"fail_percent"
]
=
fail_percent
# 获取异常率
exception_percent
=
get_percentage
(
(
By
.
CSS_SELECTOR
,
"body > div.main_section > div.result > div > div:nth-child(3) > span"
),
wd
)
test_result
[
"exception_percent"
]
=
exception_percent
# 输出test_result
logging
.
info
(
test_result
)
print
(
test_result
)
sleep
(
5
)
# 返回测试结果字典
return
test_result
# 通用方法-点击元素
def
safe_click
(
element_locator
,
wd
):
"""
对其定位器指定的元素执行安全单击。
此函数尝试以处理潜在异常的方式单击元素。
它等待元素可见并可单击,然后再尝试单击它。
如果该元素在20秒内无法点击,或者它不存在,
或者不可交互,它会捕获相应的异常并记录一条信息性消息。
参数:
-element_locator:要单击的元素的定位器,指定为元组。
-wd:用于查找元素并与之交互的WebDriver实例。
"""
try
:
# Wait up to 20 seconds for the element to be visible
element
=
WebDriverWait
(
wd
,
60
)
.
until
(
EC
.
visibility_of_element_located
(
element_locator
))
# Attempt to click the element
element
.
click
()
except
TimeoutException
:
# Log a message if the element is not found or not clickable within 20 seconds
INFO
(
f
"TimeoutException: Element {element_locator} not found or not clickable within 20 seconds."
)
except
NoSuchElementException
:
# Log a message if the element is not found
INFO
(
f
"NoSuchElementException: Element {element_locator} not found."
)
except
ElementNotInteractableException
:
# Log a message if the element is not interactable
INFO
(
f
"ElementNotInteractableException: Element {element_locator} is not interactable."
)
# 通用方法-在输入框输入内容
def
safe_send_keys
(
element_locator
,
value
,
wd
):
"""
安全地向网页元素发送键值。
该函数尝试在指定时间内找到指定的网页元素,如果找到并且元素可见,将先清除元素内容,然后发送指定的键值。
如果在指定时间内未能找到元素或元素不可点击,则捕获相应的异常并打印错误信息。
参数:
element_locator (tuple): 用于定位网页元素的策略和定位器的元组,例如(By.ID, 'element_id')。
value (str): 要发送到元素的键值字符串。
wd: WebDriver实例,用于与浏览器交互。
异常处理:
- TimeoutException: 如果元素在指定时间内未被找到或不可点击。
- NoSuchElementException: 如果元素不存在。
- ElementNotInteractableException: 如果元素存在但不可交互。
"""
try
:
# 等待元素在指定时间内可见
element
=
WebDriverWait
(
wd
,
60
)
.
until
(
EC
.
visibility_of_element_located
(
element_locator
))
element
.
clear
()
# 清除元素的当前值
element
.
send_keys
(
value
)
# 向元素发送指定的键值
except
TimeoutException
:
# 如果元素在指定时间内未被找到或不可点击,打印超时异常信息
INFO
(
f
"TimeoutException: Element {element_locator} not found or not clickable within 20 seconds."
)
except
NoSuchElementException
:
# 如果元素不存在,打印相应异常信息
INFO
(
f
"NoSuchElementException: Element {element_locator} not found."
)
except
ElementNotInteractableException
:
# 如果元素不可交互,打印相应异常信息
INFO
(
f
"ElementNotInteractableException: Element {element_locator} is not interactable."
)
# 通用方法-输入框清除
def
input_clear
(
element_locator
,
wd
):
"""
清空输入框中的文本。
该函数通过元素定位器找到指定的输入框,并尝试清空其内容。它使用显式等待来确保元素在尝试清除之前是可见的。
参数:
- element_locator: 用于定位输入框的元素定位器,通常是一个元组,包含定位方法和定位表达式。
- wd: WebDriver实例,用于与浏览器交互。
异常处理:
- TimeoutException: 如果在指定时间内元素不可见,则捕获此异常并打印超时异常消息。
- NoSuchElementException: 如果找不到指定的元素,则捕获此异常并打印未找到元素的消息。
- ElementNotInteractableException: 如果元素不可操作(例如,元素不可见或不可点击),则捕获此异常并打印相应消息。
"""
try
:
# 等待元素可见,并在可见后清空输入框。
input_element
=
WebDriverWait
(
wd
,
60
)
.
until
(
EC
.
visibility_of_element_located
(
element_locator
))
input_element
.
clear
()
except
TimeoutException
:
# 如果元素在20秒内不可见,打印超时异常消息。
print
(
f
"TimeoutException: Element {element_locator} not found or not clickable within 20 seconds."
)
except
NoSuchElementException
:
# 如果找不到元素,打印未找到元素的消息。
print
(
f
"NoSuchElementException: Element {element_locator} not found."
)
except
ElementNotInteractableException
:
# 如果元素不可操作,打印元素不可操作的消息。
print
(
f
"ElementNotInteractableException: Element {element_locator} is not interactable."
)
# 通用方法-回车
def
send_keyboard
(
element_locator
,
wd
):
"""
向指定元素发送键盘事件。
该函数尝试找到页面上的一个元素,并向其发送RETURN键点击事件。它使用显式等待来确保元素在尝试交互之前是可见的。
如果在指定时间内元素不可见、不存在或不可交互,则捕获相应的异常并打印错误消息。
参数:
- element_locator: 用于定位元素的元组,格式为(by, value)。例如,(By.ID, 'element_id')。
- wd: WebDriver实例,用于与浏览器进行交互。
异常处理:
- TimeoutException: 如果元素在20秒内不可见,则捕获此异常并打印超时错误消息。
- NoSuchElementException: 如果找不到指定的元素,则捕获此异常并打印未找到元素的错误消息。
- ElementNotInteractableException: 如果元素不可交互(例如,被遮挡或不可点击),则捕获此异常并打印相应错误消息。
"""
try
:
# 等待元素可见,并在可见后向其发送RETURN键点击事件。
element
=
WebDriverWait
(
wd
,
60
)
.
until
(
EC
.
visibility_of_element_located
(
element_locator
))
element
.
send_keys
(
Keys
.
RETURN
)
except
TimeoutException
:
# 如果元素在指定时间内不可见,打印超时错误消息。
print
(
f
"TimeoutException: Element {element_locator} not found or not clickable within 20 seconds."
)
except
NoSuchElementException
:
# 如果找不到指定的元素,打印未找到元素的错误消息。
print
(
f
"NoSuchElementException: Element {element_locator} not found."
)
except
ElementNotInteractableException
:
# 如果元素不可交互,打印不可交互错误消息。
print
(
f
"ElementNotInteractableException: Element {element_locator} is not interactable."
)
# 通用方法-获取提示文本
def
get_notify_text
(
wd
,
element_locator
):
"""
获取通知文本信息。
该函数通过WebDriver等待特定的元素出现,并截取其文本内容作为通知信息。此外,它还负责在获取通知文本后进行屏幕截图,
以便于后续的调试或记录需要。
参数:
wd (WebDriver): 由上层传入的WebDriver对象,用于操作浏览器。
返回:
str: 提取的通知文本信息。如果未能提取到信息或发生异常,则返回None。
"""
try
:
# 获取提示信息
notify_text
=
WebDriverWait
(
wd
,
60
)
.
until
(
EC
.
presence_of_element_located
(
element_locator
)
)
.
text
# 屏幕截图
SELENIUM_LOG_SCREEN
(
wd
,
"50
%
"
)
return
notify_text
except
Exception
as
e
:
# 记录异常信息
INFO
(
f
"Exception occurred: {e}"
)
# 通用方法-获取页面中的文本内容
def
elment_get_text
(
element_locator
,
wd
):
"""
获取页面元素的文本。
该函数通过显式等待的方式,确保页面元素在20秒内可见并获取其文本。
如果在规定时间内元素不可见、不存在或不可交互,则会捕获相应的异常并打印错误信息。
参数:
- element_locator: 用于定位页面元素的元组,通常包含定位方式和定位值。
- wd: WebDriver对象,用于与浏览器进行交互。
返回:
- element_text: 页面元素的文本。如果发生异常,则返回None。
"""
try
:
# 使用WebDriverWait等待页面元素在20秒内可见,并获取其文本。
element_text
=
WebDriverWait
(
wd
,
60
)
.
until
(
EC
.
visibility_of_element_located
(
element_locator
))
.
text
return
element_text
except
TimeoutException
:
# 如果超过20秒元素仍未可见,则捕获TimeoutException异常并打印错误信息。
print
(
f
"TimeoutException: Element {element_locator} not found or not clickable within 20 seconds."
)
except
NoSuchElementException
:
# 如果页面上不存在该元素,则捕获NoSuchElementException异常并打印错误信息。
print
(
f
"NoSuchElementException: Element {element_locator} not found."
)
except
ElementNotInteractableException
:
# 如果元素存在但不可交互(例如被遮挡),则捕获ElementNotInteractableException异常并打印错误信息。
print
(
f
"ElementNotInteractableException: Element {element_locator} is not interactable."
)
# 通用方法-读取XLSX文件中的数据,并将其转换为一个包含字典的列表
def
read_xlsx_data
(
xlsx_file_path
):
"""
读取XLSX文件中的数据,并将其转换为一个包含字典的列表,每个字典代表一行测试用例数据。
参数:
xlsx_file_path (str): XLSX文件的路径。
返回:
list: 包含字典的列表,每个字典包含测试用例的名称和参数。
"""
# 打开XLSX文件
workbook
=
openpyxl
.
load_workbook
(
xlsx_file_path
)
# 假设数据在第一个工作表中
sheet
=
workbook
.
active
# 读取表头,从第三行开始
headers
=
[
cell
.
value
for
cell
in
sheet
[
3
]]
# 打印表头列名
# print(f"表头列名: {headers}")
# 找到表头中名为 'JSON' 的列索引
try
:
json_index
=
headers
.
index
(
'JSON'
)
except
ValueError
as
e
:
raise
ValueError
(
f
"表头中没有找到所需的列: {e}"
)
ddt_cases
=
[]
# 遍历XLSX文件中的每一行数据,从第四行开始
for
row
in
sheet
.
iter_rows
(
min_row
=
4
,
values_only
=
True
):
# 获取 JSON 列的数据
json_data
=
row
[
json_index
]
# 打印 JSON 数据以进行调试
# print(f"JSON 数据: {json_data}")
# 解析 JSON 字符串
try
:
if
json_data
:
parsed_json
=
json
.
loads
(
json_data
)
else
:
raise
ValueError
(
"JSON 数据为空"
)
except
json
.
JSONDecodeError
:
raise
ValueError
(
f
"无法解析 JSON 数据: {json_data}"
)
# 将解析后的 JSON 数据添加到列表中
ddt_cases
.
append
(
parsed_json
)
# 日志记录:XLSX文件已读取
INFO
(
"XLSX文件已读取"
)
# 返回包含所有测试用例数据的列表
return
ddt_cases
# 通用方法-转换字符串类型
def
get_by_enum
(
type_str
):
"""
将字符串类型的定位器类型转换为 selenium.webdriver.common.by.By 枚举类型。
参数:
type_str (str): 定位器类型字符串,例如 'XPATH'。
返回:
selenium.webdriver.common.by.By: 对应的 By 枚举类型。
"""
type_str
=
type_str
.
upper
()
if
type_str
==
'XPATH'
:
return
By
.
XPATH
elif
type_str
==
'ID'
:
return
By
.
ID
elif
type_str
==
'NAME'
:
return
By
.
NAME
elif
type_str
==
'CLASS_NAME'
:
return
By
.
CLASS_NAME
elif
type_str
==
'CSS_SELECTOR'
:
return
By
.
CSS_SELECTOR
elif
type_str
==
'TAG_NAME'
:
return
By
.
TAG_NAME
elif
type_str
==
'LINK_TEXT'
:
return
By
.
LINK_TEXT
elif
type_str
==
'PARTIAL_LINK_TEXT'
:
return
By
.
PARTIAL_LINK_TEXT
else
:
raise
ValueError
(
f
"未知的定位器类型: {type_str}"
)
# 通用方法-用户登录
def
user_login
(
element_locators
,
username
,
password
,
verifycode
):
"""
管理员登录函数。
该函数通过模拟用户输入用户名、密码和验证码,并点击登录按钮,以实现管理员登录。
"""
# 获取webdriver实例
wd
=
GSTORE
[
'wd'
]
# 打印用户名输入信息
INFO
(
f
"输入用户名:{username}"
)
# 向用户名输入框发送用户名
safe_send_keys
(
element_locators
[
'username_locator'
],
f
'{username}'
,
wd
)
sleep
(
5
)
# 打印密码输入信息
INFO
(
f
"输入密码:{password}"
)
# 向密码输入框发送密码
safe_send_keys
(
element_locators
[
'password_locator'
],
f
"{password}"
,
wd
)
sleep
(
5
)
# 打印验证码输入信息
INFO
(
f
"输入验证码:{verifycode}"
)
# 向验证码输入验证码
safe_send_keys
(
element_locators
[
'verifycode_locator'
],
f
"{verifycode}"
,
wd
)
sleep
(
5
)
#点击登录按钮
INFO
(
"点击登录按钮"
)
safe_click
(
element_locators
[
'submitButton_locator'
],
wd
)
sleep
(
5
)
运维集控/项目测试/运维标准版/testdata/07类型标签/新增标签.csv
浏览文件 @
8a3ef6d6
name,typename,sort
新增标签-001-标签名称为空,,1
新增标签-002-排序为空,智慧大屏1,
新增标签-003-排序为小数,智慧大屏2,1.1
新增标签-004-排序为负数,智慧大屏3,-1
新增标签-005-正常新增标签1,智慧屏设备,1
新增标签-006-正常新增标签2,时序电源,2
新增标签-007-正常新增标签3,中控主机,3
新增标签-008-正常新增标签4,音频处理器,4
新增标签-009-正常新增标签5,视频处理器,5
新增标签-010-正常新增标签6,网络路由,6
运维集控/项目测试/运维标准版/testdata/08设备管理/新增设备.csv
浏览文件 @
8a3ef6d6
name,area_name,device_name,type,brand,model,sn,ip,tag,supplier,contact,price,expiry_time,sort,useYear,description,relateMaster,outMaster
新增设备-001-正常新增设备,测试区域11,测试设备0,智慧屏设备,华为品牌,Ideahub,123456789,192.168.1.1,资产设备1,华为,13141234567,2000,2025-01-01 12:00:00,1,3,用途说明1,否,否
\ No newline at end of file
运维集控/项目测试/运维标准版/定时任务执行.py
浏览文件 @
8a3ef6d6
...
...
@@ -69,7 +69,7 @@ start_workers(3)
# 定义每天定时执行的任务
# 每天早上07:50执行后台系统设置功能测试
for
day
in
[
'monday'
,
'tuesday'
,
'wednesday'
,
'thursday'
,
'friday'
]:
schedule
.
every
()
.
__getattribute__
(
day
)
.
at
(
"
07:50
"
)
.
do
(
run_task
,
run_automation_test
,
report_title
=
"运维系统测试报告"
,
report_url_prefix
=
"http://nat.ubainsyun.com:31135"
,
ding_type
=
"标准版巡检"
)
schedule
.
every
()
.
__getattribute__
(
day
)
.
at
(
"
11:21
"
)
.
do
(
run_task
,
run_automation_test
,
report_title
=
"运维系统测试报告"
,
report_url_prefix
=
"http://nat.ubainsyun.com:31135"
,
ding_type
=
"标准版巡检"
)
# 调试使用
#schedule.every().day.at("09:59").do(run_task, run_automation_test, report_title="运维系统脚本调试", report_url_prefix="http://nat.ubainsyun.com:31135", ding_type="标准版巡检")
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论