提交 77ec55c5 authored 作者: 陈泽健's avatar 陈泽健

将原有pytest框架代码改为hytest框架使用,优化了脚本执行效率,并对应增加异常处理。MQTT相关模块还未调整完。

上级 d8d160aa
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Black">
<option name="sdkName" value="Python 3.10 (pythonProject1)" />
<option name="sdkName" value="Python 3.10 (预定系统标准版)" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (pythonProject1)" project-jdk-type="Python SDK" />
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (预定系统标准版)" project-jdk-type="Python SDK" />
</project>
\ No newline at end of file
......@@ -2,7 +2,7 @@
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/预定系统标准版.iml" filepath="$PROJECT_DIR$/.idea/预定系统标准版.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/预定系统.iml" filepath="$PROJECT_DIR$/.idea/预定系统.iml" />
</modules>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AutoImportSettings">
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="63769e74-10f9-467e-9dd8-5f198f917cec" name="更改" comment="" />
<list default="true" id="c611fa12-cf95-4015-91bc-655fca8727f9" name="更改" comment="">
<change afterPath="$PROJECT_DIR$/Base/__init__.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/Base/base.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/__init__.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/cases/登录测试.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/.gitignore" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/.name" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/inspectionProfiles/profiles_settings.xml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/misc.xml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/modules.xml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/预定系统标准版.iml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/MQTT/安卓信息模块/安卓信息上报.py" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/MQTT/毫米波雷达模块/毫米波雷达上报.py" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/README.md" beforeDir="false" afterPath="$PROJECT_DIR$/README.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/base/Base.py" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/base/Broswer_driver.py" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/base/Mqtt_Send.py" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/测试数据/Login_Test.csv" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/测试数据/MQTT安卓上报数据.csv" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/测试数据/MQTT毫米波上报数据.csv" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/登录模块/Login_Test_UnitTest.py" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/登录模块/账号密码登录.py" beforeDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="FileTemplateManagerImpl">
<option name="RECENT_TEMPLATES">
<list>
<option value="Python Unit Test" />
<option value="Python Script" />
</list>
</option>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$/.." />
</component>
<component name="ProjectColorInfo">{
&quot;associatedIndex&quot;: 7
&quot;associatedIndex&quot;: 1
}</component>
<component name="ProjectId" id="2mPF5l1gB6OIns7dktvs9fKz8QA" />
<component name="ProjectId" id="2oHCs6mlWOf2wqcuRAkwXTXS0kl" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
"Python 测试.Login_Test.MyTestCase 的 Python 测试.executor": "Run",
"Python 测试.Login_Test.MyTestCase.test 的 Python 测试.executor": "Run",
"Python 测试.Login_Test.MyTestCase.test_login_errorLimit 的 Python 测试.executor": "Run",
"Python 测试.Login_Test.MyTestCase.test_login_from_csv 的 Python 测试.executor": "Run",
"Python 测试.Login_Test.MyTestCase.test_login_success 的 Python 测试.executor": "Run",
"Python 测试.Python 测试 (LoginBy_ActAndPwd_PyTest.py 内).executor": "Run",
"Python 测试.Python 测试 (Login_PyTest.py 内).executor": "Run",
"Python 测试.Python 测试 (Login_Pytest2.py 内).executor": "Run",
"Python 测试.Python 测试 (Login_Test.py 内).executor": "Run",
"Python.Login_CZJ.executor": "Run",
"Python.Login_Test_CZJ (1).executor": "Run",
"Python.登录测试.executor": "Run",
"RunOnceActivity.ShowReadmeOnStart": "true",
"last_opened_file_path": "D:/PycharmData/预定系统标准版",
"node.js.detected.package.eslint": "true",
"node.js.detected.package.tslint": "true",
"node.js.selected.package.eslint": "(autodetect)",
"node.js.selected.package.tslint": "(autodetect)",
"git-widget-placeholder": "develop",
"last_opened_file_path": "D:/GithubData/ubains-module-test/ubains-module-test/预定系统",
"nodejs_package_manager_path": "npm",
"settings.editor.selected.configurable": "preferences.pluginManager",
"vue.rearranger.settings.migration": "true"
}
}]]></component>
<component name="RecentsManager">
<key name="MoveFile.RECENT_KEYS">
<recent name="D:\PycharmData\pythonProject1\预定标准\登录模块" />
</key>
</component>
<component name="RunManager" selected="Python 测试.Python 测试 (LoginBy_ActAndPwd_PyTest.py 内)">
<configuration name="Python 测试 (D:/PycharmData/预定系统标准版/登录模块/page/Login_PyTest.py 内)" type="tests" factoryName="Autodetect" temporary="true" nameIsGenerated="true">
<module name="预定系统标准版" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/登录模块/page" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="_new_additionalArguments" value="&quot;&quot;" />
<option name="_new_target" value="&quot;$PROJECT_DIR$/登录模块/page/Login_PyTest.py&quot;" />
<option name="_new_targetType" value="&quot;PATH&quot;" />
<method v="2" />
</configuration>
<configuration name="Python 测试 (D:/PycharmData/预定系统标准版/登录模块/page/Login_Pytest2.py 内)" type="tests" factoryName="Autodetect" temporary="true" nameIsGenerated="true">
<module name="预定系统标准版" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/登录模块/page" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="_new_additionalArguments" value="&quot;&quot;" />
<option name="_new_target" value="&quot;$PROJECT_DIR$/登录模块/page/Login_Pytest2.py&quot;" />
<option name="_new_targetType" value="&quot;PATH&quot;" />
<method v="2" />
</configuration>
<configuration name="Python 测试 (LoginBy_ActAndPwd_PyTest.py 内)" type="tests" factoryName="Autodetect" temporary="true" nameIsGenerated="true">
<module name="预定系统标准版" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/登录模块/page" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="_new_additionalArguments" value="&quot;&quot;" />
<option name="_new_target" value="&quot;$PROJECT_DIR$/登录模块/page/LoginBy_ActAndPwd_PyTest.py&quot;" />
<option name="_new_targetType" value="&quot;PATH&quot;" />
<method v="2" />
</configuration>
<configuration name="Python 测试 (Login_Test_UnitTest.py 内)" type="tests" factoryName="Autodetect" temporary="true" nameIsGenerated="true">
<module name="预定系统标准版" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/登录模块/page" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="_new_additionalArguments" value="&quot;&quot;" />
<option name="_new_target" value="&quot;$PROJECT_DIR$/登录模块/page/Login_Test_UnitTest.py&quot;" />
<option name="_new_targetType" value="&quot;PATH&quot;" />
<method v="2" />
</configuration>
<configuration name="登录模块.page.Login_Test_UnitTest 的 Python 测试" type="tests" factoryName="Autodetect" temporary="true" nameIsGenerated="true">
<module name="预定系统标准版" />
<option name="ENV_FILES" value="" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/登录模块/page" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="_new_additionalArguments" value="&quot;&quot;" />
<option name="_new_target" value="&quot;登录模块.page.Login_Test_UnitTest&quot;" />
<option name="_new_targetType" value="&quot;PYTHON&quot;" />
<method v="2" />
</configuration>
<recent_temporary>
<list>
<item itemvalue="Python 测试.Python 测试 (LoginBy_ActAndPwd_PyTest.py 内)" />
<item itemvalue="Python 测试.Python 测试 (D:/PycharmData/预定系统标准版/登录模块/page/Login_PyTest.py 内)" />
<item itemvalue="Python 测试.Python 测试 (D:/PycharmData/预定系统标准版/登录模块/page/Login_Pytest2.py 内)" />
<item itemvalue="Python 测试.Python 测试 (Login_Test_UnitTest.py 内)" />
<item itemvalue="Python 测试.登录模块.page.Login_Test_UnitTest 的 Python 测试" />
</list>
</recent_temporary>
</component>
<component name="SharedIndexes">
<attachedChunks>
<set>
......@@ -157,23 +62,14 @@
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="应用程序级" UseSingleDictionary="true" transferred="true" />
<component name="TaskManager">
<task active="true" id="Default" summary="默认任务">
<changelist id="63769e74-10f9-467e-9dd8-5f198f917cec" name="更改" comment="" />
<created>1726970122280</created>
<changelist id="c611fa12-cf95-4015-91bc-655fca8727f9" name="更改" comment="" />
<created>1730517317372</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1726970122280</updated>
<workItem from="1726970123695" duration="31693000" />
<workItem from="1727095378299" duration="9072000" />
<workItem from="1727143346632" duration="15217000" />
<workItem from="1727163581288" duration="9108000" />
<workItem from="1727182815172" duration="5276000" />
<workItem from="1727188242736" duration="2168000" />
<workItem from="1727225088964" duration="10301000" />
<workItem from="1727258378123" duration="5624000" />
<workItem from="1727274398017" duration="3245000" />
<workItem from="1727493678249" duration="636000" />
<workItem from="1727663202507" duration="896000" />
<workItem from="1728388575086" duration="863000" />
<updated>1730517317372</updated>
<workItem from="1730517318454" duration="39000" />
<workItem from="1730517748773" duration="156000" />
<workItem from="1730518030969" duration="15000" />
</task>
<servers />
</component>
......@@ -181,9 +77,6 @@
<option name="version" value="3" />
</component>
<component name="com.intellij.coverage.CoverageDataManagerImpl">
<SUITE FILE_PATH="coverage/pythonProject1$Login_Test_CZJ__1_.coverage" NAME="Login_Test_CZJ (1) 覆盖结果" MODIFIED="1726983885714" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/预定标准/登录模块" />
<SUITE FILE_PATH="coverage/pythonProject1$.coverage" NAME=" 覆盖结果" MODIFIED="1727161759018" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/登录模块/page" />
<SUITE FILE_PATH="coverage/$.coverage" NAME=" 覆盖结果" MODIFIED="1728389350052" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/登录模块/page" />
<SUITE FILE_PATH="coverage/pythonProject1$Login_CZJ.coverage" NAME="Login_CZJ 覆盖结果" MODIFIED="1726982554636" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/预定标准/登录模块" />
<SUITE FILE_PATH="coverage/$.coverage" NAME="登录测试 覆盖结果" MODIFIED="1730517793653" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/cases" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
......@@ -129,10 +129,7 @@ class Mqtt:
:param current_time: 当前时间
:return: 消息字典
"""
<<<<<<< HEAD:预定系统/base/Mqtt_Send.py
#安卓信息设备上报
=======
>>>>>>> 949209b52f0b2ea4a02345aefb25f4daee4ec4bd:预定系统/base/Mqtt_Android.py
if topic == "rebootResponseTopic":
return {
"method": "/system/readSystemInfo",
......@@ -189,17 +186,13 @@ class Mqtt:
}
})
}
<<<<<<< HEAD:预定系统/base/Mqtt_Send.py
#安卓信息心跳上报
=======
>>>>>>> 949209b52f0b2ea4a02345aefb25f4daee4ec4bd:预定系统/base/Mqtt_Android.py
elif topic == "/uams/android/broadcast":
return json.dumps({
"type":"heartbeat",
"clientId" : config['clientId'],
"appId":"com.ubains.uniplatform",
"deviceId": config['deviceId']
<<<<<<< HEAD:预定系统/base/Mqtt_Send.py
})
#毫米波雷达数据上报
......@@ -222,10 +215,6 @@ class Mqtt:
"ip" : config['ip']
}
})
=======
})
>>>>>>> 949209b52f0b2ea4a02345aefb25f4daee4ec4bd:预定系统/base/Mqtt_Android.py
def send_and_receive_messages(self, topic, message, num_times=1, timeout=5, interval=0.2):
"""
......
import logging
from hytest import *
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
def browser_init():
INFO("'----------' 正在初始化浏览器 '----------'")
options = webdriver.ChromeOptions()
options.add_experimental_option('excludeSwitches', ['enable-logging'])
wd = webdriver.Chrome(options=options)
wd.implicitly_wait(10)
wd.get('https://nat.ubainsyun.com:11046')
wd.maximize_window()
GSTORE['wd'] = wd
def handle_ssl_warning():
wd = GSTORE['wd']
try:
# 记录处理 SSL 证书警告的开始信息
INFO("'----------' 正在处理SSL证书警告 '----------'")
# 等待并点击“详细信息”按钮
WebDriverWait(wd, 10).until(
EC.element_to_be_clickable((By.XPATH, '//*[@id="details-button"]'))
).click()
# 等待并点击“继续”链接,以忽略 SSL 警告
WebDriverWait(wd, 10).until(
EC.element_to_be_clickable((By.XPATH, '//*[@id="proceed-link"]'))
).click()
# 等待页面加载完成
WebDriverWait(wd, 10).until(
EC.presence_of_element_located((By.TAG_NAME, 'body'))
)
# 记录处理 SSL 证书警告完成的信息
INFO("'----------' SSL证书警告处理完成 '----------'")
except Exception as e:
# 记录处理 SSL 证书警告过程中遇到的错误,并抛出异常
logging.error(f"处理 SSL 证书警告遇到错误: {e}")
raise
def admin_login():
wd = GSTORE['wd']
INFO("输入用户名:admin@czj")
# 等待元素刷新
WebDriverWait(wd, 10).until(
EC.element_to_be_clickable((By.XPATH, '//*[@id="app"]/div/div[3]/div[1]/div[2]/div/form/div[1]/div/input')
)).send_keys("admin@czj")
INFO("输入密码:Ubains@4321")
WebDriverWait(wd, 10).until(
EC.element_to_be_clickable((By.XPATH, '//*[@id="app"]/div/div[3]/div[1]/div[2]/div/form/div[2]/div/input')
)).send_keys("Ubains@4321")
INFO("输入验证码:csba")
WebDriverWait(wd, 10).until(
EC.element_to_be_clickable(
(By.XPATH, '//*[@id="app"]/div/div[3]/div[1]/div[2]/div/form/div[3]/div[1]/div/input')
)).send_keys("csba")
wd.implicitly_wait(5)
INFO("点击登录按钮")
WebDriverWait(wd, 10).until(
EC.element_to_be_clickable(
(By.XPATH, '//*[@id="app"]/div/div[3]/div[1]/div[2]/div/form/div[4]/input')
)).click()
def browser_quit():
INFO("清除浏览器")
wd = GSTORE['wd']
wd.quit()
\ No newline at end of file
......@@ -13,9 +13,12 @@
- 了解清楚安卓信息的状态判断,后续将调试redis连接以及将键值对存入redis。
4. 2024-10-24
- 优化MQTT底层方法,通过判断topic的值来发送不同的消息体。
<<<<<<< HEAD
- 优化安卓信息上报.py脚本通过读配置文件中的topic,调用build_message时传入topic进行主题判断。后续方便进行MQTT主题与消息体的管理。
- 补充毫米波雷达数据上报数据,毫米波设备的device_id需要与实际设备匹配才行。
=======
- 优化安卓信息上报.py脚本通过读配置文件中的topic,调用build_message时传入topic进行主题判断。后续方便进行MQTT主题与消息体的管理。
>>>>>>> 949209b52f0b2ea4a02345aefb25f4daee4ec4bd
- 修改提交git时代码中出现了很多非法字符的问题。
5. 2024-10-28
- 优化了Mqtt_Send中封装的函数,补充异常处理以及日志优化。
6. 2024-11-02
- 将原有pytest框架代码改为hytest框架使用,优化了脚本执行效率,并对应增加异常处理。
- MQTT相关模块还未调整完。
\ No newline at end of file
import logging
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common import StaleElementReferenceException
class Base:
def __init__(self, driver):
self.driver = driver
self.logger = logging.getLogger(__name__)
def find_element(self, by, value):
"""
查找元素,并处理可能的异常
"""
try:
return WebDriverWait(self.driver, 30).until(
EC.presence_of_element_located((by, value))
)
except StaleElementReferenceException:
return WebDriverWait(self.driver, 30).until(
EC.presence_of_element_located((by, value))
)
def perform_login(self, username, password, verification_code):
"""
执行登录操作
"""
self.driver.implicitly_wait(5)
self.driver.refresh()
try:
# 清除并输入用户名
username_input = self.find_element(By.XPATH, '//*[@id="app"]/div/div[3]/div[1]/div[2]/div/form/div[1]/div/input')
username_input.clear()
username_input.send_keys(username)
# 清除并输入密码
password_input = self.find_element(By.XPATH, '//*[@id="app"]/div/div[3]/div[1]/div[2]/div/form/div[2]/div/input')
password_input.clear()
password_input.send_keys(password)
# 清除并输入验证码
verification_input = self.find_element(By.XPATH, '//*[@id="app"]/div/div[3]/div[1]/div[2]/div/form/div[3]/div[1]/div/input')
verification_input.clear()
verification_input.send_keys(verification_code)
# 点击登录按钮
login_button = self.find_element(By.XPATH, '//*[@id="app"]/div/div[3]/div[1]/div[2]/div/form/div[4]/input')
login_button.click()
# 检查登录是否成功
if self.check_login_null():
self.logger.info("登录失败,必填项不能为空!断言成功!")
elif self.check_login_success():
self.logger.info("登录成功,断言成功!")
self.return_to_login_page()
elif self.check_login_failure():
self.logger.info("登录失败, 必填项错误!断言成功!")
else:
self.logger.error("登录状态未知,断言失败!")
pytest.fail("登录状态未知,断言失败!")
except StaleElementReferenceException as e:
self.logger.error(f"元素已失效,重新查找... {e}")
pytest.fail(f"元素已失效,重新查找... {e}")
except Exception as e:
self.logger.error(f"登录操作失败: {e}")
pytest.fail(f"登录操作失败: {e}")
def return_to_login_page(self):
"""
返回登录页面
"""
try:
# 定位到退出按钮并点击
logout_button = self.find_element(By.XPATH, '//*[@id="app"]/div/div[1]/div/img[3]')
logout_button.click()
# 记录日志,表明已成功尝试返回登录页面
self.logger.info("已成功返回登录页面")
# 刷新页面,并等待一段时间以确保页面加载完成
self.driver.refresh()
self.driver.implicitly_wait(5)
except Exception as e:
# 如果发生异常,记录错误日志并使测试用例失败
self.logger.error(f"返回登录页面失败: {e}")
pytest.fail(f"返回登录页面失败: {e}")
def check_login_null(self):
"""
检查登录失败,必填项为空的情况
"""
try:
login_element_text = WebDriverWait(self.driver, 10).until(
EC.visibility_of_element_located((By.XPATH, '/html/body/div[2]/p'))
).text
# 断言登录失败后,提示信息中包含'请输入'关键词
assert "请输入" in login_element_text, "登录失败后未找到'请输入'提示语"
return True
except Exception as e:
self.logger.error(f"登录失败检查失败: {e}")
return False
def check_login_success(self):
"""
检查登录成功的情况
"""
try:
message_element_text = WebDriverWait(self.driver, 10).until(
EC.visibility_of_element_located((By.XPATH, "//*[contains(text(), '欢迎')]"))
).text
# 断言欢迎信息是否符合预期
assert "欢迎 预定标准版测试" == message_element_text, "登录成功后找到'欢迎 预定标准版测试'提示语"
return True
except Exception as e:
self.logger.error(f"登录成功检查失败: {e}")
return False
def check_login_failure(self):
"""
检查登录失败的情况
"""
try:
login_element_text = WebDriverWait(self.driver, 10).until(
EC.visibility_of_element_located((By.XPATH, '//*[@id="app"]/div/div[3]/div[1]/div[1]/div[1]'))
).text
# 断言登录元素的文本是否为"账号登录",如果符合,则说明登录失败检查成功
assert "账号登录" == login_element_text, "登录失败后未找到'账号登录'提示语"
return True
except Exception as e:
self.logger.error(f"登录失败检查失败: {e}")
return False
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
import logging
class Browser_driver(object):
def browser_init(self):
# logging.info('初始化开始!')
try:
# 自动下载并使用 ChromeDriver
self.driver = webdriver.Chrome(service=ChromeService(ChromeDriverManager().install()))
# 设置隐式等待时间
self.driver.implicitly_wait(5) # 延长至5秒
# logging.info('初始化成功,驱动正常!')
except Exception as e:
logging.error(f'初始化失败: {e}')
raise
return self.driver
from hytest import *
import sys
import os
# 获取当前脚本的绝对路径
current_dir = os.path.dirname(os.path.abspath(__file__))
# 构建预定系统的绝对路径
预定系统_path = os.path.abspath(os.path.join(current_dir, '..','..'))
# 添加路径
sys.path.append(预定系统_path)
# 导入模块
try:
from 预定系统.Base.base import *
except ModuleNotFoundError as e:
print(f"ModuleNotFoundError: {e}")
print("尝试使用绝对路径导入")
from 预定系统.Base.base import *
def suite_setup():
browser_init()
handle_ssl_warning()
def suite_teardown():
browser_quit()
\ No newline at end of file
from time import sleep
from hytest import *
import sys
import os
# 获取当前脚本的绝对路径
current_dir = os.path.dirname(os.path.abspath(__file__))
# 构建预定系统的绝对路径
预定系统_path = os.path.abspath(os.path.join(current_dir, '..','..','..'))
# 添加路径
sys.path.append(预定系统_path)
# 导入模块
try:
from 预定系统.Base.base import *
except ModuleNotFoundError as e:
print(f"ModuleNotFoundError: {e}")
print("尝试使用绝对路径导入")
from 预定系统.Base.base import *
# 提取常量
XPATH_USERNAME_INPUT = '//*[@id="app"]/div/div[3]/div[1]/div[2]/div/form/div[1]/div/input'
# 用户名输入框的 XPath 路径
XPATH_PASSWORD_INPUT = '//*[@id="app"]/div/div[3]/div[1]/div[2]/div/form/div[2]/div/input'
# 密码输入框的 XPath 路径
XPATH_CODE_INPUT = '//*[@id="app"]/div/div[3]/div[1]/div[2]/div/form/div[3]/div[1]/div/input'
# 验证码输入框的 XPath 路径
XPATH_LOGIN_BUTTON = '//*[@id="app"]/div/div[3]/div[1]/div[2]/div/form/div[4]/input'
# 登录按钮的 XPath 路径
XPATH_WELCOME_TEXT = '//*[@id="app"]/div/div[1]/div/span[1]'
# 欢迎文本的 XPath 路径
CLASS_MESSAGE_CONTENT = 'el-message__content'
# 消息内容的 CSS 类名
DEFAULT_WAIT_TIME = 10
# 默认等待时间(秒),用于元素加载或操作之间的等待
def clear_and_send_keys(wd, locator, value):
"""
清空输入框并发送指定值
该函数首先等待指定的元素变得可点击,然后清空该元素的内容,
最后向该元素发送指定的值。这个过程常用于表单填写自动化。
参数:
- wd: WebDriver实例,用于与浏览器交互。
- locator: 定位器,用于定位页面上的元素。
- value: 需要发送到元素的值,通常为字符串。
返回值:
"""
# 等待元素变得可点击,这是为了确保元素已经加载完成并且可以接收输入
element = WebDriverWait(wd, DEFAULT_WAIT_TIME).until(EC.element_to_be_clickable(locator))
# 清空元素的内容,通常用于输入框,以确保之前的内容不会影响新的输入
element.clear()
# 向元素发送指定的值,这是自动化表单填写的关键步骤
element.send_keys(value)
class UI_000x:
ddt_cases = [
{
'name': '登录 UI_0001',
'para': [None,'Ubains@4321','csba','请输入账号!']
},
{
'name': '登录 UI_0002',
'para': ['admin@czj',None,'csba','请输入密码!']
},
{
'name': '登录 UI_0003',
'para': ['admin@czj','Ubains@4321',None,'请输入验证码!']
},
{
'name': '登录 UI_0004',
'para': ['admin@czj112','Ubains@4321','csba','账号或密码错误']
},
{
'name': '登录 UI_0005',
'para': ['adM 12in@czj','Ubains@4321','csba','账号或密码错误']
},
{
'name': '登录 UI_0006',
'para': ['admin@czj', '12345', 'csba', '账号或密码错误']
},
{
'name': '登录 UI_0007',
'para': ['admin@czj', 'U bains1s@432', 'csba', '账号或密码错误']
},
{
'name': '登录 UI_0008',
'para': ['admin@czj', 'Ubains@4321', '123', '验证码错误']
},
{
'name': '登录 UI_0009',
'para': ['admin@czj', 'Ubains@4321', 'cs 12', '验证码错误']
},
{
'name': '登录 UI_0010',
'para': ['admin@czj', 'Ubains@4321', 'csba', '欢迎 预定标准版测试']
}
]
def teststeps(self):
"""
执行测试步骤以验证登录功能。
本函数根据参数输入账号、密码和验证码,并检查登录后的提示信息是否与预期相符。
"""
# 初始化通知文本为空字符串
notify_text = ""
# 从全局存储中获取webdriver实例
wd = GSTORE['wd']
# 从self.para中解构出用户名、密码、验证码和检查文本
username, password, code, check_text = self.para
# 步骤1:输入账号、密码和验证码
STEP(1, f"输入账号: {username}, 密码: {password}, 验证码: {code}")
# 如果用户名不为空,则清空用户名输入框并输入用户名
if username is not None:
clear_and_send_keys(wd, (By.XPATH, XPATH_USERNAME_INPUT), username)
# 如果密码不为空,则清空密码输入框并输入密码
if password is not None:
clear_and_send_keys(wd, (By.XPATH, XPATH_PASSWORD_INPUT), password)
# 如果验证码不为空,则清空验证码输入框并输入验证码
if code is not None:
clear_and_send_keys(wd, (By.XPATH, XPATH_CODE_INPUT), code)
# 步骤2:点击登录按钮
STEP(2, "点击登录按钮")
# 等待登录按钮可点击,并点击它
login_button = WebDriverWait(wd, DEFAULT_WAIT_TIME).until(
EC.element_to_be_clickable((By.XPATH, XPATH_LOGIN_BUTTON)))
login_button.click()
# 等待1秒以允许页面响应
sleep(2)
# 根据预期的检查文本类型,获取并记录提示信息
if check_text == "欢迎":
notify_text = WebDriverWait(wd, DEFAULT_WAIT_TIME).until(
EC.presence_of_element_located((By.XPATH, XPATH_WELCOME_TEXT))
).text
INFO(f"Alert text: {notify_text}")
else:
try:
notify_text = WebDriverWait(wd, DEFAULT_WAIT_TIME).until(
EC.presence_of_element_located((By.CLASS_NAME, CLASS_MESSAGE_CONTENT))
).text
INFO(f"Alert text: {notify_text}")
except Exception as e:
INFO(f"Exception occurred: {e}")
# 步骤3:校验提示信息
STEP(3, f"校验提示信息: {check_text}")
# 设置隐式等待时间
wd.implicitly_wait(DEFAULT_WAIT_TIME)
# 检查点:验证提示信息是否与预期相符
CHECK_POINT('弹出提示', notify_text == check_text)
def teardown(self):
"""
测试 teardown 方法,用于测试结束后清理环境。
该方法从全局存储 GSTORE 中获取 WebDriver 实例,并在测试结束前刷新当前页面。
这是为了确保每个测试都是在干净的状态下执行,避免不同测试之间相互影响。
"""
# 从全局存储中获取 WebDriver 实例
wd = GSTORE['wd']
# 执行步骤 4:刷新页面,以确保下一个测试从一个干净的状态开始
STEP(4, "刷新页面")
wd.refresh()
\ No newline at end of file
# from datetime import datetime
# import time
# from hytest import *
# import sys
# import os
# # 获取当前脚本的绝对路径
# current_dir = os.path.dirname(os.path.abspath(__file__))
# # 构建预定系统的绝对路径
# 预定系统_path = os.path.abspath(os.path.join(current_dir, '..','..','..'))
# # 添加路径
# sys.path.append(预定系统_path)
# # 导入模块
# try:
# from 预定系统.Base.Mqtt_Send import *
# except ModuleNotFoundError as e:
# print(f"ModuleNotFoundError: {e}")
# print("尝试使用绝对路径导入")
# from 预定系统.Base.Mqtt_Send import *
#
# if __name__ == "__main__":
# # 读取配置文件
# configs = Mqtt.read_config_from_csv('../测试数据/MQTT安卓上报数据.csv')
#
# broker_address = "192.168.5.218"
# port = 1883
# # topic = "rebootResponseTopic"
# num_repeats = 100 # 重复执行的次数
# interval_between_repeats = 0.2 # 每次重复之间的间隔时间(秒)
#
# # 创建 MQTT 客户端实例
# mqtt_client = Mqtt(broker_address, port)
#
# try:
# # 连接到 MQTT 服务器
# mqtt_client.connect()
#
# for repeat in range(num_repeats):
# logging.info(f"开始第 {repeat + 1} 次上报")
#
# # 遍历配置文件中的每一行数据
# for config in configs:
# # 构建消息内容-
# # 构建消息内容
# topic = config["topic"]
# current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
# message = Mqtt.build_message(config, current_time, topic)
#
# # 发送消息
# mqtt_client.publish(topic, message)
#
# # 每次发送之间可以设置一个间隔时间
# time.sleep(interval_between_repeats)
#
# # 每次重复之间设置一个间隔时间
# time.sleep(interval_between_repeats)
#
# except Exception as e:
# logging.error(f"发送消息时发生错误: {e}")
#
# finally:
# # 断开与 MQTT 服务器的连接
# mqtt_client.disconnect()
# from datetime import datetime
# import logging
# import time
# import sys
# import os
# # 获取当前脚本的绝对路径
# current_dir = os.path.dirname(os.path.abspath(__file__))
# # 构建预定系统的绝对路径
# 预定系统_path = os.path.abspath(os.path.join(current_dir, '..','..','..'))
# # 添加路径
# sys.path.append(预定系统_path)
# # 导入模块
# try:
# from 预定系统.Base.Mqtt_Send import *
# except ModuleNotFoundError as e:
# print(f"ModuleNotFoundError: {e}")
# print("尝试使用绝对路径导入")
# from 预定系统.Base.Mqtt_Send import *
#
# if __name__ == "__main__":
# # 读取配置文件
# configs = Mqtt.read_config_from_csv('../测试数据/MQTT毫米波上报数据.csv')
#
# broker_address = "192.168.5.218"
# port = 1883
# num_repeats = 100 # 重复执行的次数
# interval_between_repeats = 0.2 # 每次重复之间的间隔时间(秒)
#
# # 创建 MQTT 客户端实例-
# mqtt_client = Mqtt(broker_address, port)
#
# try:
# # 连接到 MQTT 服务器
# mqtt_client.connect()
#
# for repeat in range(num_repeats):
# logging.info(f"开始第 {repeat + 1} 次上报")
#
# # 遍历配置文件中的每一行数据
# for config in configs:
# # 构建消息内容
# topic = config["topic"]
# current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
# message = Mqtt.build_message(config, current_time, topic)
#
# # 发送消息
# mqtt_client.publish(topic, message)
#
# # 每次发送之间可以设置一个间隔时间
# time.sleep(interval_between_repeats)
#
# # 每次重复之间设置一个间隔时间
# time.sleep(interval_between_repeats)
#
# except Exception as e:
# logging.error(f"发送消息时发生错误: {e}")
#
# finally:
# # 断开与 MQTT 服务器的连接
# mqtt_client.disconnect()
from hytest import *
import sys
import os
# 获取当前脚本的绝对路径
current_dir = os.path.dirname(os.path.abspath(__file__))
# 构建预定系统的绝对路径
预定系统_path = os.path.abspath(os.path.join(current_dir, '..','..','..'))
# 添加路径
sys.path.append(预定系统_path)
# 导入模块
try:
from 预定系统.Base.base import *
except ModuleNotFoundError as e:
print(f"ModuleNotFoundError: {e}")
print("尝试使用绝对路径导入")
from 预定系统.Base.base import *
def suite_setup():
admin_login()
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<title>测试报告</title>
<meta charset="UTF-8">
<style>body {
font-family: consolas, Verdana, sans-serif;
font-size: .95em;
color: #696e71;
display: grid;
grid-template-columns: 1fr 5rem;
}
.main_section {
width: 90%;
margin: 0 auto;
}
#float_menu{
position:fixed;
top:0;
right:0;
text-align: center;
}
#float_menu .menu-item {
cursor: pointer;
padding: .5em;
margin: .5em 0;
color: #c08580;
background-color: #f8f0ef;
font-size: 1.2em;
}
.result{
display: flex;
}
.result_table{
border-collapse: collapse;
border: 1px solid #f0e0e5;
width: 30em;
text-align: center;
font-size: 1.0em;
}
.result_table td{
border: 1px solid #f0e0e5;
padding: .3em;
}
.result_barchart{
width: 30em;
margin: 0 5em 0 5em;
}
.barchar_item{
margin: 2.5rem 0;
}
.barchart_barbox {
margin: 0.5em 0;
width: 100%;
background-color: #fff;
border: 1px solid #86c2dd;
border-radius: .2em;
}
.barchart_bar {
text-align: right;
height: 1.2rem;
}
.h3_button {
margin: 1.5em;
cursor: pointer;
color: #03a9f4;
}
.info
{
white-space:pre-wrap;
margin: .8em 1.5em;
}
.error-info
{
color: #a64747
}
.suite_dir {
margin: 1em .2em;
padding: .3em;
/* background-color: #dfeff6; */
border: 1px solid #bcd8e4;
}
.suite_file {
margin: 1em .2em;
padding: .3em;
border: 1px solid #bcd8e4;
}
.case {
margin: 1em .2em;
/* padding: .3em; */
border: 1px solid #e7d4d4;
}
.case_class_path{
margin: 0em 1em;
}
.folder_header {
padding: .2em .7em;
background-color: #fffaf9;
cursor: pointer;
}
.setup{
margin: .2em;
/* padding: .3em; */
/* border: 1px solid #e7d4d4; */
}
.teardown{
margin: .2em;
/* padding: .3em;*/
/* border: 1px solid #e7d4d4; */
}
.test_steps{
margin: .2em;
padding: .3em;
/* border: 1px solid #e7d4d4; */
}
.label {
display: inline-block;
padding: .1em .5em;
font-size: .88em;
letter-spacing: 1px;
white-space: nowrap;
color: #0d6ebc;
border-radius: .2em;
min-width: 5em;
margin-right: 2em;
font-family: consolas;
}
/* .suite_setup .label{
color: #219e26 ;
}
.suite_teardown .label{
color: #219e26;
} */
/* .case.pass .casename{
color: #329132 ;
} */
.case.pass .caselabel{
color: white;
background-color: #3b9e3f;
}
/* .case.fail .casename{
color: #a64747;
} */
.case.fail .caselabel{
color: white;
background-color: #a64747;
}
/* .case.abort .casename{
color: #953ab7;
} */
.case.abort .caselabel{
color: white;
background-color: #9c27b0;
}
.case_step {
margin: .8em;
}
.checkpoint_pass {
margin: .8em;
}
.checkpoint_fail {
margin: .8em;
}
.case_step .tag{
color: #2196f3;;
margin: .3em 1em .3em 0;
padding: .1em .3em;
font-size: .92em;
}
.checkpoint_pass .tag{
color: #009806;
margin:.3em 1em .3em .5em;
padding: .1em .3em;
font-size: .92em;
}
.checkpoint_fail .tag{
color: #9c2020;
margin:.3em 1em .3em .5em;
padding: .1em .3em;
font-size: .92em;
}
.screenshot {
border: 1px solid #86c2dd;
}
.executetime {
float: right;
}</style>
<script type="text/javascript">var FOLDER_ALL_CASES = false //是否为精简模式的标记
var ERROR_INFOS = []; // 错误信息列表
var current_error_idx = -1;
// 页面加载后执行的函数
window.addEventListener("load", function(){
// 所有 .folder_header 添加点击事件处理
let folderHeaderEles = document.querySelectorAll(".folder_header");
folderHeaderEles.forEach(function(ele) {
ele.addEventListener("click", function(event) {
let fb = event.target.closest('.folder_header').nextElementSibling;
fb.style.display = fb.style.display === 'none' ? 'block' : 'none'
});
});
// 找到所有的错误信息对象
ERROR_INFOS = document.querySelectorAll(".error-info");
});
function toggle_folder_all_cases(){
let eles = document.querySelectorAll(".folder_body");
FOLDER_ALL_CASES = !FOLDER_ALL_CASES;
document.getElementById('display_mode').innerHTML = FOLDER_ALL_CASES? "Detail" : "Summary"
for (const ele of eles){
ele.style.display = FOLDER_ALL_CASES? "none": "block"
}
}
function previous_error(){
// 查找错误必须是详细模式
if (FOLDER_ALL_CASES)
toggle_folder_all_cases()
current_error_idx -= 1;
if (current_error_idx<0)
current_error_idx = 0
let error = ERROR_INFOS[current_error_idx];
error.scrollIntoView({behavior: "smooth", block: "center", inline: "start"});
}
function next_error(){
// 查找错误必须是详细模式
if (FOLDER_ALL_CASES)
toggle_folder_all_cases()
current_error_idx += 1;
if (current_error_idx > ERROR_INFOS.length-1)
current_error_idx = ERROR_INFOS.length-1
let error = ERROR_INFOS[current_error_idx];
error.scrollIntoView({behavior: "smooth", block: "center", inline: "start"});
}</script>
</head>
<body>
<div class="main_section">
<h1 style="font-family: auto">测试报告</h1>
<h3>统计结果</h3>
<div class="result">
<table class="result_table">
<tbody>
<tr>
<td>hytest 版本</td>
<td>0.8.12</td>
</tr>
<tr>
<td>开始时间</td>
<td>2024/11/02 13:23:43</td>
</tr>
<tr>
<td>结束时间</td>
<td>2024/11/02 13:23:58</td>
</tr>
<tr>
<td>耗时</td>
<td>15.019 秒</td>
</tr>
<tr>
<td>预备执行用例数量</td>
<td>10</td>
</tr>
<tr>
<td>实际执用例行数量</td>
<td>10</td>
</tr>
<tr>
<td>通过</td>
<td>4</td>
</tr>
<tr>
<td>失败</td>
<td style="color:red">6</td>
</tr>
<tr>
<td>异常</td>
<td style="">0</td>
</tr>
<tr>
<td>阻塞</td>
<td style="">0</td>
</tr>
<tr>
<td>套件初始化失败</td>
<td style="">0</td>
</tr>
<tr>
<td>套件清除 失败</td>
<td style="">0</td>
</tr>
<tr>
<td>用例初始化失败</td>
<td style="">0</td>
</tr>
<tr>
<td>用例清除 失败</td>
<td style="">0</td>
</tr>
</tbody>
</table>
<div class="result_barchart">
<div class="barchar_item">
<span>用例通过 40% : 4 个</span>
<div class="barchart_barbox">
<div class="barchart_bar" style="width: 40.0%; background-color: #04AA6D;"></div>
</div>
</div>
<div class="barchar_item">
<span>用例失败 60% : 6 个</span>
<div class="barchart_barbox">
<div class="barchart_bar" style="width: 60.0%; background-color: #bb4069;"></div>
</div>
</div>
<div class="barchar_item">
<span>用例异常 0% : 0 个</span>
<div class="barchart_barbox">
<div class="barchart_bar" style="width: 0.0%; background-color: #9c27b0;"></div>
</div>
</div>
<div class="barchar_item">
<span>用例阻塞 0% : 0 个</span>
<div class="barchart_barbox">
<div class="barchart_bar" style="width: 0.0%; background-color: #dcbdbd;"></div>
</div>
</div>
</div>
</div>
<div style="margin-top:2em">
<h3 style="display:inline">执行日志</h3>
</div>
<div class="exec_log">
<div class="suite_dir" id="suite_dir cases\">
<div>
<span class="label">进入目录</span>
<span>cases\</span>
</div>
<div class="suite_setup setup" id="suite_setup setup cases\">
<div class="folder_header">
<span class="label">套件初始化</span>
<span>cases\</span>
<span class="executetime">2024-11-02 13:23:43</span>
</div>
<div class="folder_body">
<div class="info">'----------' 正在初始化浏览器 '----------'</div>
<div class="info">'----------' 正在处理SSL证书警告 '----------'</div>
<div class="info">'----------' SSL证书警告处理完成 '----------'</div>
</div>
</div>
</div>
<div class="suite_file" id="suite_file cases\登录模块\账号密码登录测试.py">
<div>
<span class="label">进入文件</span>
<span>cases\登录模块\账号密码登录测试.py</span>
</div>
<div class="case fail" id="case_00000001">
<div class="folder_header">
<span class="label caselabel">用例 FAIL</span>
<span class="casename">登录 UI_0001</span>
<span class="executetime">2024-11-02 13:23:51</span>
</div>
<div class="folder_body">
<span class="case_class_path">cases\登录模块\账号密码登录测试.py::UI_000x</span>
<div class="test_steps" id="test_steps 登录 UI_0001">
<span class="label">测试步骤</span>
<div class="case_step">
<span class="tag">步骤 #1</span>
<span>输入账号: None, 密码: Ubains@4321, 验证码: csba</span>
</div>
<div class="case_step">
<span class="tag">步骤 #2</span>
<span>点击登录按钮</span>
</div>
<div class="info">Alert text: </div>
<div class="case_step">
<span class="tag">步骤 #3</span>
<span>校验提示信息: 请输入账号!</span>
</div>
<div class="checkpoint_fail">
<span class="tag">检查点 FAIL</span>
<span>弹出提示</span>
</div>
<div class="info error-info">
Traceback:
File &quot;D:\GithubData\ubains-module-test\ubains-module-test\预定系统\cases\登录模块\账号密码登录测试.py&quot;, line 117, in teststeps
CHECK_POINT('弹出提示', notify_text == check_text)</div>
</div>
<div class="case_teardown teardown case_st_lable" id="case_teardown teardown 登录 UI_0001">
<span class="label">用例清除</span>
<div class="case_step">
<span class="tag">步骤 #4</span>
<span>刷新页面</span>
</div>
</div>
</div>
</div>
<div class="case fail" id="case_00000002">
<div class="folder_header">
<span class="label caselabel">用例 FAIL</span>
<span class="casename">登录 UI_0002</span>
<span class="executetime">2024-11-02 13:23:51</span>
</div>
<div class="folder_body">
<span class="case_class_path">cases\登录模块\账号密码登录测试.py::UI_000x</span>
<div class="test_steps" id="test_steps 登录 UI_0002">
<span class="label">测试步骤</span>
<div class="case_step">
<span class="tag">步骤 #1</span>
<span>输入账号: admin@czj, 密码: None, 验证码: csba</span>
</div>
<div class="case_step">
<span class="tag">步骤 #2</span>
<span>点击登录按钮</span>
</div>
<div class="info">Alert text: </div>
<div class="case_step">
<span class="tag">步骤 #3</span>
<span>校验提示信息: 请输入密码!</span>
</div>
<div class="checkpoint_fail">
<span class="tag">检查点 FAIL</span>
<span>弹出提示</span>
</div>
<div class="info error-info">
Traceback:
File &quot;D:\GithubData\ubains-module-test\ubains-module-test\预定系统\cases\登录模块\账号密码登录测试.py&quot;, line 117, in teststeps
CHECK_POINT('弹出提示', notify_text == check_text)</div>
</div>
<div class="case_teardown teardown case_st_lable" id="case_teardown teardown 登录 UI_0002">
<span class="label">用例清除</span>
<div class="case_step">
<span class="tag">步骤 #4</span>
<span>刷新页面</span>
</div>
</div>
</div>
</div>
<div class="case fail" id="case_00000003">
<div class="folder_header">
<span class="label caselabel">用例 FAIL</span>
<span class="casename">登录 UI_0003</span>
<span class="executetime">2024-11-02 13:23:51</span>
</div>
<div class="folder_body">
<span class="case_class_path">cases\登录模块\账号密码登录测试.py::UI_000x</span>
<div class="test_steps" id="test_steps 登录 UI_0003">
<span class="label">测试步骤</span>
<div class="case_step">
<span class="tag">步骤 #1</span>
<span>输入账号: admin@czj, 密码: Ubains@4321, 验证码: None</span>
</div>
<div class="case_step">
<span class="tag">步骤 #2</span>
<span>点击登录按钮</span>
</div>
<div class="info">Alert text: </div>
<div class="case_step">
<span class="tag">步骤 #3</span>
<span>校验提示信息: 请输入验证码!</span>
</div>
<div class="checkpoint_fail">
<span class="tag">检查点 FAIL</span>
<span>弹出提示</span>
</div>
<div class="info error-info">
Traceback:
File &quot;D:\GithubData\ubains-module-test\ubains-module-test\预定系统\cases\登录模块\账号密码登录测试.py&quot;, line 117, in teststeps
CHECK_POINT('弹出提示', notify_text == check_text)</div>
</div>
<div class="case_teardown teardown case_st_lable" id="case_teardown teardown 登录 UI_0003">
<span class="label">用例清除</span>
<div class="case_step">
<span class="tag">步骤 #4</span>
<span>刷新页面</span>
</div>
</div>
</div>
</div>
<div class="case pass" id="case_00000004">
<div class="folder_header">
<span class="label caselabel">用例 PASS</span>
<span class="casename">登录 UI_0004</span>
<span class="executetime">2024-11-02 13:23:52</span>
</div>
<div class="folder_body">
<span class="case_class_path">cases\登录模块\账号密码登录测试.py::UI_000x</span>
<div class="test_steps" id="test_steps 登录 UI_0004">
<span class="label">测试步骤</span>
<div class="case_step">
<span class="tag">步骤 #1</span>
<span>输入账号: admin@czj112, 密码: Ubains@4321, 验证码: csba</span>
</div>
<div class="case_step">
<span class="tag">步骤 #2</span>
<span>点击登录按钮</span>
</div>
<div class="info">Alert text: 账号或密码错误</div>
<div class="case_step">
<span class="tag">步骤 #3</span>
<span>校验提示信息: 账号或密码错误</span>
</div>
<div class="checkpoint_pass">
<span class="tag">检查点 PASS</span>
<span>弹出提示</span>
</div>
</div>
<div class="case_teardown teardown case_st_lable" id="case_teardown teardown 登录 UI_0004">
<span class="label">用例清除</span>
<div class="case_step">
<span class="tag">步骤 #4</span>
<span>刷新页面</span>
</div>
</div>
</div>
</div>
<div class="case pass" id="case_00000005">
<div class="folder_header">
<span class="label caselabel">用例 PASS</span>
<span class="casename">登录 UI_0005</span>
<span class="executetime">2024-11-02 13:23:52</span>
</div>
<div class="folder_body">
<span class="case_class_path">cases\登录模块\账号密码登录测试.py::UI_000x</span>
<div class="test_steps" id="test_steps 登录 UI_0005">
<span class="label">测试步骤</span>
<div class="case_step">
<span class="tag">步骤 #1</span>
<span>输入账号: adM 12in@czj, 密码: Ubains@4321, 验证码: csba</span>
</div>
<div class="case_step">
<span class="tag">步骤 #2</span>
<span>点击登录按钮</span>
</div>
<div class="info">Alert text: 账号或密码错误</div>
<div class="case_step">
<span class="tag">步骤 #3</span>
<span>校验提示信息: 账号或密码错误</span>
</div>
<div class="checkpoint_pass">
<span class="tag">检查点 PASS</span>
<span>弹出提示</span>
</div>
</div>
<div class="case_teardown teardown case_st_lable" id="case_teardown teardown 登录 UI_0005">
<span class="label">用例清除</span>
<div class="case_step">
<span class="tag">步骤 #4</span>
<span>刷新页面</span>
</div>
</div>
</div>
</div>
<div class="case fail" id="case_00000006">
<div class="folder_header">
<span class="label caselabel">用例 FAIL</span>
<span class="casename">登录 UI_0006</span>
<span class="executetime">2024-11-02 13:23:53</span>
</div>
<div class="folder_body">
<span class="case_class_path">cases\登录模块\账号密码登录测试.py::UI_000x</span>
<div class="test_steps" id="test_steps 登录 UI_0006">
<span class="label">测试步骤</span>
<div class="case_step">
<span class="tag">步骤 #1</span>
<span>输入账号: admin@czj, 密码: 12345, 验证码: csba</span>
</div>
<div class="case_step">
<span class="tag">步骤 #2</span>
<span>点击登录按钮</span>
</div>
<div class="info">Alert text: </div>
<div class="case_step">
<span class="tag">步骤 #3</span>
<span>校验提示信息: 账号或密码错误</span>
</div>
<div class="checkpoint_fail">
<span class="tag">检查点 FAIL</span>
<span>弹出提示</span>
</div>
<div class="info error-info">
Traceback:
File &quot;D:\GithubData\ubains-module-test\ubains-module-test\预定系统\cases\登录模块\账号密码登录测试.py&quot;, line 117, in teststeps
CHECK_POINT('弹出提示', notify_text == check_text)</div>
</div>
<div class="case_teardown teardown case_st_lable" id="case_teardown teardown 登录 UI_0006">
<span class="label">用例清除</span>
<div class="case_step">
<span class="tag">步骤 #4</span>
<span>刷新页面</span>
</div>
</div>
</div>
</div>
<div class="case pass" id="case_00000007">
<div class="folder_header">
<span class="label caselabel">用例 PASS</span>
<span class="casename">登录 UI_0007</span>
<span class="executetime">2024-11-02 13:23:54</span>
</div>
<div class="folder_body">
<span class="case_class_path">cases\登录模块\账号密码登录测试.py::UI_000x</span>
<div class="test_steps" id="test_steps 登录 UI_0007">
<span class="label">测试步骤</span>
<div class="case_step">
<span class="tag">步骤 #1</span>
<span>输入账号: admin@czj, 密码: U bains1s@432, 验证码: csba</span>
</div>
<div class="case_step">
<span class="tag">步骤 #2</span>
<span>点击登录按钮</span>
</div>
<div class="info">Alert text: 账号或密码错误</div>
<div class="case_step">
<span class="tag">步骤 #3</span>
<span>校验提示信息: 账号或密码错误</span>
</div>
<div class="checkpoint_pass">
<span class="tag">检查点 PASS</span>
<span>弹出提示</span>
</div>
</div>
<div class="case_teardown teardown case_st_lable" id="case_teardown teardown 登录 UI_0007">
<span class="label">用例清除</span>
<div class="case_step">
<span class="tag">步骤 #4</span>
<span>刷新页面</span>
</div>
</div>
</div>
</div>
<div class="case fail" id="case_00000008">
<div class="folder_header">
<span class="label caselabel">用例 FAIL</span>
<span class="casename">登录 UI_0008</span>
<span class="executetime">2024-11-02 13:23:54</span>
</div>
<div class="folder_body">
<span class="case_class_path">cases\登录模块\账号密码登录测试.py::UI_000x</span>
<div class="test_steps" id="test_steps 登录 UI_0008">
<span class="label">测试步骤</span>
<div class="case_step">
<span class="tag">步骤 #1</span>
<span>输入账号: admin@czj, 密码: Ubains@4321, 验证码: 123</span>
</div>
<div class="case_step">
<span class="tag">步骤 #2</span>
<span>点击登录按钮</span>
</div>
<div class="info">Alert text: </div>
<div class="case_step">
<span class="tag">步骤 #3</span>
<span>校验提示信息: 验证码错误</span>
</div>
<div class="checkpoint_fail">
<span class="tag">检查点 FAIL</span>
<span>弹出提示</span>
</div>
<div class="info error-info">
Traceback:
File &quot;D:\GithubData\ubains-module-test\ubains-module-test\预定系统\cases\登录模块\账号密码登录测试.py&quot;, line 117, in teststeps
CHECK_POINT('弹出提示', notify_text == check_text)</div>
</div>
<div class="case_teardown teardown case_st_lable" id="case_teardown teardown 登录 UI_0008">
<span class="label">用例清除</span>
<div class="case_step">
<span class="tag">步骤 #4</span>
<span>刷新页面</span>
</div>
</div>
</div>
</div>
<div class="case fail" id="case_00000009">
<div class="folder_header">
<span class="label caselabel">用例 FAIL</span>
<span class="casename">登录 UI_0009</span>
<span class="executetime">2024-11-02 13:23:55</span>
</div>
<div class="folder_body">
<span class="case_class_path">cases\登录模块\账号密码登录测试.py::UI_000x</span>
<div class="test_steps" id="test_steps 登录 UI_0009">
<span class="label">测试步骤</span>
<div class="case_step">
<span class="tag">步骤 #1</span>
<span>输入账号: admin@czj, 密码: Ubains@4321, 验证码: cs 12</span>
</div>
<div class="case_step">
<span class="tag">步骤 #2</span>
<span>点击登录按钮</span>
</div>
<div class="info">Alert text: </div>
<div class="case_step">
<span class="tag">步骤 #3</span>
<span>校验提示信息: 验证码错误</span>
</div>
<div class="checkpoint_fail">
<span class="tag">检查点 FAIL</span>
<span>弹出提示</span>
</div>
<div class="info error-info">
Traceback:
File &quot;D:\GithubData\ubains-module-test\ubains-module-test\预定系统\cases\登录模块\账号密码登录测试.py&quot;, line 117, in teststeps
CHECK_POINT('弹出提示', notify_text == check_text)</div>
</div>
<div class="case_teardown teardown case_st_lable" id="case_teardown teardown 登录 UI_0009">
<span class="label">用例清除</span>
<div class="case_step">
<span class="tag">步骤 #4</span>
<span>刷新页面</span>
</div>
</div>
</div>
</div>
<div class="case pass" id="case_00000010">
<div class="folder_header">
<span class="label caselabel">用例 PASS</span>
<span class="casename">登录 UI_0010</span>
<span class="executetime">2024-11-02 13:23:55</span>
</div>
<div class="folder_body">
<span class="case_class_path">cases\登录模块\账号密码登录测试.py::UI_000x</span>
<div class="test_steps" id="test_steps 登录 UI_0010">
<span class="label">测试步骤</span>
<div class="case_step">
<span class="tag">步骤 #1</span>
<span>输入账号: admin@czj, 密码: Ubains@4321, 验证码: csba</span>
</div>
<div class="case_step">
<span class="tag">步骤 #2</span>
<span>点击登录按钮</span>
</div>
<div class="info">Alert text: 欢迎</div>
<div class="case_step">
<span class="tag">步骤 #3</span>
<span>校验提示信息: 欢迎</span>
</div>
<div class="checkpoint_pass">
<span class="tag">检查点 PASS</span>
<span>弹出提示</span>
</div>
</div>
<div class="case_teardown teardown case_st_lable" id="case_teardown teardown 登录 UI_0010">
<span class="label">用例清除</span>
<div class="case_step">
<span class="tag">步骤 #4</span>
<span>刷新页面</span>
</div>
</div>
</div>
</div>
<div class="suite_teardown teardown" id="suite_teardown teardown cases\">
<div class="folder_header">
<span class="label">套件清除</span>
<span>cases\</span>
<span class="executetime">2024-11-02 13:23:56</span>
</div>
<div class="folder_body">
<div class="info">清除浏览器</div>
</div>
</div>
</div>
</div>
</div>
<div id="float_menu">
<div class="menu-item" onclick="document.querySelector(&quot;body&quot;).scrollIntoView()">页首</div>
<div class="menu-item" onclick="window.open(&quot;http://www.byhy.net/tut/auto/hytest/01&quot;, &quot;_blank&quot;); ">帮助</div>
<div class="menu-item" id="display_mode" onclick="toggle_folder_all_cases()">Summary</div>
<div class="error_jumper" display="block">
<div class="menu-item" onclick="previous_error()" title="上一个错误"></div>
<div class="menu-item" onclick="next_error()" title="下一个错误"></div>
</div>
</div>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<title>测试报告</title>
<meta charset="UTF-8">
<style>body {
font-family: consolas, Verdana, sans-serif;
font-size: .95em;
color: #696e71;
display: grid;
grid-template-columns: 1fr 5rem;
}
.main_section {
width: 90%;
margin: 0 auto;
}
#float_menu{
position:fixed;
top:0;
right:0;
text-align: center;
}
#float_menu .menu-item {
cursor: pointer;
padding: .5em;
margin: .5em 0;
color: #c08580;
background-color: #f8f0ef;
font-size: 1.2em;
}
.result{
display: flex;
}
.result_table{
border-collapse: collapse;
border: 1px solid #f0e0e5;
width: 30em;
text-align: center;
font-size: 1.0em;
}
.result_table td{
border: 1px solid #f0e0e5;
padding: .3em;
}
.result_barchart{
width: 30em;
margin: 0 5em 0 5em;
}
.barchar_item{
margin: 2.5rem 0;
}
.barchart_barbox {
margin: 0.5em 0;
width: 100%;
background-color: #fff;
border: 1px solid #86c2dd;
border-radius: .2em;
}
.barchart_bar {
text-align: right;
height: 1.2rem;
}
.h3_button {
margin: 1.5em;
cursor: pointer;
color: #03a9f4;
}
.info
{
white-space:pre-wrap;
margin: .8em 1.5em;
}
.error-info
{
color: #a64747
}
.suite_dir {
margin: 1em .2em;
padding: .3em;
/* background-color: #dfeff6; */
border: 1px solid #bcd8e4;
}
.suite_file {
margin: 1em .2em;
padding: .3em;
border: 1px solid #bcd8e4;
}
.case {
margin: 1em .2em;
/* padding: .3em; */
border: 1px solid #e7d4d4;
}
.case_class_path{
margin: 0em 1em;
}
.folder_header {
padding: .2em .7em;
background-color: #fffaf9;
cursor: pointer;
}
.setup{
margin: .2em;
/* padding: .3em; */
/* border: 1px solid #e7d4d4; */
}
.teardown{
margin: .2em;
/* padding: .3em;*/
/* border: 1px solid #e7d4d4; */
}
.test_steps{
margin: .2em;
padding: .3em;
/* border: 1px solid #e7d4d4; */
}
.label {
display: inline-block;
padding: .1em .5em;
font-size: .88em;
letter-spacing: 1px;
white-space: nowrap;
color: #0d6ebc;
border-radius: .2em;
min-width: 5em;
margin-right: 2em;
font-family: consolas;
}
/* .suite_setup .label{
color: #219e26 ;
}
.suite_teardown .label{
color: #219e26;
} */
/* .case.pass .casename{
color: #329132 ;
} */
.case.pass .caselabel{
color: white;
background-color: #3b9e3f;
}
/* .case.fail .casename{
color: #a64747;
} */
.case.fail .caselabel{
color: white;
background-color: #a64747;
}
/* .case.abort .casename{
color: #953ab7;
} */
.case.abort .caselabel{
color: white;
background-color: #9c27b0;
}
.case_step {
margin: .8em;
}
.checkpoint_pass {
margin: .8em;
}
.checkpoint_fail {
margin: .8em;
}
.case_step .tag{
color: #2196f3;;
margin: .3em 1em .3em 0;
padding: .1em .3em;
font-size: .92em;
}
.checkpoint_pass .tag{
color: #009806;
margin:.3em 1em .3em .5em;
padding: .1em .3em;
font-size: .92em;
}
.checkpoint_fail .tag{
color: #9c2020;
margin:.3em 1em .3em .5em;
padding: .1em .3em;
font-size: .92em;
}
.screenshot {
border: 1px solid #86c2dd;
}
.executetime {
float: right;
}</style>
<script type="text/javascript">var FOLDER_ALL_CASES = false //是否为精简模式的标记
var ERROR_INFOS = []; // 错误信息列表
var current_error_idx = -1;
// 页面加载后执行的函数
window.addEventListener("load", function(){
// 所有 .folder_header 添加点击事件处理
let folderHeaderEles = document.querySelectorAll(".folder_header");
folderHeaderEles.forEach(function(ele) {
ele.addEventListener("click", function(event) {
let fb = event.target.closest('.folder_header').nextElementSibling;
fb.style.display = fb.style.display === 'none' ? 'block' : 'none'
});
});
// 找到所有的错误信息对象
ERROR_INFOS = document.querySelectorAll(".error-info");
});
function toggle_folder_all_cases(){
let eles = document.querySelectorAll(".folder_body");
FOLDER_ALL_CASES = !FOLDER_ALL_CASES;
document.getElementById('display_mode').innerHTML = FOLDER_ALL_CASES? "Detail" : "Summary"
for (const ele of eles){
ele.style.display = FOLDER_ALL_CASES? "none": "block"
}
}
function previous_error(){
// 查找错误必须是详细模式
if (FOLDER_ALL_CASES)
toggle_folder_all_cases()
current_error_idx -= 1;
if (current_error_idx<0)
current_error_idx = 0
let error = ERROR_INFOS[current_error_idx];
error.scrollIntoView({behavior: "smooth", block: "center", inline: "start"});
}
function next_error(){
// 查找错误必须是详细模式
if (FOLDER_ALL_CASES)
toggle_folder_all_cases()
current_error_idx += 1;
if (current_error_idx > ERROR_INFOS.length-1)
current_error_idx = ERROR_INFOS.length-1
let error = ERROR_INFOS[current_error_idx];
error.scrollIntoView({behavior: "smooth", block: "center", inline: "start"});
}</script>
</head>
<body>
<div class="main_section">
<h1 style="font-family: auto">测试报告</h1>
<h3>统计结果</h3>
<div class="result">
<table class="result_table">
<tbody>
<tr>
<td>hytest 版本</td>
<td>0.8.12</td>
</tr>
<tr>
<td>开始时间</td>
<td>2024/11/02 13:25:42</td>
</tr>
<tr>
<td>结束时间</td>
<td>2024/11/02 13:26:15</td>
</tr>
<tr>
<td>耗时</td>
<td>33.319 秒</td>
</tr>
<tr>
<td>预备执行用例数量</td>
<td>10</td>
</tr>
<tr>
<td>实际执用例行数量</td>
<td>10</td>
</tr>
<tr>
<td>通过</td>
<td>9</td>
</tr>
<tr>
<td>失败</td>
<td style="color:red">1</td>
</tr>
<tr>
<td>异常</td>
<td style="">0</td>
</tr>
<tr>
<td>阻塞</td>
<td style="">0</td>
</tr>
<tr>
<td>套件初始化失败</td>
<td style="">0</td>
</tr>
<tr>
<td>套件清除 失败</td>
<td style="">0</td>
</tr>
<tr>
<td>用例初始化失败</td>
<td style="">0</td>
</tr>
<tr>
<td>用例清除 失败</td>
<td style="">0</td>
</tr>
</tbody>
</table>
<div class="result_barchart">
<div class="barchar_item">
<span>用例通过 90% : 9 个</span>
<div class="barchart_barbox">
<div class="barchart_bar" style="width: 90.0%; background-color: #04AA6D;"></div>
</div>
</div>
<div class="barchar_item">
<span>用例失败 10% : 1 个</span>
<div class="barchart_barbox">
<div class="barchart_bar" style="width: 10.0%; background-color: #bb4069;"></div>
</div>
</div>
<div class="barchar_item">
<span>用例异常 0% : 0 个</span>
<div class="barchart_barbox">
<div class="barchart_bar" style="width: 0.0%; background-color: #9c27b0;"></div>
</div>
</div>
<div class="barchar_item">
<span>用例阻塞 0% : 0 个</span>
<div class="barchart_barbox">
<div class="barchart_bar" style="width: 0.0%; background-color: #dcbdbd;"></div>
</div>
</div>
</div>
</div>
<div style="margin-top:2em">
<h3 style="display:inline">执行日志</h3>
</div>
<div class="exec_log">
<div class="suite_dir" id="suite_dir cases\">
<div>
<span class="label">进入目录</span>
<span>cases\</span>
</div>
<div class="suite_setup setup" id="suite_setup setup cases\">
<div class="folder_header">
<span class="label">套件初始化</span>
<span>cases\</span>
<span class="executetime">2024-11-02 13:25:42</span>
</div>
<div class="folder_body">
<div class="info">'----------' 正在初始化浏览器 '----------'</div>
<div class="info">'----------' 正在处理SSL证书警告 '----------'</div>
<div class="info">'----------' SSL证书警告处理完成 '----------'</div>
</div>
</div>
</div>
<div class="suite_file" id="suite_file cases\登录模块\账号密码登录测试.py">
<div>
<span class="label">进入文件</span>
<span>cases\登录模块\账号密码登录测试.py</span>
</div>
<div class="case pass" id="case_00000001">
<div class="folder_header">
<span class="label caselabel">用例 PASS</span>
<span class="casename">登录 UI_0001</span>
<span class="executetime">2024-11-02 13:25:49</span>
</div>
<div class="folder_body">
<span class="case_class_path">cases\登录模块\账号密码登录测试.py::UI_000x</span>
<div class="test_steps" id="test_steps 登录 UI_0001">
<span class="label">测试步骤</span>
<div class="case_step">
<span class="tag">步骤 #1</span>
<span>输入账号: None, 密码: Ubains@4321, 验证码: csba</span>
</div>
<div class="case_step">
<span class="tag">步骤 #2</span>
<span>点击登录按钮</span>
</div>
<div class="info">Alert text: 请输入账号!</div>
<div class="case_step">
<span class="tag">步骤 #3</span>
<span>校验提示信息: 请输入账号!</span>
</div>
<div class="checkpoint_pass">
<span class="tag">检查点 PASS</span>
<span>弹出提示</span>
</div>
</div>
<div class="case_teardown teardown case_st_lable" id="case_teardown teardown 登录 UI_0001">
<span class="label">用例清除</span>
<div class="case_step">
<span class="tag">步骤 #4</span>
<span>刷新页面</span>
</div>
</div>
</div>
</div>
<div class="case pass" id="case_00000002">
<div class="folder_header">
<span class="label caselabel">用例 PASS</span>
<span class="casename">登录 UI_0002</span>
<span class="executetime">2024-11-02 13:25:51</span>
</div>
<div class="folder_body">
<span class="case_class_path">cases\登录模块\账号密码登录测试.py::UI_000x</span>
<div class="test_steps" id="test_steps 登录 UI_0002">
<span class="label">测试步骤</span>
<div class="case_step">
<span class="tag">步骤 #1</span>
<span>输入账号: admin@czj, 密码: None, 验证码: csba</span>
</div>
<div class="case_step">
<span class="tag">步骤 #2</span>
<span>点击登录按钮</span>
</div>
<div class="info">Alert text: 请输入密码!</div>
<div class="case_step">
<span class="tag">步骤 #3</span>
<span>校验提示信息: 请输入密码!</span>
</div>
<div class="checkpoint_pass">
<span class="tag">检查点 PASS</span>
<span>弹出提示</span>
</div>
</div>
<div class="case_teardown teardown case_st_lable" id="case_teardown teardown 登录 UI_0002">
<span class="label">用例清除</span>
<div class="case_step">
<span class="tag">步骤 #4</span>
<span>刷新页面</span>
</div>
</div>
</div>
</div>
<div class="case pass" id="case_00000003">
<div class="folder_header">
<span class="label caselabel">用例 PASS</span>
<span class="casename">登录 UI_0003</span>
<span class="executetime">2024-11-02 13:25:54</span>
</div>
<div class="folder_body">
<span class="case_class_path">cases\登录模块\账号密码登录测试.py::UI_000x</span>
<div class="test_steps" id="test_steps 登录 UI_0003">
<span class="label">测试步骤</span>
<div class="case_step">
<span class="tag">步骤 #1</span>
<span>输入账号: admin@czj, 密码: Ubains@4321, 验证码: None</span>
</div>
<div class="case_step">
<span class="tag">步骤 #2</span>
<span>点击登录按钮</span>
</div>
<div class="info">Alert text: 请输入验证码!</div>
<div class="case_step">
<span class="tag">步骤 #3</span>
<span>校验提示信息: 请输入验证码!</span>
</div>
<div class="checkpoint_pass">
<span class="tag">检查点 PASS</span>
<span>弹出提示</span>
</div>
</div>
<div class="case_teardown teardown case_st_lable" id="case_teardown teardown 登录 UI_0003">
<span class="label">用例清除</span>
<div class="case_step">
<span class="tag">步骤 #4</span>
<span>刷新页面</span>
</div>
</div>
</div>
</div>
<div class="case pass" id="case_00000004">
<div class="folder_header">
<span class="label caselabel">用例 PASS</span>
<span class="casename">登录 UI_0004</span>
<span class="executetime">2024-11-02 13:25:56</span>
</div>
<div class="folder_body">
<span class="case_class_path">cases\登录模块\账号密码登录测试.py::UI_000x</span>
<div class="test_steps" id="test_steps 登录 UI_0004">
<span class="label">测试步骤</span>
<div class="case_step">
<span class="tag">步骤 #1</span>
<span>输入账号: admin@czj112, 密码: Ubains@4321, 验证码: csba</span>
</div>
<div class="case_step">
<span class="tag">步骤 #2</span>
<span>点击登录按钮</span>
</div>
<div class="info">Alert text: 账号或密码错误</div>
<div class="case_step">
<span class="tag">步骤 #3</span>
<span>校验提示信息: 账号或密码错误</span>
</div>
<div class="checkpoint_pass">
<span class="tag">检查点 PASS</span>
<span>弹出提示</span>
</div>
</div>
<div class="case_teardown teardown case_st_lable" id="case_teardown teardown 登录 UI_0004">
<span class="label">用例清除</span>
<div class="case_step">
<span class="tag">步骤 #4</span>
<span>刷新页面</span>
</div>
</div>
</div>
</div>
<div class="case pass" id="case_00000005">
<div class="folder_header">
<span class="label caselabel">用例 PASS</span>
<span class="casename">登录 UI_0005</span>
<span class="executetime">2024-11-02 13:25:58</span>
</div>
<div class="folder_body">
<span class="case_class_path">cases\登录模块\账号密码登录测试.py::UI_000x</span>
<div class="test_steps" id="test_steps 登录 UI_0005">
<span class="label">测试步骤</span>
<div class="case_step">
<span class="tag">步骤 #1</span>
<span>输入账号: adM 12in@czj, 密码: Ubains@4321, 验证码: csba</span>
</div>
<div class="case_step">
<span class="tag">步骤 #2</span>
<span>点击登录按钮</span>
</div>
<div class="info">Alert text: 账号或密码错误</div>
<div class="case_step">
<span class="tag">步骤 #3</span>
<span>校验提示信息: 账号或密码错误</span>
</div>
<div class="checkpoint_pass">
<span class="tag">检查点 PASS</span>
<span>弹出提示</span>
</div>
</div>
<div class="case_teardown teardown case_st_lable" id="case_teardown teardown 登录 UI_0005">
<span class="label">用例清除</span>
<div class="case_step">
<span class="tag">步骤 #4</span>
<span>刷新页面</span>
</div>
</div>
</div>
</div>
<div class="case pass" id="case_00000006">
<div class="folder_header">
<span class="label caselabel">用例 PASS</span>
<span class="casename">登录 UI_0006</span>
<span class="executetime">2024-11-02 13:26:01</span>
</div>
<div class="folder_body">
<span class="case_class_path">cases\登录模块\账号密码登录测试.py::UI_000x</span>
<div class="test_steps" id="test_steps 登录 UI_0006">
<span class="label">测试步骤</span>
<div class="case_step">
<span class="tag">步骤 #1</span>
<span>输入账号: admin@czj, 密码: 12345, 验证码: csba</span>
</div>
<div class="case_step">
<span class="tag">步骤 #2</span>
<span>点击登录按钮</span>
</div>
<div class="info">Alert text: 账号或密码错误</div>
<div class="case_step">
<span class="tag">步骤 #3</span>
<span>校验提示信息: 账号或密码错误</span>
</div>
<div class="checkpoint_pass">
<span class="tag">检查点 PASS</span>
<span>弹出提示</span>
</div>
</div>
<div class="case_teardown teardown case_st_lable" id="case_teardown teardown 登录 UI_0006">
<span class="label">用例清除</span>
<div class="case_step">
<span class="tag">步骤 #4</span>
<span>刷新页面</span>
</div>
</div>
</div>
</div>
<div class="case pass" id="case_00000007">
<div class="folder_header">
<span class="label caselabel">用例 PASS</span>
<span class="casename">登录 UI_0007</span>
<span class="executetime">2024-11-02 13:26:03</span>
</div>
<div class="folder_body">
<span class="case_class_path">cases\登录模块\账号密码登录测试.py::UI_000x</span>
<div class="test_steps" id="test_steps 登录 UI_0007">
<span class="label">测试步骤</span>
<div class="case_step">
<span class="tag">步骤 #1</span>
<span>输入账号: admin@czj, 密码: U bains1s@432, 验证码: csba</span>
</div>
<div class="case_step">
<span class="tag">步骤 #2</span>
<span>点击登录按钮</span>
</div>
<div class="info">Alert text: 账号或密码错误</div>
<div class="case_step">
<span class="tag">步骤 #3</span>
<span>校验提示信息: 账号或密码错误</span>
</div>
<div class="checkpoint_pass">
<span class="tag">检查点 PASS</span>
<span>弹出提示</span>
</div>
</div>
<div class="case_teardown teardown case_st_lable" id="case_teardown teardown 登录 UI_0007">
<span class="label">用例清除</span>
<div class="case_step">
<span class="tag">步骤 #4</span>
<span>刷新页面</span>
</div>
</div>
</div>
</div>
<div class="case pass" id="case_00000008">
<div class="folder_header">
<span class="label caselabel">用例 PASS</span>
<span class="casename">登录 UI_0008</span>
<span class="executetime">2024-11-02 13:26:06</span>
</div>
<div class="folder_body">
<span class="case_class_path">cases\登录模块\账号密码登录测试.py::UI_000x</span>
<div class="test_steps" id="test_steps 登录 UI_0008">
<span class="label">测试步骤</span>
<div class="case_step">
<span class="tag">步骤 #1</span>
<span>输入账号: admin@czj, 密码: Ubains@4321, 验证码: 123</span>
</div>
<div class="case_step">
<span class="tag">步骤 #2</span>
<span>点击登录按钮</span>
</div>
<div class="info">Alert text: 验证码错误</div>
<div class="case_step">
<span class="tag">步骤 #3</span>
<span>校验提示信息: 验证码错误</span>
</div>
<div class="checkpoint_pass">
<span class="tag">检查点 PASS</span>
<span>弹出提示</span>
</div>
</div>
<div class="case_teardown teardown case_st_lable" id="case_teardown teardown 登录 UI_0008">
<span class="label">用例清除</span>
<div class="case_step">
<span class="tag">步骤 #4</span>
<span>刷新页面</span>
</div>
</div>
</div>
</div>
<div class="case pass" id="case_00000009">
<div class="folder_header">
<span class="label caselabel">用例 PASS</span>
<span class="casename">登录 UI_0009</span>
<span class="executetime">2024-11-02 13:26:08</span>
</div>
<div class="folder_body">
<span class="case_class_path">cases\登录模块\账号密码登录测试.py::UI_000x</span>
<div class="test_steps" id="test_steps 登录 UI_0009">
<span class="label">测试步骤</span>
<div class="case_step">
<span class="tag">步骤 #1</span>
<span>输入账号: admin@czj, 密码: Ubains@4321, 验证码: cs 12</span>
</div>
<div class="case_step">
<span class="tag">步骤 #2</span>
<span>点击登录按钮</span>
</div>
<div class="info">Alert text: 验证码错误</div>
<div class="case_step">
<span class="tag">步骤 #3</span>
<span>校验提示信息: 验证码错误</span>
</div>
<div class="checkpoint_pass">
<span class="tag">检查点 PASS</span>
<span>弹出提示</span>
</div>
</div>
<div class="case_teardown teardown case_st_lable" id="case_teardown teardown 登录 UI_0009">
<span class="label">用例清除</span>
<div class="case_step">
<span class="tag">步骤 #4</span>
<span>刷新页面</span>
</div>
</div>
</div>
</div>
<div class="case fail" id="case_00000010">
<div class="folder_header">
<span class="label caselabel">用例 FAIL</span>
<span class="casename">登录 UI_0010</span>
<span class="executetime">2024-11-02 13:26:10</span>
</div>
<div class="folder_body">
<span class="case_class_path">cases\登录模块\账号密码登录测试.py::UI_000x</span>
<div class="test_steps" id="test_steps 登录 UI_0010">
<span class="label">测试步骤</span>
<div class="case_step">
<span class="tag">步骤 #1</span>
<span>输入账号: admin@czj, 密码: Ubains@4321, 验证码: csba</span>
</div>
<div class="case_step">
<span class="tag">步骤 #2</span>
<span>点击登录按钮</span>
</div>
<div class="info">Alert text: 欢迎 预定标准版测试</div>
<div class="case_step">
<span class="tag">步骤 #3</span>
<span>校验提示信息: 欢迎</span>
</div>
<div class="checkpoint_fail">
<span class="tag">检查点 FAIL</span>
<span>弹出提示</span>
</div>
<div class="info error-info">
Traceback:
File &quot;D:\GithubData\ubains-module-test\ubains-module-test\预定系统\cases\登录模块\账号密码登录测试.py&quot;, line 118, in teststeps
CHECK_POINT('弹出提示', notify_text == check_text)</div>
</div>
<div class="case_teardown teardown case_st_lable" id="case_teardown teardown 登录 UI_0010">
<span class="label">用例清除</span>
<div class="case_step">
<span class="tag">步骤 #4</span>
<span>刷新页面</span>
</div>
</div>
</div>
</div>
<div class="suite_teardown teardown" id="suite_teardown teardown cases\">
<div class="folder_header">
<span class="label">套件清除</span>
<span>cases\</span>
<span class="executetime">2024-11-02 13:26:13</span>
</div>
<div class="folder_body">
<div class="info">清除浏览器</div>
</div>
</div>
</div>
</div>
</div>
<div id="float_menu">
<div class="menu-item" onclick="document.querySelector(&quot;body&quot;).scrollIntoView()">页首</div>
<div class="menu-item" onclick="window.open(&quot;http://www.byhy.net/tut/auto/hytest/01&quot;, &quot;_blank&quot;); ">帮助</div>
<div class="menu-item" id="display_mode" onclick="toggle_folder_all_cases()">Summary</div>
<div class="error_jumper" display="block">
<div class="menu-item" onclick="previous_error()" title="上一个错误"></div>
<div class="menu-item" onclick="next_error()" title="下一个错误"></div>
</div>
</div>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<title>测试报告</title>
<meta charset="UTF-8">
<style>body {
font-family: consolas, Verdana, sans-serif;
font-size: .95em;
color: #696e71;
display: grid;
grid-template-columns: 1fr 5rem;
}
.main_section {
width: 90%;
margin: 0 auto;
}
#float_menu{
position:fixed;
top:0;
right:0;
text-align: center;
}
#float_menu .menu-item {
cursor: pointer;
padding: .5em;
margin: .5em 0;
color: #c08580;
background-color: #f8f0ef;
font-size: 1.2em;
}
.result{
display: flex;
}
.result_table{
border-collapse: collapse;
border: 1px solid #f0e0e5;
width: 30em;
text-align: center;
font-size: 1.0em;
}
.result_table td{
border: 1px solid #f0e0e5;
padding: .3em;
}
.result_barchart{
width: 30em;
margin: 0 5em 0 5em;
}
.barchar_item{
margin: 2.5rem 0;
}
.barchart_barbox {
margin: 0.5em 0;
width: 100%;
background-color: #fff;
border: 1px solid #86c2dd;
border-radius: .2em;
}
.barchart_bar {
text-align: right;
height: 1.2rem;
}
.h3_button {
margin: 1.5em;
cursor: pointer;
color: #03a9f4;
}
.info
{
white-space:pre-wrap;
margin: .8em 1.5em;
}
.error-info
{
color: #a64747
}
.suite_dir {
margin: 1em .2em;
padding: .3em;
/* background-color: #dfeff6; */
border: 1px solid #bcd8e4;
}
.suite_file {
margin: 1em .2em;
padding: .3em;
border: 1px solid #bcd8e4;
}
.case {
margin: 1em .2em;
/* padding: .3em; */
border: 1px solid #e7d4d4;
}
.case_class_path{
margin: 0em 1em;
}
.folder_header {
padding: .2em .7em;
background-color: #fffaf9;
cursor: pointer;
}
.setup{
margin: .2em;
/* padding: .3em; */
/* border: 1px solid #e7d4d4; */
}
.teardown{
margin: .2em;
/* padding: .3em;*/
/* border: 1px solid #e7d4d4; */
}
.test_steps{
margin: .2em;
padding: .3em;
/* border: 1px solid #e7d4d4; */
}
.label {
display: inline-block;
padding: .1em .5em;
font-size: .88em;
letter-spacing: 1px;
white-space: nowrap;
color: #0d6ebc;
border-radius: .2em;
min-width: 5em;
margin-right: 2em;
font-family: consolas;
}
/* .suite_setup .label{
color: #219e26 ;
}
.suite_teardown .label{
color: #219e26;
} */
/* .case.pass .casename{
color: #329132 ;
} */
.case.pass .caselabel{
color: white;
background-color: #3b9e3f;
}
/* .case.fail .casename{
color: #a64747;
} */
.case.fail .caselabel{
color: white;
background-color: #a64747;
}
/* .case.abort .casename{
color: #953ab7;
} */
.case.abort .caselabel{
color: white;
background-color: #9c27b0;
}
.case_step {
margin: .8em;
}
.checkpoint_pass {
margin: .8em;
}
.checkpoint_fail {
margin: .8em;
}
.case_step .tag{
color: #2196f3;;
margin: .3em 1em .3em 0;
padding: .1em .3em;
font-size: .92em;
}
.checkpoint_pass .tag{
color: #009806;
margin:.3em 1em .3em .5em;
padding: .1em .3em;
font-size: .92em;
}
.checkpoint_fail .tag{
color: #9c2020;
margin:.3em 1em .3em .5em;
padding: .1em .3em;
font-size: .92em;
}
.screenshot {
border: 1px solid #86c2dd;
}
.executetime {
float: right;
}</style>
<script type="text/javascript">var FOLDER_ALL_CASES = false //是否为精简模式的标记
var ERROR_INFOS = []; // 错误信息列表
var current_error_idx = -1;
// 页面加载后执行的函数
window.addEventListener("load", function(){
// 所有 .folder_header 添加点击事件处理
let folderHeaderEles = document.querySelectorAll(".folder_header");
folderHeaderEles.forEach(function(ele) {
ele.addEventListener("click", function(event) {
let fb = event.target.closest('.folder_header').nextElementSibling;
fb.style.display = fb.style.display === 'none' ? 'block' : 'none'
});
});
// 找到所有的错误信息对象
ERROR_INFOS = document.querySelectorAll(".error-info");
});
function toggle_folder_all_cases(){
let eles = document.querySelectorAll(".folder_body");
FOLDER_ALL_CASES = !FOLDER_ALL_CASES;
document.getElementById('display_mode').innerHTML = FOLDER_ALL_CASES? "Detail" : "Summary"
for (const ele of eles){
ele.style.display = FOLDER_ALL_CASES? "none": "block"
}
}
function previous_error(){
// 查找错误必须是详细模式
if (FOLDER_ALL_CASES)
toggle_folder_all_cases()
current_error_idx -= 1;
if (current_error_idx<0)
current_error_idx = 0
let error = ERROR_INFOS[current_error_idx];
error.scrollIntoView({behavior: "smooth", block: "center", inline: "start"});
}
function next_error(){
// 查找错误必须是详细模式
if (FOLDER_ALL_CASES)
toggle_folder_all_cases()
current_error_idx += 1;
if (current_error_idx > ERROR_INFOS.length-1)
current_error_idx = ERROR_INFOS.length-1
let error = ERROR_INFOS[current_error_idx];
error.scrollIntoView({behavior: "smooth", block: "center", inline: "start"});
}</script>
</head>
<body>
<div class="main_section">
<h1 style="font-family: auto">测试报告</h1>
<h3>统计结果</h3>
<div class="result">
<table class="result_table">
<tbody>
<tr>
<td>hytest 版本</td>
<td>0.8.12</td>
</tr>
<tr>
<td>开始时间</td>
<td>2024/11/02 13:56:32</td>
</tr>
<tr>
<td>结束时间</td>
<td>2024/11/02 13:57:05</td>
</tr>
<tr>
<td>耗时</td>
<td>33.340 秒</td>
</tr>
<tr>
<td>预备执行用例数量</td>
<td>10</td>
</tr>
<tr>
<td>实际执用例行数量</td>
<td>10</td>
</tr>
<tr>
<td>通过</td>
<td>9</td>
</tr>
<tr>
<td>失败</td>
<td style="color:red">1</td>
</tr>
<tr>
<td>异常</td>
<td style="">0</td>
</tr>
<tr>
<td>阻塞</td>
<td style="">0</td>
</tr>
<tr>
<td>套件初始化失败</td>
<td style="">0</td>
</tr>
<tr>
<td>套件清除 失败</td>
<td style="">0</td>
</tr>
<tr>
<td>用例初始化失败</td>
<td style="">0</td>
</tr>
<tr>
<td>用例清除 失败</td>
<td style="">0</td>
</tr>
</tbody>
</table>
<div class="result_barchart">
<div class="barchar_item">
<span>用例通过 90% : 9 个</span>
<div class="barchart_barbox">
<div class="barchart_bar" style="width: 90.0%; background-color: #04AA6D;"></div>
</div>
</div>
<div class="barchar_item">
<span>用例失败 10% : 1 个</span>
<div class="barchart_barbox">
<div class="barchart_bar" style="width: 10.0%; background-color: #bb4069;"></div>
</div>
</div>
<div class="barchar_item">
<span>用例异常 0% : 0 个</span>
<div class="barchart_barbox">
<div class="barchart_bar" style="width: 0.0%; background-color: #9c27b0;"></div>
</div>
</div>
<div class="barchar_item">
<span>用例阻塞 0% : 0 个</span>
<div class="barchart_barbox">
<div class="barchart_bar" style="width: 0.0%; background-color: #dcbdbd;"></div>
</div>
</div>
</div>
</div>
<div style="margin-top:2em">
<h3 style="display:inline">执行日志</h3>
</div>
<div class="exec_log">
<div class="suite_dir" id="suite_dir cases\">
<div>
<span class="label">进入目录</span>
<span>cases\</span>
</div>
<div class="suite_setup setup" id="suite_setup setup cases\">
<div class="folder_header">
<span class="label">套件初始化</span>
<span>cases\</span>
<span class="executetime">2024-11-02 13:56:32</span>
</div>
<div class="folder_body">
<div class="info">'----------' 正在初始化浏览器 '----------'</div>
<div class="info">'----------' 正在处理SSL证书警告 '----------'</div>
<div class="info">'----------' SSL证书警告处理完成 '----------'</div>
</div>
</div>
</div>
<div class="suite_file" id="suite_file cases\登录模块\账号密码登录测试.py">
<div>
<span class="label">进入文件</span>
<span>cases\登录模块\账号密码登录测试.py</span>
</div>
<div class="case pass" id="case_00000001">
<div class="folder_header">
<span class="label caselabel">用例 PASS</span>
<span class="casename">登录 UI_0001</span>
<span class="executetime">2024-11-02 13:56:39</span>
</div>
<div class="folder_body">
<span class="case_class_path">cases\登录模块\账号密码登录测试.py::UI_000x</span>
<div class="test_steps" id="test_steps 登录 UI_0001">
<span class="label">测试步骤</span>
<div class="case_step">
<span class="tag">步骤 #1</span>
<span>输入账号: None, 密码: Ubains@4321, 验证码: csba</span>
</div>
<div class="case_step">
<span class="tag">步骤 #2</span>
<span>点击登录按钮</span>
</div>
<div class="info">Alert text: 请输入账号!</div>
<div class="case_step">
<span class="tag">步骤 #3</span>
<span>校验提示信息: 请输入账号!</span>
</div>
<div class="checkpoint_pass">
<span class="tag">检查点 PASS</span>
<span>弹出提示</span>
</div>
</div>
<div class="case_teardown teardown case_st_lable" id="case_teardown teardown 登录 UI_0001">
<span class="label">用例清除</span>
<div class="case_step">
<span class="tag">步骤 #4</span>
<span>刷新页面</span>
</div>
</div>
</div>
</div>
<div class="case pass" id="case_00000002">
<div class="folder_header">
<span class="label caselabel">用例 PASS</span>
<span class="casename">登录 UI_0002</span>
<span class="executetime">2024-11-02 13:56:40</span>
</div>
<div class="folder_body">
<span class="case_class_path">cases\登录模块\账号密码登录测试.py::UI_000x</span>
<div class="test_steps" id="test_steps 登录 UI_0002">
<span class="label">测试步骤</span>
<div class="case_step">
<span class="tag">步骤 #1</span>
<span>输入账号: admin@czj, 密码: None, 验证码: csba</span>
</div>
<div class="case_step">
<span class="tag">步骤 #2</span>
<span>点击登录按钮</span>
</div>
<div class="info">Alert text: 请输入密码!</div>
<div class="case_step">
<span class="tag">步骤 #3</span>
<span>校验提示信息: 请输入密码!</span>
</div>
<div class="checkpoint_pass">
<span class="tag">检查点 PASS</span>
<span>弹出提示</span>
</div>
</div>
<div class="case_teardown teardown case_st_lable" id="case_teardown teardown 登录 UI_0002">
<span class="label">用例清除</span>
<div class="case_step">
<span class="tag">步骤 #4</span>
<span>刷新页面</span>
</div>
</div>
</div>
</div>
<div class="case pass" id="case_00000003">
<div class="folder_header">
<span class="label caselabel">用例 PASS</span>
<span class="casename">登录 UI_0003</span>
<span class="executetime">2024-11-02 13:56:41</span>
</div>
<div class="folder_body">
<span class="case_class_path">cases\登录模块\账号密码登录测试.py::UI_000x</span>
<div class="test_steps" id="test_steps 登录 UI_0003">
<span class="label">测试步骤</span>
<div class="case_step">
<span class="tag">步骤 #1</span>
<span>输入账号: admin@czj, 密码: Ubains@4321, 验证码: None</span>
</div>
<div class="case_step">
<span class="tag">步骤 #2</span>
<span>点击登录按钮</span>
</div>
<div class="info">Alert text: 请输入验证码!</div>
<div class="case_step">
<span class="tag">步骤 #3</span>
<span>校验提示信息: 请输入验证码!</span>
</div>
<div class="checkpoint_pass">
<span class="tag">检查点 PASS</span>
<span>弹出提示</span>
</div>
</div>
<div class="case_teardown teardown case_st_lable" id="case_teardown teardown 登录 UI_0003">
<span class="label">用例清除</span>
<div class="case_step">
<span class="tag">步骤 #4</span>
<span>刷新页面</span>
</div>
</div>
</div>
</div>
<div class="case pass" id="case_00000004">
<div class="folder_header">
<span class="label caselabel">用例 PASS</span>
<span class="casename">登录 UI_0004</span>
<span class="executetime">2024-11-02 13:56:43</span>
</div>
<div class="folder_body">
<span class="case_class_path">cases\登录模块\账号密码登录测试.py::UI_000x</span>
<div class="test_steps" id="test_steps 登录 UI_0004">
<span class="label">测试步骤</span>
<div class="case_step">
<span class="tag">步骤 #1</span>
<span>输入账号: admin@czj112, 密码: Ubains@4321, 验证码: csba</span>
</div>
<div class="case_step">
<span class="tag">步骤 #2</span>
<span>点击登录按钮</span>
</div>
<div class="info">Alert text: 账号或密码错误</div>
<div class="case_step">
<span class="tag">步骤 #3</span>
<span>校验提示信息: 账号或密码错误</span>
</div>
<div class="checkpoint_pass">
<span class="tag">检查点 PASS</span>
<span>弹出提示</span>
</div>
</div>
<div class="case_teardown teardown case_st_lable" id="case_teardown teardown 登录 UI_0004">
<span class="label">用例清除</span>
<div class="case_step">
<span class="tag">步骤 #4</span>
<span>刷新页面</span>
</div>
</div>
</div>
</div>
<div class="case pass" id="case_00000005">
<div class="folder_header">
<span class="label caselabel">用例 PASS</span>
<span class="casename">登录 UI_0005</span>
<span class="executetime">2024-11-02 13:56:44</span>
</div>
<div class="folder_body">
<span class="case_class_path">cases\登录模块\账号密码登录测试.py::UI_000x</span>
<div class="test_steps" id="test_steps 登录 UI_0005">
<span class="label">测试步骤</span>
<div class="case_step">
<span class="tag">步骤 #1</span>
<span>输入账号: adM 12in@czj, 密码: Ubains@4321, 验证码: csba</span>
</div>
<div class="case_step">
<span class="tag">步骤 #2</span>
<span>点击登录按钮</span>
</div>
<div class="info">Alert text: 账号或密码错误</div>
<div class="case_step">
<span class="tag">步骤 #3</span>
<span>校验提示信息: 账号或密码错误</span>
</div>
<div class="checkpoint_pass">
<span class="tag">检查点 PASS</span>
<span>弹出提示</span>
</div>
</div>
<div class="case_teardown teardown case_st_lable" id="case_teardown teardown 登录 UI_0005">
<span class="label">用例清除</span>
<div class="case_step">
<span class="tag">步骤 #4</span>
<span>刷新页面</span>
</div>
</div>
</div>
</div>
<div class="case pass" id="case_00000006">
<div class="folder_header">
<span class="label caselabel">用例 PASS</span>
<span class="casename">登录 UI_0006</span>
<span class="executetime">2024-11-02 13:56:45</span>
</div>
<div class="folder_body">
<span class="case_class_path">cases\登录模块\账号密码登录测试.py::UI_000x</span>
<div class="test_steps" id="test_steps 登录 UI_0006">
<span class="label">测试步骤</span>
<div class="case_step">
<span class="tag">步骤 #1</span>
<span>输入账号: admin@czj, 密码: 12345, 验证码: csba</span>
</div>
<div class="case_step">
<span class="tag">步骤 #2</span>
<span>点击登录按钮</span>
</div>
<div class="info">Alert text: 账号或密码错误</div>
<div class="case_step">
<span class="tag">步骤 #3</span>
<span>校验提示信息: 账号或密码错误</span>
</div>
<div class="checkpoint_pass">
<span class="tag">检查点 PASS</span>
<span>弹出提示</span>
</div>
</div>
<div class="case_teardown teardown case_st_lable" id="case_teardown teardown 登录 UI_0006">
<span class="label">用例清除</span>
<div class="case_step">
<span class="tag">步骤 #4</span>
<span>刷新页面</span>
</div>
</div>
</div>
</div>
<div class="case pass" id="case_00000007">
<div class="folder_header">
<span class="label caselabel">用例 PASS</span>
<span class="casename">登录 UI_0007</span>
<span class="executetime">2024-11-02 13:56:47</span>
</div>
<div class="folder_body">
<span class="case_class_path">cases\登录模块\账号密码登录测试.py::UI_000x</span>
<div class="test_steps" id="test_steps 登录 UI_0007">
<span class="label">测试步骤</span>
<div class="case_step">
<span class="tag">步骤 #1</span>
<span>输入账号: admin@czj, 密码: U bains1s@432, 验证码: csba</span>
</div>
<div class="case_step">
<span class="tag">步骤 #2</span>
<span>点击登录按钮</span>
</div>
<div class="info">Alert text: 账号或密码错误</div>
<div class="case_step">
<span class="tag">步骤 #3</span>
<span>校验提示信息: 账号或密码错误</span>
</div>
<div class="checkpoint_pass">
<span class="tag">检查点 PASS</span>
<span>弹出提示</span>
</div>
</div>
<div class="case_teardown teardown case_st_lable" id="case_teardown teardown 登录 UI_0007">
<span class="label">用例清除</span>
<div class="case_step">
<span class="tag">步骤 #4</span>
<span>刷新页面</span>
</div>
</div>
</div>
</div>
<div class="case pass" id="case_00000008">
<div class="folder_header">
<span class="label caselabel">用例 PASS</span>
<span class="casename">登录 UI_0008</span>
<span class="executetime">2024-11-02 13:56:48</span>
</div>
<div class="folder_body">
<span class="case_class_path">cases\登录模块\账号密码登录测试.py::UI_000x</span>
<div class="test_steps" id="test_steps 登录 UI_0008">
<span class="label">测试步骤</span>
<div class="case_step">
<span class="tag">步骤 #1</span>
<span>输入账号: admin@czj, 密码: Ubains@4321, 验证码: 123</span>
</div>
<div class="case_step">
<span class="tag">步骤 #2</span>
<span>点击登录按钮</span>
</div>
<div class="info">Alert text: 验证码错误</div>
<div class="case_step">
<span class="tag">步骤 #3</span>
<span>校验提示信息: 验证码错误</span>
</div>
<div class="checkpoint_pass">
<span class="tag">检查点 PASS</span>
<span>弹出提示</span>
</div>
</div>
<div class="case_teardown teardown case_st_lable" id="case_teardown teardown 登录 UI_0008">
<span class="label">用例清除</span>
<div class="case_step">
<span class="tag">步骤 #4</span>
<span>刷新页面</span>
</div>
</div>
</div>
</div>
<div class="case pass" id="case_00000009">
<div class="folder_header">
<span class="label caselabel">用例 PASS</span>
<span class="casename">登录 UI_0009</span>
<span class="executetime">2024-11-02 13:56:50</span>
</div>
<div class="folder_body">
<span class="case_class_path">cases\登录模块\账号密码登录测试.py::UI_000x</span>
<div class="test_steps" id="test_steps 登录 UI_0009">
<span class="label">测试步骤</span>
<div class="case_step">
<span class="tag">步骤 #1</span>
<span>输入账号: admin@czj, 密码: Ubains@4321, 验证码: cs 12</span>
</div>
<div class="case_step">
<span class="tag">步骤 #2</span>
<span>点击登录按钮</span>
</div>
<div class="info">Alert text: 验证码错误</div>
<div class="case_step">
<span class="tag">步骤 #3</span>
<span>校验提示信息: 验证码错误</span>
</div>
<div class="checkpoint_pass">
<span class="tag">检查点 PASS</span>
<span>弹出提示</span>
</div>
</div>
<div class="case_teardown teardown case_st_lable" id="case_teardown teardown 登录 UI_0009">
<span class="label">用例清除</span>
<div class="case_step">
<span class="tag">步骤 #4</span>
<span>刷新页面</span>
</div>
</div>
</div>
</div>
<div class="case fail" id="case_00000010">
<div class="folder_header">
<span class="label caselabel">用例 FAIL</span>
<span class="casename">登录 UI_0010</span>
<span class="executetime">2024-11-02 13:56:51</span>
</div>
<div class="folder_body">
<span class="case_class_path">cases\登录模块\账号密码登录测试.py::UI_000x</span>
<div class="test_steps" id="test_steps 登录 UI_0010">
<span class="label">测试步骤</span>
<div class="case_step">
<span class="tag">步骤 #1</span>
<span>输入账号: admin@czj, 密码: Ubains@4321, 验证码: csba</span>
</div>
<div class="case_step">
<span class="tag">步骤 #2</span>
<span>点击登录按钮</span>
</div>
<div class="info">Exception occurred: Message:
Stacktrace:
GetHandleVerifier [0x00007FF63C4DFD55+29557]
(No symbol) [0x00007FF63C4521F0]
(No symbol) [0x00007FF63C30B6EA]
(No symbol) [0x00007FF63C35FA15]
(No symbol) [0x00007FF63C35FC6C]
(No symbol) [0x00007FF63C3ABB07]
(No symbol) [0x00007FF63C38753F]
(No symbol) [0x00007FF63C3A88A3]
(No symbol) [0x00007FF63C3872A3]
(No symbol) [0x00007FF63C3512DF]
(No symbol) [0x00007FF63C352451]
GetHandleVerifier [0x00007FF63C80DC4D+3363437]
GetHandleVerifier [0x00007FF63C859AD7+3674359]
GetHandleVerifier [0x00007FF63C84EA7B+3629211]
GetHandleVerifier [0x00007FF63C59FC16+815670]
(No symbol) [0x00007FF63C45D69F]
(No symbol) [0x00007FF63C459264]
(No symbol) [0x00007FF63C459400]
(No symbol) [0x00007FF63C4481AF]
BaseThreadInitThunk [0x00007FFD832E257D+29]
RtlUserThreadStart [0x00007FFD83FCAF08+40]
</div>
<div class="case_step">
<span class="tag">步骤 #3</span>
<span>校验提示信息: 欢迎 预定标准版测试</span>
</div>
<div class="checkpoint_fail">
<span class="tag">检查点 FAIL</span>
<span>弹出提示</span>
</div>
<div class="info error-info">
Traceback:
File &quot;D:\GithubData\自动化脚本-3\ubains-module-test\预定系统\cases\登录模块\账号密码登录测试.py&quot;, line 167, in teststeps
CHECK_POINT('弹出提示', notify_text == check_text)</div>
</div>
<div class="case_teardown teardown case_st_lable" id="case_teardown teardown 登录 UI_0010">
<span class="label">用例清除</span>
<div class="case_step">
<span class="tag">步骤 #4</span>
<span>刷新页面</span>
</div>
</div>
</div>
</div>
<div class="suite_teardown teardown" id="suite_teardown teardown cases\">
<div class="folder_header">
<span class="label">套件清除</span>
<span>cases\</span>
<span class="executetime">2024-11-02 13:57:03</span>
</div>
<div class="folder_body">
<div class="info">清除浏览器</div>
</div>
</div>
</div>
</div>
</div>
<div id="float_menu">
<div class="menu-item" onclick="document.querySelector(&quot;body&quot;).scrollIntoView()">页首</div>
<div class="menu-item" onclick="window.open(&quot;http://www.byhy.net/tut/auto/hytest/01&quot;, &quot;_blank&quot;); ">帮助</div>
<div class="menu-item" id="display_mode" onclick="toggle_folder_all_cases()">Summary</div>
<div class="error_jumper" display="block">
<div class="menu-item" onclick="previous_error()" title="上一个错误"></div>
<div class="menu-item" onclick="next_error()" title="下一个错误"></div>
</div>
</div>
</body>
</html>
\ No newline at end of file
=== [ 收集测试用例 ] ===
== cases\__st__.py
== cases\__init__.py
** no cases in this file, skip it.
== cases\会议室管理\__init__.py
** no cases in this file, skip it.
== cases\授权码管理\__init__.py
** no cases in this file, skip it.
== cases\登录模块\__init__.py
** no cases in this file, skip it.
== cases\登录模块\账号密码登录测试.py
== cases\设备管理\__init__.py
** no cases in this file, skip it.
== cases\设备管理\安卓信息上报.py
** no cases in this file, skip it.
== cases\设备管理\毫米波雷达上报.py
** no cases in this file, skip it.
== cases\账号管理\__st__.py
== cases\账号管理\__init__.py
** no cases in this file, skip it.
== cases\账号管理\部门管理.py
** no cases in this file, skip it.
=== [ 执行测试用例 ] ===
预备执行用例数量 : 10
========= 测试开始 : 20241102_135632 =========
>>> cases\
[ suite setup ] cases\
'----------' 正在初始化浏览器 '----------'
'----------' 正在处理SSL证书警告 '----------'
'----------' SSL证书警告处理完成 '----------'
>>> cases\登录模块\账号密码登录测试.py
* 登录 UI_0001 - 2024-11-02 13:56:39
[ case execution steps ]
-- 第 1 步 -- 输入账号: None, 密码: Ubains@4321, 验证码: csba
-- 第 2 步 -- 点击登录按钮
Alert text: 请输入账号!
-- 第 3 步 -- 校验提示信息: 请输入账号!
** 检查点 ** 弹出提示 ----> 通过
PASS
[ case teardown ] 登录 UI_0001
-- 第 4 步 -- 刷新页面
* 登录 UI_0002 - 2024-11-02 13:56:40
[ case execution steps ]
-- 第 1 步 -- 输入账号: admin@czj, 密码: None, 验证码: csba
-- 第 2 步 -- 点击登录按钮
Alert text: 请输入密码!
-- 第 3 步 -- 校验提示信息: 请输入密码!
** 检查点 ** 弹出提示 ----> 通过
PASS
[ case teardown ] 登录 UI_0002
-- 第 4 步 -- 刷新页面
* 登录 UI_0003 - 2024-11-02 13:56:41
[ case execution steps ]
-- 第 1 步 -- 输入账号: admin@czj, 密码: Ubains@4321, 验证码: None
-- 第 2 步 -- 点击登录按钮
Alert text: 请输入验证码!
-- 第 3 步 -- 校验提示信息: 请输入验证码!
** 检查点 ** 弹出提示 ----> 通过
PASS
[ case teardown ] 登录 UI_0003
-- 第 4 步 -- 刷新页面
* 登录 UI_0004 - 2024-11-02 13:56:43
[ case execution steps ]
-- 第 1 步 -- 输入账号: admin@czj112, 密码: Ubains@4321, 验证码: csba
-- 第 2 步 -- 点击登录按钮
Alert text: 账号或密码错误
-- 第 3 步 -- 校验提示信息: 账号或密码错误
** 检查点 ** 弹出提示 ----> 通过
PASS
[ case teardown ] 登录 UI_0004
-- 第 4 步 -- 刷新页面
* 登录 UI_0005 - 2024-11-02 13:56:44
[ case execution steps ]
-- 第 1 步 -- 输入账号: adM 12in@czj, 密码: Ubains@4321, 验证码: csba
-- 第 2 步 -- 点击登录按钮
Alert text: 账号或密码错误
-- 第 3 步 -- 校验提示信息: 账号或密码错误
** 检查点 ** 弹出提示 ----> 通过
PASS
[ case teardown ] 登录 UI_0005
-- 第 4 步 -- 刷新页面
* 登录 UI_0006 - 2024-11-02 13:56:45
[ case execution steps ]
-- 第 1 步 -- 输入账号: admin@czj, 密码: 12345, 验证码: csba
-- 第 2 步 -- 点击登录按钮
Alert text: 账号或密码错误
-- 第 3 步 -- 校验提示信息: 账号或密码错误
** 检查点 ** 弹出提示 ----> 通过
PASS
[ case teardown ] 登录 UI_0006
-- 第 4 步 -- 刷新页面
* 登录 UI_0007 - 2024-11-02 13:56:47
[ case execution steps ]
-- 第 1 步 -- 输入账号: admin@czj, 密码: U bains1s@432, 验证码: csba
-- 第 2 步 -- 点击登录按钮
Alert text: 账号或密码错误
-- 第 3 步 -- 校验提示信息: 账号或密码错误
** 检查点 ** 弹出提示 ----> 通过
PASS
[ case teardown ] 登录 UI_0007
-- 第 4 步 -- 刷新页面
* 登录 UI_0008 - 2024-11-02 13:56:48
[ case execution steps ]
-- 第 1 步 -- 输入账号: admin@czj, 密码: Ubains@4321, 验证码: 123
-- 第 2 步 -- 点击登录按钮
Alert text: 验证码错误
-- 第 3 步 -- 校验提示信息: 验证码错误
** 检查点 ** 弹出提示 ----> 通过
PASS
[ case teardown ] 登录 UI_0008
-- 第 4 步 -- 刷新页面
* 登录 UI_0009 - 2024-11-02 13:56:50
[ case execution steps ]
-- 第 1 步 -- 输入账号: admin@czj, 密码: Ubains@4321, 验证码: cs 12
-- 第 2 步 -- 点击登录按钮
Alert text: 验证码错误
-- 第 3 步 -- 校验提示信息: 验证码错误
** 检查点 ** 弹出提示 ----> 通过
PASS
[ case teardown ] 登录 UI_0009
-- 第 4 步 -- 刷新页面
* 登录 UI_0010 - 2024-11-02 13:56:51
[ case execution steps ]
-- 第 1 步 -- 输入账号: admin@czj, 密码: Ubains@4321, 验证码: csba
-- 第 2 步 -- 点击登录按钮
Exception occurred: Message:
Stacktrace:
GetHandleVerifier [0x00007FF63C4DFD55+29557]
(No symbol) [0x00007FF63C4521F0]
(No symbol) [0x00007FF63C30B6EA]
(No symbol) [0x00007FF63C35FA15]
(No symbol) [0x00007FF63C35FC6C]
(No symbol) [0x00007FF63C3ABB07]
(No symbol) [0x00007FF63C38753F]
(No symbol) [0x00007FF63C3A88A3]
(No symbol) [0x00007FF63C3872A3]
(No symbol) [0x00007FF63C3512DF]
(No symbol) [0x00007FF63C352451]
GetHandleVerifier [0x00007FF63C80DC4D+3363437]
GetHandleVerifier [0x00007FF63C859AD7+3674359]
GetHandleVerifier [0x00007FF63C84EA7B+3629211]
GetHandleVerifier [0x00007FF63C59FC16+815670]
(No symbol) [0x00007FF63C45D69F]
(No symbol) [0x00007FF63C459264]
(No symbol) [0x00007FF63C459400]
(No symbol) [0x00007FF63C4481AF]
BaseThreadInitThunk [0x00007FFD832E257D+29]
RtlUserThreadStart [0x00007FFD83FCAF08+40]
-- 第 3 步 -- 校验提示信息: 欢迎 预定标准版测试
** 检查点 ** 弹出提示 ----> !! 不通过!!
FAIL
Traceback:
File "D:\GithubData\自动化脚本-3\ubains-module-test\预定系统\cases\登录模块\账号密码登录测试.py", line 167, in teststeps
CHECK_POINT('弹出提示', notify_text == check_text)
File "D:\GithubData\ubains-module-test\ubains-module-test\.venv\lib\site-packages\hytest\common.py", line 76, in CHECK_POINT
raise AssertionError()
AssertionError
[ case teardown ] 登录 UI_0010
-- 第 4 步 -- 刷新页面
[ suite teardown ] cases\
清除浏览器
========= 测试结束 : 20241102_135705 =========
耗时 : 33.340 秒
预备执行用例数量 : 10
实际执行用例数量 : 10
通过 : 9
失败 : 1
异常 : 0
套件初始化失败 : 0
套件清除 失败 : 0
用例初始化失败 : 0
用例清除 失败 : 0
=== [ 收集测试用例 ] ===
== cases\__st__.py
== cases\__init__.py
** no cases in this file, skip it.
== cases\会议室管理\__init__.py
** no cases in this file, skip it.
== cases\授权码管理\__init__.py
** no cases in this file, skip it.
== cases\登录模块\__init__.py
** no cases in this file, skip it.
== cases\登录模块\账号密码登录测试.py
== cases\设备管理\__init__.py
** no cases in this file, skip it.
== cases\设备管理\安卓信息上报.py
=== [ 收集测试用例 ] ===
== cases\__st__.py
== cases\__init__.py
** no cases in this file, skip it.
== cases\会议室管理\__init__.py
** no cases in this file, skip it.
== cases\授权码管理\__init__.py
** no cases in this file, skip it.
== cases\登录模块\__init__.py
** no cases in this file, skip it.
== cases\登录模块\账号密码登录测试.py
== cases\设备管理\__init__.py
** no cases in this file, skip it.
== cases\设备管理\安卓信息上报.py
<<<<<<< HEAD
from 预定系统.base.Mqtt_Send import Mqtt
=======
from 预定系统.base.Mqtt_Android import Mqtt
>>>>>>> 949209b52f0b2ea4a02345aefb25f4daee4ec4bd
from datetime import datetime
import logging
import time
if __name__ == "__main__":
# 读取配置文件
<<<<<<< HEAD
configs = Mqtt.read_config_from_csv('../测试数据/MQTT安卓上报数据.csv')
=======
configs = Mqtt.read_config_from_csv('../测试数据/MQTT心跳上报.csv')
>>>>>>> 949209b52f0b2ea4a02345aefb25f4daee4ec4bd
broker_address = "192.168.5.218"
port = 1883
# topic = "rebootResponseTopic"
num_repeats = 100 # 重复执行的次数
interval_between_repeats = 0.2 # 每次重复之间的间隔时间(秒)
# 创建 MQTT 客户端实例
mqtt_client = Mqtt(broker_address, port)
try:
# 连接到 MQTT 服务器
mqtt_client.connect()
for repeat in range(num_repeats):
logging.info(f"开始第 {repeat + 1} 次上报")
# 遍历配置文件中的每一行数据
for config in configs:
<<<<<<< HEAD
# 构建消息内容-
=======
# 构建消息内容
>>>>>>> 949209b52f0b2ea4a02345aefb25f4daee4ec4bd
topic = config["topic"]
current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
message = Mqtt.build_message(config, current_time, topic)
# 发送消息
mqtt_client.publish(topic, message)
# 每次发送之间可以设置一个间隔时间
time.sleep(interval_between_repeats)
# 每次重复之间设置一个间隔时间
time.sleep(interval_between_repeats)
except Exception as e:
logging.error(f"发送消息时发生错误: {e}")
finally:
# 断开与 MQTT 服务器的连接
mqtt_client.disconnect()
from 预定系统.base.Mqtt_Send import Mqtt
from datetime import datetime
import logging
import time
if __name__ == "__main__":
# 读取配置文件
configs = Mqtt.read_config_from_csv('../测试数据/MQTT毫米波上报数据.csv')
broker_address = "192.168.5.218"
port = 1883
num_repeats = 100 # 重复执行的次数
interval_between_repeats = 0.2 # 每次重复之间的间隔时间(秒)
# 创建 MQTT 客户端实例-
mqtt_client = Mqtt(broker_address, port)
try:
# 连接到 MQTT 服务器
mqtt_client.connect()
for repeat in range(num_repeats):
logging.info(f"开始第 {repeat + 1} 次上报")
# 遍历配置文件中的每一行数据
for config in configs:
# 构建消息内容
topic = config["topic"]
current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
message = Mqtt.build_message(config, current_time, topic)
# 发送消息
mqtt_client.publish(topic, message)
# 每次发送之间可以设置一个间隔时间
time.sleep(interval_between_repeats)
# 每次重复之间设置一个间隔时间
time.sleep(interval_between_repeats)
except Exception as e:
logging.error(f"发送消息时发生错误: {e}")
finally:
# 断开与 MQTT 服务器的连接
mqtt_client.disconnect()
username,password,verification_code
admin@czj,Ubains@4321,
,Ubains@4321,csba
admin@czj,Ubains@4321,
,Ubains@4321,csba
admin@czj,Ubains@4321,
,Ubains@4321,csba
admin@czj2,Ubains@4321,csba
admin@czj,Ubains@4321,csba
admin@,Ubains@4321,csba
admin@czj,Ubains@4321,
,Ubains@4321,csba
admin@czj,Ubains@4321,
,Ubains@4321,csba
admin@czj,Ubains@4321,
,Ubains@4321,csba
admin@czj2,Ubains@4321,csba
admin@czj,Ubains@4321,csba
admin@,Ubains@4321,csba
admin@czj,Ubains@4321,
,Ubains@4321,csba
admin@czj,Ubains@4321,
admin@czj,Ubains@4321,
,Ubains@4321,csba
admin@czj,Ubains@4321,
,Ubains@4321,csba
admin@czj,Ubains@4321,
,Ubains@4321,csba
admin@czj2,Ubains@4321,csba
admin@czj,Ubains@4321,csba
admin@,Ubains@4321,csba
admin@czj,Ubains@4321,
,Ubains@4321,csba
admin@czj,Ubains@4321,
,Ubains@4321,csba
admin@czj,Ubains@4321,
,Ubains@4321,csba
admin@czj2,Ubains@4321,csba
admin@czj,Ubains@4321,csba
admin@,Ubains@4321,csba
admin@czj,Ubains@4321,
,Ubains@4321,csba
admin@czj,Ubains@4321,
,Ubains@4321,csba
admin@czj,Ubains@4321,
,Ubains@4321,csba
admin@czj2,Ubains@4321,csba
admin@czj,Ubains@4321,csba
admin@,Ubains@4321,csba
admin@czj,Ubains@4321,
,Ubains@4321,csba
admin@czj,Ubains@4321,
,Ubains@4321,csba
admin@czj,Ubains@4321,
,Ubains@4321,csba
admin@czj2,Ubains@4321,csba
admin@czj,Ubains@4321,csba
admin@,Ubains@4321,csba
admin@czj,Ubains@4321,
,Ubains@4321,csba
admin@czj,Ubains@4321,
,Ubains@4321,csba
admin@czj,Ubains@4321,
,Ubains@4321,csba
admin@czj2,Ubains@4321,csba
admin@czj,Ubains@4321,csba
admin@,Ubains@4321,csba
admin@czj,Ubains@4321,
,Ubains@4321,csba
admin@czj,Ubains@4321,
,Ubains@4321,csba
admin@czj,Ubains@4321,
,Ubains@4321,csba
admin@czj2,Ubains@4321,csba
admin@czj,Ubains@4321,csba
\ No newline at end of file
topic,clientId,appToken,companyNumber,cnum,conferenceId,macAddress,authCode
rebootResponseTopic,48134e6047a19aaf,AND-8AJ-0021,CN-8AJ-UBAINS,22tcji1m49t45ro0r3zyaj0zqd1863yh,219,20:59:20:00:28:81,AND-8AJ-0021
rebootResponseTopic,48134e6047a19aac,AND-8AJ-0022,CN-8AJ-UBAINS,9arvn9am36cjzlimxm4ojd9xzdzusaup,219,20:59:20:00:28:82,AND-8AJ-0022
rebootResponseTopic,48134e6047a19aab,AND-8AJ-0023,CN-8AJ-UBAINS,v3ydnq9u34ocunzanac6l3q8atkvvic3,219,20:59:20:00:28:83,AND-8AJ-0023
rebootResponseTopic,48134e6047a19aaz,AND-8AJ-0024,CN-8AJ-UBAINS,r8xvvvs4r7hhzhfi4i2zldoxoe4estss,219,20:59:20:00:28:84,AND-8AJ-0024
rebootResponseTopic,48134e6047a19aax,AND-8AJ-0025,CN-8AJ-UBAINS,r8xvvvs4r7hhzhfi4i2zldoxoe4estss,219,20:59:20:00:28:85,AND-8AJ-0025
\ No newline at end of file
topic,clientId,deviceId
/uams/android/broadcast,48134e6047a19aaf,aa44e258a4e1e571
/uams/android/broadcast,48134e6047a19aac,aa44e258a4e1e572
/uams/android/broadcast,48134e6047a19aab,aa44e258a4e1e573
/uams/android/broadcast,48134e6047a19aaz,aa44e258a4e1e574
/uams/android/broadcast,48134e6047a19aax,aa44e258a4e1e575
\ No newline at end of file
import pytest
import logging
from selenium.common import StaleElementReferenceException
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import csv
from 预定系统.base.Broswer_driver import Browser_driver
def read_csv_data():
"""
读取 CSV 文件数据
"""
data = []
try:
with open('../测试数据/Login_Test.csv', mode='r', encoding='utf-8') as csvfile:
csv_reader = csv.DictReader(csvfile)
for row in csv_reader:
data.append((row['username'], row['password'], row['verification_code']))
except FileNotFoundError:
logger.error("CSV 文件未找到,请检查文件路径")
pytest.exit("CSV 文件未找到,请检查文件路径")
except Exception as e:
logger.error(f"出现错误: {e}")
pytest.exit(f"出现错误: {e}")
return data
# 设置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
@pytest.fixture(scope='session')
def driver():
"""
初始化浏览器并打开指定URL
"""
url = 'https://192.168.5.218'
logging.info("'----------' 正在初始化浏览器 '----------'")
try:
driver = Browser_driver().browser_init() # 初始化浏览器驱动
logging.info("'----------' 浏览器初始化成功 '----------'")
except Exception as e:
logging.error(f"浏览器初始化失败: {e}")
raise
driver.implicitly_wait(10) # 设置隐式等待时间为10秒
driver.maximize_window() # 最大化浏览器窗口
logging.info("'----------' 正在打开URL '----------'")
try:
driver.get(url)
logging.info(f"成功打开URL: {url}")
except Exception as e:
logging.error(f"打开URL失败: {e}")
raise
handle_ssl_warning(driver) # 处理可能存在的SSL证书警告
yield driver
driver.quit() # 在测试结束后关闭浏览器
def handle_ssl_warning(driver):
"""处理 SSL 证书警告"""
try:
logging.info("'----------' 正在处理SSL证书警告 '----------'")
WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, '//*[@id="details-button"]'))
).click()
WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, '//*[@id="proceed-link"]'))
).click()
# 等待页面加载完成
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.TAG_NAME, 'body'))
)
logging.info("'----------' SSL证书警告处理完成 '----------'")
except Exception as e:
logging.error(f"处理 SSL 证书警告遇到错误: {e}")
raise
def _find_element(driver, by, value):
"""
查找元素,并处理可能的异常
"""
try:
return WebDriverWait(driver, 20).until(
EC.presence_of_element_located((by, value))
)
except StaleElementReferenceException:
return WebDriverWait(driver, 20).until(
EC.presence_of_element_located((by, value))
)
def perform_login(driver, username, password, verification_code):
"""
执行登录操作
"""
try:
# 清除并输入用户名
username_input = _find_element(driver, By.XPATH,
'//*[@id="app"]/div/div[3]/div[1]/div[2]/div/form/div[1]/div/input')
username_input.clear()
username_input.send_keys(username)
# 清除并输入密码
password_input = _find_element(driver, By.XPATH,
'//*[@id="app"]/div/div[3]/div[1]/div[2]/div/form/div[2]/div/input')
password_input.clear()
password_input.send_keys(password)
# 清除并输入验证码
verification_input = _find_element(driver, By.XPATH,
'//*[@id="app"]/div/div[3]/div[1]/div[2]/div/form/div[3]/div[1]/div/input')
verification_input.clear()
verification_input.send_keys(verification_code)
# 点击登录按钮
login_button = _find_element(driver, By.XPATH, '//*[@id="app"]/div/div[3]/div[1]/div[2]/div/form/div[4]/input')
login_button.click()
if username | password | verification_code == "":
check_login_null(driver)
logger.info("登录失败,必填项不能为空!断言成功!\n")
elif check_login_failure(driver):
logger.info("登录失败, 必填项错误!断言成功!\n")
elif check_login_success(driver):
logger.info("登录成功,断言成功!\n")
return_to_login_page(driver) # 返回登录页面
# # 检查登录是否成功
# if check_login_null(driver):
# logger.info("登录失败,必填项不能为空!断言成功!\n")
#
# elif check_login_success(driver):
# logger.info("登录成功,断言成功!\n")
# return_to_login_page(driver) # 返回登录页面
# elif check_login_failure(driver):
# logger.info("登录失败, 必填项错误!断言成功!\n")
else:
logger.error("登录状态未知,断言失败!\n")
pytest.fail("登录状态未知,断言失败!")
except StaleElementReferenceException as e:
logger.error(f"元素已失效,重新查找... {e}\n")
pytest.fail(f"元素已失效,重新查找... {e}")
except Exception as e:
logger.error(f"登录操作失败: {e}\n")
pytest.fail(f"登录操作失败: {e}")
def return_to_login_page(driver):
"""
返回登录页面
"""
try:
logout_button = _find_element(driver, By.XPATH, '//*[@id="app"]/div/div[1]/div/div[1]/div[2]/div[2]')
logout_button.click()
logging.info("已成功返回登录页面\n")
except Exception as e:
logger.error(f"返回登录页面失败: {e}\n")
pytest.fail(f"返回登录页面失败: {e}")
def check_login_null(driver):
"""
检查登录失败,必填项为空的情况
"""
try:
login_element_text = WebDriverWait(driver, 10).until(
EC.visibility_of_element_located((By.XPATH, '/html/body/div[2]/p'))
).text
assert "请输入" in login_element_text, "登录失败后未找到'请输入'提示语"
return True
except Exception as e:
logger.error(f"登录失败检查失败: {e}")
return False
def check_login_success(driver):
"""
检查登录成功的情况
"""
try:
message_element_text = WebDriverWait(driver, 10).until(
EC.visibility_of_element_located((By.XPATH, "//*[contains(text(), '欢迎')]"))
).text
assert "欢迎 预定标准版测试" == message_element_text, "登录成功后找到'欢迎 预定标准版测试'提示语"
driver.find_element(By.XPATH, '//*[@id="app"]/div/div[1]/div/img[3]').click()
driver.refresh()
driver.implicitly_wait(5)
return True
except Exception as e:
logger.error(f"登录成功检查失败: {e}")
return False
def check_login_failure(driver):
"""
检查登录失败的情况
"""
try:
login_element_text = WebDriverWait(driver, 10).until(
EC.visibility_of_element_located((By.XPATH, '//*[@id="app"]/div/div[3]/div[1]/div[1]/div[1]'))
).text
assert "账号登录" == login_element_text, "登录失败后未找到'账号登录'提示语"
return True
except Exception as e:
logger.error(f"登录失败检查失败: {e}")
return False
@pytest.mark.parametrize("username,password,verification_code", read_csv_data())
def test_login_from_csv(driver, username, password, verification_code):
"""
从 CSV 文件读取并测试登录情况
"""
logger.info(f"'----------' 开始执行测试 '----------'\n")
perform_login(driver, username, password, verification_code)
logger.info(f"'----------' 执行完成测试 '----------'\n")
driver.implicitly_wait(10)
if __name__ == '__main__':
pytest.main()
import pytest
import logging
import os
import csv
from selenium.common import StaleElementReferenceException
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from 预定系统.base.Broswer_driver import Browser_driver
# 初始化日志记录器
logging.basicConfig(level=logging.ERROR, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
def read_csv_data(file_path=None):
"""
读取 CSV 文件数据
"""
# 初始化数据列表,用于存储 CSV 文件中的数据
data = []
# 使用环境变量或参数指定文件路径
if file_path is None:
file_path = os.getenv('CSV_FILE_PATH', '../测试数据/Login_Test.csv')
try:
# 打开 CSV 文件,使用 utf-8 编码读取
with open(file_path, mode='r', encoding='utf-8') as csvfile:
# 使用 csv.DictReader 读取 CSV 文件,自动将每行数据转换为字典
csv_reader = csv.DictReader(csvfile)
# 遍历每行数据,提取用户名、密码和验证码,将其作为元组添加到数据列表中
for row in csv_reader:
data.append((row['username'], row['password'], row['verification_code']))
except FileNotFoundError:
# 如果 CSV 文件未找到,记录错误日志并退出测试
logger.error("CSV 文件未找到,请检查文件路径")
pytest.exit("CSV 文件未找到,请检查文件路径")
except csv.Error as e:
# 如果 CSV 格式错误,记录错误日志并退出测试
logger.error(f"CSV 格式错误: {e}")
pytest.exit(f"CSV 格式错误: {e}")
except Exception as e:
# 如果有其他异常发生,记录错误日志并退出测试
logger.error(f"出现错误: {e}")
pytest.exit(f"出现错误: {e}")
# 返回读取的数据列表
return data
@pytest.fixture(scope='session')
def driver():
"""
初始化浏览器并打开指定URL
"""
url = 'https://nat.ubainsyun.com:11046' # 通过配置文件获取URL
# url = 'https://192.168.5.218'
logging.info("'----------' 正在初始化浏览器 '----------'")
try:
driver = Browser_driver().browser_init() # 初始化浏览器驱动
logging.info("'----------' 浏览器初始化成功 '----------'")
except Exception as e:
logging.error(f"浏览器初始化失败: {e}")
raise
driver.implicitly_wait(10) # 设置隐式等待时间为10秒
driver.maximize_window() # 最大化浏览器窗口
logging.info("'----------' 正在打开URL '----------'")
try:
driver.get(url)
logging.info(f"成功打开URL: {url}")
except Exception as e:
logging.error(f"打开URL失败: {e}")
raise
handle_ssl_warning(driver) # 处理可能存在的SSL证书警告
yield driver
driver.quit() # 在测试结束后关闭浏览器
def handle_ssl_warning(driver):
"""
处理 SSL 证书警告
此函数用于在网页浏览器中处理 SSL 证书错误。它通过点击特定的按钮来忽略 SSL 警告,以便在自动化测试中继续进行。
参数:
- driver: WebDriver实例,用于控制网页浏览器的行为
异常:
- 如果在处理 SSL 警告过程中发生任何错误,会记录错误信息并抛出异常
"""
try:
# 记录处理 SSL 证书警告的开始信息
logging.info("'----------' 正在处理SSL证书警告 '----------'")
# 等待并点击“详细信息”按钮
WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, '//*[@id="details-button"]'))
).click()
# 等待并点击“继续”链接,以忽略 SSL 警告
WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, '//*[@id="proceed-link"]'))
).click()
# 等待页面加载完成
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.TAG_NAME, 'body'))
)
# 记录处理 SSL 证书警告完成的信息
logging.info("'----------' SSL证书警告处理完成 '----------'")
except Exception as e:
# 记录处理 SSL 证书警告过程中遇到的错误,并抛出异常
logging.error(f"处理 SSL 证书警告遇到错误: {e}")
raise
def _find_element(driver, by, value):
"""
查找元素,并处理可能的异常
该函数尝试在给定的驱动程序(driver)中查找一个元素,该元素由定位方式(by)和定位值(value)共同确定。
如果在查找过程中出现StaleElementReferenceException异常,即元素可能不再附属于当前页面,
则函数会再次尝试查找该元素,以确保元素被正确找到并返回。
参数:
- driver: WebDriver实例,用于操作浏览器。
- by: 字符串,指定查找元素的定位方式(如ID, XPATH等)。
- value: 字符串,定位方式对应的值。
返回:
- 找到的元素对象。
"""
try:
# 使用WebDriverWait等待最多20秒,直到元素被定位到。
# 这里使用presence_of_element_located预期条件,以等待元素出现在DOM中。
return WebDriverWait(driver, 20).until(
EC.presence_of_element_located((by, value))
)
except StaleElementReferenceException:
# 如果抛出StaleElementReferenceException异常,说明页面可能已经变化,
# 导致原先的元素引用失效。这时再次尝试查找元素。
return WebDriverWait(driver, 20).until(
EC.presence_of_element_located((by, value))
)
def perform_login(driver, username, password, verification_code):
"""
执行登录操作
参数:
- driver: 浏览器驱动
- username: 用户名
- password: 密码
- verification_code: 验证码
该函数通过浏览器驱动模拟用户登录过程,依次输入用户名、密码和验证码,然后点击登录按钮。
登录后,根据返回的页面判断登录是否成功,并记录相应的日志信息。
"""
# 隐式等待确保元素能被找到
driver.implicitly_wait(5)
# 刷新页面以确保登录页面最新
driver.refresh()
try:
# 清除并输入用户名
username_input = _find_element(driver, By.XPATH,
'//*[@id="app"]/div/div[3]/div[1]/div[2]/div/form/div[1]/div/input')
username_input.clear()
username_input.send_keys(username)
# 清除并输入密码
password_input = _find_element(driver, By.XPATH,
'//*[@id="app"]/div/div[3]/div[1]/div[2]/div/form/div[2]/div/input')
password_input.clear()
password_input.send_keys(password)
# 清除并输入验证码
verification_input = _find_element(driver, By.XPATH,
'//*[@id="app"]/div/div[3]/div[1]/div[2]/div/form/div[3]/div[1]/div/input')
verification_input.clear()
verification_input.send_keys(verification_code)
# 点击登录按钮
login_button = _find_element(driver, By.XPATH, '//*[@id="app"]/div/div[3]/div[1]/div[2]/div/form/div[4]/input')
login_button.click()
# 检查登录是否成功
if check_login_null(driver):
# 登录失败,必填项不能为空
logger.info("登录失败,必填项不能为空!断言成功!")
elif check_login_success(driver):
# 登录成功
logger.info("登录成功,断言成功!")
return_to_login_page(driver) # 返回登录页面
elif check_login_failure(driver):
# 登录失败,必填项错误
logger.info("登录失败, 必填项错误!断言成功!")
else:
# 登录状态未知
logger.error("登录状态未知,断言失败!")
pytest.fail("登录状态未知,断言失败!")
except StaleElementReferenceException as e:
# 元素已失效,重新查找
logger.error(f"元素已失效,重新查找... {e}")
pytest.fail(f"元素已失效,重新查找... {e}")
except Exception as e:
# 登录操作失败
logger.error(f"登录操作失败: {e}")
pytest.fail(f"登录操作失败: {e}")
def return_to_login_page(driver):
"""
返回登录页面
通过点击退出按钮操作,实现从当前页面返回登录页面的功能。
参数:
- driver: WebDriver实例,用于操作浏览器。
返回值:
"""
try:
# 定位到退出按钮并点击
logout_button = _find_element(driver, By.XPATH, '//*[@id="app"]/div/div[1]/div/img[3]')
logout_button.click()
# 记录日志,表明已成功尝试返回登录页面
logging.info("已成功返回登录页面")
# 刷新页面,并等待一段时间以确保页面加载完成
driver.refresh()
driver.implicitly_wait(5)
except Exception as e:
# 如果发生异常,记录错误日志并使测试用例失败
logger.error(f"返回登录页面失败: {e}")
pytest.fail(f"返回登录页面失败: {e}")
def check_login_null(driver):
"""
检查登录失败,必填项为空的情况
"""
try:
# 使用WebDriverWait等待器,等待最多10秒,直到登录失败的提示元素可见
login_element_text = WebDriverWait(driver, 10).until(
EC.visibility_of_element_located((By.XPATH, '/html/body/div[2]/p'))
).text
# 断言登录失败后,提示信息中包含'请输入'关键词
assert "请输入" in login_element_text, "登录失败后未找到'请输入'提示语"
return True
except Exception as e:
# 异常情况下,记录错误日志,并返回False表示检查未通过
logger.error(f"登录失败检查失败: {e}")
return False
def check_login_success(driver):
"""
检查登录成功的情况
"""
try:
# 等待并获取登录成功后的欢迎信息
message_element_text = WebDriverWait(driver, 10).until(
EC.visibility_of_element_located((By.XPATH, "//*[contains(text(), '欢迎')]"))
).text
# 断言欢迎信息是否符合预期
assert "欢迎 预定标准版测试" == message_element_text, "登录成功后找到'欢迎 预定标准版测试'提示语"
# 如果一切正常,返回True
return True
except Exception as e:
# 如果检查过程中发生异常,记录错误信息,并返回False
logger.error(f"登录成功检查失败: {e}")
return False
def check_login_failure(driver):
"""
检查登录失败的情况
"""
try:
# 使用WebDriverWait等待,直到定位到特定XPath的元素可见,获取该元素的文本
login_element_text = WebDriverWait(driver, 10).until(
EC.visibility_of_element_located((By.XPATH, '//*[@id="app"]/div/div[3]/div[1]/div[1]/div[1]'))
).text
# 断言登录元素的文本是否为"账号登录",如果符合,则说明登录失败检查成功
assert "账号登录" == login_element_text, "登录失败后未找到'账号登录'提示语"
return True
except Exception as e:
# 如果发生异常,记录错误信息并返回False,表示登录失败检查失败
logger.error(f"登录失败检查失败: {e}")
return False
@pytest.mark.parametrize("username,password,verification_code", read_csv_data())
def test_login_from_csv(driver, username, password, verification_code):
"""
从 CSV 文件读取并测试登录情况
"""
# 初始化日志记录,标记测试开始
logger.info(f"'----------' 开始执行测试 '----------'")
# 执行登录操作,传递驱动、用户名、密码和验证码
perform_login(driver, username, password, verification_code)
# 登录操作完成后,记录日志,标记测试结束
logger.info(f"'----------' 执行完成测试 '----------'")
# 隐式等待,确保后续操作前页面加载完成
driver.implicitly_wait(10)
if __name__ == '__main__':
pytest.main()
# import pytest
# import logging
# import os
# import csv
# from selenium.webdriver.common.by import By
# from selenium.webdriver.support.ui import WebDriverWait
# from selenium.webdriver.support import expected_conditions as EC
# from selenium.common import StaleElementReferenceException
# from selenium.webdriver import Chrome
#
# from 登录模块.base.Base import Base
# from 登录模块.base.Broswer_driver import Browser_driver
#
# # 初始化日志记录器
# logging.basicConfig(level=logging.ERROR, format='%(asctime)s - %(levelname)s - %(message)s')
# logger = logging.getLogger(__name__)
#
# def read_csv_data(file_path=None):
# """
# 读取 CSV 文件数据
# """
# data = []
# if file_path is None:
# file_path = os.getenv('CSV_FILE_PATH', 'Login_Test.csv')
#
# try:
# with open(file_path, mode='r', encoding='utf-8') as csvfile:
# csv_reader = csv.DictReader(csvfile)
# for row in csv_reader:
# data.append((row['username'], row['password'], row['verification_code']))
# except FileNotFoundError:
# logger.error("CSV 文件未找到,请检查文件路径")
# pytest.exit("CSV 文件未找到,请检查文件路径")
# except csv.Error as e:
# logger.error(f"CSV 格式错误: {e}")
# pytest.exit(f"CSV 格式错误: {e}")
# except Exception as e:
# logger.error(f"出现错误: {e}")
# pytest.exit(f"出现错误: {e}")
#
# return data
#
# @pytest.fixture(scope='session')
# def driver():
# """
# 初始化浏览器并打开指定URL
# """
# url = 'https://nat.ubainsyun.com:11046'
# logging.info("'----------' 正在初始化浏览器 '----------'")
# try:
# driver = Browser_driver().browser_init()
# logging.info("'----------' 浏览器初始化成功 '----------'")
# except Exception as e:
# logging.error(f"浏览器初始化失败: {e}")
# raise
#
# driver.implicitly_wait(10)
# driver.maximize_window()
# logging.info("'----------' 正在打开URL '----------'")
#
# try:
# driver.get(url)
# logging.info(f"成功打开URL: {url}")
# except Exception as e:
# logging.error(f"打开URL失败: {e}")
# raise
#
# yield driver
# driver.quit()
#
# def test_login_from_csv(driver):
# """
# 从 CSV 文件读取并测试登录情况
# """
# logger.info(f"'----------' 开始执行测试 '----------'")
# base = Base(driver)
#
# for username, password, verification_code in read_csv_data():
# base.perform_login(username, password, verification_code)
#
# logger.info(f"'----------' 执行完成测试 '----------'")
# driver.implicitly_wait(10)
#
# if __name__ == '__main__':
# pytest.main()
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论