提交 8a3ef6d6 authored 作者: 彭甘宇's avatar 彭甘宇

更新运维自动化测试,调整代码,新增模块功能。

上级 403f3844
/预定系统/log
/预定系统/reports/
/预定系统/reports/imgs/
\ No newline at end of file
/预定系统/reports/imgs/
......@@ -42,3 +42,4 @@ class User_Login:
# 截图并保存
SELENIUM_LOG_SCREEN(wd, "50%")
wd.refresh()
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()
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
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,ElementNotInteractableException
from selenium.common import TimeoutException, ElementNotInteractableException, NoSuchElementException
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)
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
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
......@@ -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 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论