WebsocketTest 1.0.3__tar.gz → 1.0.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- websockettest-1.0.5/PKG-INFO +16 -0
- {WebsocketTest-1.0.3 → websockettest-1.0.5}/WebsocketTest/caseScript/Aqua.py +5 -8
- {WebsocketTest-1.0.3 → websockettest-1.0.5}/WebsocketTest/caseScript/Gateway.py +5 -5
- websockettest-1.0.5/WebsocketTest/cli.py +26 -0
- websockettest-1.0.5/WebsocketTest/commands/startproject.py +28 -0
- websockettest-1.0.5/WebsocketTest/commands/test.py +20 -0
- {WebsocketTest-1.0.3 → websockettest-1.0.5}/WebsocketTest/common/Assertion.py +1 -1
- {WebsocketTest-1.0.3 → websockettest-1.0.5}/WebsocketTest/common/WSBaseApi.py +5 -4
- {WebsocketTest-1.0.3 → websockettest-1.0.5}/WebsocketTest/common/assertUtils.py +1 -1
- websockettest-1.0.5/WebsocketTest/common/logger.py +14 -0
- {WebsocketTest-1.0.3 → websockettest-1.0.5}/WebsocketTest/common/utils.py +2 -3
- {WebsocketTest-1.0.3 → websockettest-1.0.5}/WebsocketTest/conftest.py +1 -5
- {WebsocketTest-1.0.3 → websockettest-1.0.5}/WebsocketTest/run_tests.py +21 -18
- websockettest-1.0.5/WebsocketTest.egg-info/PKG-INFO +16 -0
- {WebsocketTest-1.0.3 → websockettest-1.0.5}/WebsocketTest.egg-info/SOURCES.txt +4 -4
- websockettest-1.0.5/WebsocketTest.egg-info/entry_points.txt +2 -0
- {WebsocketTest-1.0.3 → websockettest-1.0.5}/setup.cfg +3 -0
- websockettest-1.0.5/setup.py +43 -0
- WebsocketTest-1.0.3/PKG-INFO +0 -7
- WebsocketTest-1.0.3/WebsocketTest/cli.py +0 -56
- WebsocketTest-1.0.3/WebsocketTest/common/WebSocketApi.py +0 -73
- WebsocketTest-1.0.3/WebsocketTest/common/logger.py +0 -27
- WebsocketTest-1.0.3/WebsocketTest/testcase/test_all.py +0 -10
- WebsocketTest-1.0.3/WebsocketTest.egg-info/PKG-INFO +0 -7
- WebsocketTest-1.0.3/WebsocketTest.egg-info/entry_points.txt +0 -2
- WebsocketTest-1.0.3/setup.py +0 -26
- {WebsocketTest-1.0.3 → websockettest-1.0.5}/README.md +0 -0
- {WebsocketTest-1.0.3 → websockettest-1.0.5}/WebsocketTest/__init__.py +0 -0
- {WebsocketTest-1.0.3 → websockettest-1.0.5}/WebsocketTest/caseScript/__init__.py +0 -0
- {WebsocketTest-1.0.3/WebsocketTest/common → websockettest-1.0.5/WebsocketTest/commands}/__init__.py +0 -0
- {WebsocketTest-1.0.3/WebsocketTest/testcase → websockettest-1.0.5/WebsocketTest/common}/__init__.py +0 -0
- {WebsocketTest-1.0.3 → websockettest-1.0.5}/WebsocketTest.egg-info/dependency_links.txt +0 -0
- {WebsocketTest-1.0.3 → websockettest-1.0.5}/WebsocketTest.egg-info/requires.txt +0 -0
- {WebsocketTest-1.0.3 → websockettest-1.0.5}/WebsocketTest.egg-info/top_level.txt +0 -0
@@ -0,0 +1,16 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: WebsocketTest
|
3
|
+
Version: 1.0.5
|
4
|
+
Summary: websocket api autotest
|
5
|
+
Author: chencheng
|
6
|
+
Requires-Python: >=3.10
|
7
|
+
Requires-Dist: allure_python_commons==2.13.5
|
8
|
+
Requires-Dist: numpy==2.2.4
|
9
|
+
Requires-Dist: pandas==2.2.3
|
10
|
+
Requires-Dist: pytest==8.2.2
|
11
|
+
Requires-Dist: PyYAML==6.0.2
|
12
|
+
Requires-Dist: websockets==12.0
|
13
|
+
Dynamic: author
|
14
|
+
Dynamic: requires-dist
|
15
|
+
Dynamic: requires-python
|
16
|
+
Dynamic: summary
|
@@ -1,11 +1,8 @@
|
|
1
1
|
|
2
|
-
from common.utils import *
|
2
|
+
from WebsocketTest.common.utils import *
|
3
3
|
from urllib.parse import quote_plus
|
4
|
-
from common import WSBaseApi
|
5
|
-
from common.WSBaseApi import WSBaseApi
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
from WebsocketTest.common import WSBaseApi
|
5
|
+
from WebsocketTest.common.WSBaseApi import WSBaseApi
|
9
6
|
|
10
7
|
class ApiTestRunner(WSBaseApi):
|
11
8
|
def __init__(self, **kwargs):
|
@@ -145,7 +142,7 @@ class ApiTestRunner(WSBaseApi):
|
|
145
142
|
msg = json.loads(_msg)
|
146
143
|
code = safe_get(msg, ["header","code"])
|
147
144
|
if code != 0:
|
148
|
-
|
145
|
+
logger.error(f'请求错误: {code}, {msg}')
|
149
146
|
break
|
150
147
|
else:
|
151
148
|
answer = safe_get(msg, ["payload","results","text","intent","answer"])
|
@@ -159,7 +156,7 @@ class ApiTestRunner(WSBaseApi):
|
|
159
156
|
return
|
160
157
|
|
161
158
|
except Exception as e:
|
162
|
-
|
159
|
+
logger.error(f"error in handle_v1_chain :{e}")
|
163
160
|
break
|
164
161
|
|
165
162
|
|
@@ -6,8 +6,8 @@ import hashlib
|
|
6
6
|
import hmac,time
|
7
7
|
from urllib.parse import urlencode, urlparse
|
8
8
|
import uuid
|
9
|
-
from common.utils import *
|
10
|
-
from common.WSBaseApi import WSBaseApi
|
9
|
+
from WebsocketTest.common.utils import *
|
10
|
+
from WebsocketTest.common.WSBaseApi import WSBaseApi
|
11
11
|
from pathlib import Path
|
12
12
|
|
13
13
|
class ApiTestRunner(WSBaseApi):
|
@@ -81,10 +81,10 @@ class ApiTestRunner(WSBaseApi):
|
|
81
81
|
elif status == 2:
|
82
82
|
break
|
83
83
|
else:
|
84
|
-
|
84
|
+
logger.error(f"返回结果错误:{response_data['header']['message']}")
|
85
85
|
break
|
86
86
|
except Exception as e:
|
87
|
-
|
87
|
+
logger.error(f"Error in processing message: {e}")
|
88
88
|
break
|
89
89
|
# @exception_decorator
|
90
90
|
async def handle_v1_chain(self, ws):
|
@@ -113,7 +113,7 @@ class ApiTestRunner(WSBaseApi):
|
|
113
113
|
self.response = json.loads(data['content'])
|
114
114
|
return
|
115
115
|
except Exception as e:
|
116
|
-
|
116
|
+
logger.error(f"error in handle_v1_chain :{e}")
|
117
117
|
break
|
118
118
|
|
119
119
|
def build_params(self,chain=None):
|
@@ -0,0 +1,26 @@
|
|
1
|
+
import argparse
|
2
|
+
from pathlib import Path
|
3
|
+
from importlib import import_module
|
4
|
+
|
5
|
+
def main():
|
6
|
+
parser = argparse.ArgumentParser(description="WebSocket Test CLI")
|
7
|
+
subparsers = parser.add_subparsers(dest='command', required=True)
|
8
|
+
|
9
|
+
# 动态加载子命令
|
10
|
+
commands_dir = Path(__file__).parent / "commands"
|
11
|
+
for cmd_file in commands_dir.glob("*.py"):
|
12
|
+
if cmd_file.stem != "__init__":
|
13
|
+
cmd_name = cmd_file.stem
|
14
|
+
module = import_module(f"WebsocketTest.commands.{cmd_name}")
|
15
|
+
cmd_parser = subparsers.add_parser(cmd_name, help=module.__doc__)
|
16
|
+
if hasattr(module, 'configure_parser'):
|
17
|
+
module.configure_parser(cmd_parser)
|
18
|
+
# 关键:绑定执行函数
|
19
|
+
if hasattr(module, 'func'):
|
20
|
+
cmd_parser.set_defaults(func=module.func)
|
21
|
+
args = parser.parse_args()
|
22
|
+
args.func(args) # 调用子命令的执行函数
|
23
|
+
|
24
|
+
|
25
|
+
if __name__ == "__main__":
|
26
|
+
main()
|
@@ -0,0 +1,28 @@
|
|
1
|
+
import shutil
|
2
|
+
from pathlib import Path
|
3
|
+
|
4
|
+
|
5
|
+
def configure_parser(parser):
|
6
|
+
"""配置子命令参数"""
|
7
|
+
parser.add_argument("project_name", help="项目名称")
|
8
|
+
parser.add_argument("-t", "--template",
|
9
|
+
choices=["basic", "advanced"],
|
10
|
+
default="basic")
|
11
|
+
parser.add_argument("--force", action="store_true",
|
12
|
+
help="覆盖已存在目录")
|
13
|
+
|
14
|
+
def execute(args):
|
15
|
+
"""执行项目创建"""
|
16
|
+
template_dir = Path(__file__).parent.parent.parent / "templates" / args.template
|
17
|
+
target_dir = Path.cwd() / args.project_name
|
18
|
+
|
19
|
+
if target_dir.exists():
|
20
|
+
if not args.force:
|
21
|
+
raise FileExistsError(f"目录已存在: {target_dir}")
|
22
|
+
shutil.rmtree(target_dir)
|
23
|
+
|
24
|
+
shutil.copytree(template_dir, target_dir)
|
25
|
+
print(f"项目创建成功: {target_dir}")
|
26
|
+
|
27
|
+
# 注册到主CLI
|
28
|
+
func = execute
|
@@ -0,0 +1,20 @@
|
|
1
|
+
|
2
|
+
from WebsocketTest.run_tests import TestRunner
|
3
|
+
|
4
|
+
|
5
|
+
def configure_parser(parser):
|
6
|
+
"""配置子命令参数"""
|
7
|
+
parser.add_argument("--env", required=True, help="Test environment")
|
8
|
+
parser.add_argument("--app", required=True, help="Application ID")
|
9
|
+
parser.add_argument("--service", required=True, help="Service name")
|
10
|
+
parser.add_argument("--project", required=True, help="Project name")
|
11
|
+
parser.add_argument("--port", type=int, default=8883, help="Allure report port")
|
12
|
+
parser.add_argument("--report-dir", default="allure_report", help="Allure report directory")
|
13
|
+
parser.add_argument("--testcase", required=False, help='Specify the test case to run (e.g., "testcase/test_all.py::TestAqua::test_api[case_suite0]"')
|
14
|
+
|
15
|
+
def execute(args):
|
16
|
+
"""执行test"""
|
17
|
+
test_runner = TestRunner(args)
|
18
|
+
exit(test_runner.run())
|
19
|
+
# 注册到主CLI
|
20
|
+
func = execute
|
@@ -1,10 +1,10 @@
|
|
1
1
|
import websockets
|
2
2
|
from functools import cached_property
|
3
3
|
import asyncio
|
4
|
-
from common.utils import *
|
4
|
+
from WebsocketTest.common.utils import *
|
5
5
|
import allure
|
6
6
|
from pathlib import Path
|
7
|
-
from common.Assertion import Assert
|
7
|
+
from WebsocketTest.common.Assertion import Assert
|
8
8
|
import pytest
|
9
9
|
import traceback
|
10
10
|
class WSBaseApi:
|
@@ -39,7 +39,7 @@ class BaseApiTest:
|
|
39
39
|
def API_TEST_RUNNER_CLASS(self):
|
40
40
|
"""动态加载对应的测试运行器类(自动缓存)"""
|
41
41
|
class_prefix = self.__class__.__name__[4:] # TestGateway -> Gateway
|
42
|
-
module_path = f"caseScript.{class_prefix}"
|
42
|
+
module_path = f"WebsocketTest.caseScript.{class_prefix}"
|
43
43
|
|
44
44
|
try:
|
45
45
|
module = __import__(module_path, fromlist=['ApiTestRunner'])
|
@@ -49,9 +49,10 @@ class BaseApiTest:
|
|
49
49
|
f"无法加载 {module_path}.ApiTestRunner,"
|
50
50
|
"请检查模块路径和类命名是否符合规范"
|
51
51
|
) from e
|
52
|
+
|
52
53
|
|
53
54
|
@pytest.mark.parametrize('case_suite', gen_case_suite(CASE_PATH))
|
54
|
-
def
|
55
|
+
def test(self, case_suite, setup_env):
|
55
56
|
"""测试用例执行模板"""
|
56
57
|
try:
|
57
58
|
# 1. 合并参数
|
@@ -0,0 +1,14 @@
|
|
1
|
+
import logging
|
2
|
+
|
3
|
+
# 配置全局日志记录设置
|
4
|
+
# 配置日志记录
|
5
|
+
logging.basicConfig(
|
6
|
+
level=logging.INFO,
|
7
|
+
format='%(asctime)s.%(msecs)03d - %(levelname)s - %(name)s - %(message)s',
|
8
|
+
datefmt='%H:%M:%S',
|
9
|
+
handlers=[
|
10
|
+
logging.StreamHandler(), # 输出到控制台
|
11
|
+
]
|
12
|
+
)
|
13
|
+
# 创建一个记录器实例
|
14
|
+
logger = logging.getLogger()
|
@@ -6,9 +6,8 @@ import string
|
|
6
6
|
from datetime import datetime
|
7
7
|
import email.utils
|
8
8
|
from functools import wraps
|
9
|
-
from common.logger import
|
9
|
+
from WebsocketTest.common.logger import logger
|
10
10
|
from typing import Optional, Union, Literal
|
11
|
-
import numpy as np
|
12
11
|
def get_rfc1123_time():
|
13
12
|
# 获取当前UTC时间
|
14
13
|
now = datetime.utcnow()
|
@@ -208,7 +207,7 @@ def exception_decorator(func):
|
|
208
207
|
function_name = func.__name__
|
209
208
|
file_name = os.path.basename(func.__code__.co_filename) # 提取文件名
|
210
209
|
# 打印异常和函数名
|
211
|
-
|
210
|
+
logger.error( f"异常发生在文件 [{file_name}] 的函数 [{function_name}] 中: {str(e)}",
|
212
211
|
exc_info=True # 自动追加堆栈信息
|
213
212
|
)
|
214
213
|
# 可选择再次抛出异常或进行其他处理
|
@@ -1,13 +1,12 @@
|
|
1
|
-
import subprocess
|
1
|
+
import subprocess
|
2
2
|
import argparse
|
3
3
|
import shutil
|
4
|
-
from common.logger import *
|
5
4
|
import time
|
6
5
|
import webbrowser
|
7
6
|
from urllib.request import urlopen
|
8
7
|
from urllib.error import URLError
|
9
|
-
|
10
|
-
logger
|
8
|
+
from pathlib import Path
|
9
|
+
from WebsocketTest.common.logger import logger
|
11
10
|
|
12
11
|
class AllureManager:
|
13
12
|
def __init__(self, port: int = 8883):
|
@@ -28,7 +27,7 @@ class AllureManager:
|
|
28
27
|
"""启动Allure服务"""
|
29
28
|
try:
|
30
29
|
cmd = [self.allure_path, "open", report_dir, "-p", str(self.port)]
|
31
|
-
logger.info(f"start_server Executing: {' '.join(cmd)}")
|
30
|
+
# logger.info(f"start_server Executing: {' '.join(cmd)}")
|
32
31
|
subprocess.Popen(
|
33
32
|
cmd,
|
34
33
|
stdout=subprocess.DEVNULL,
|
@@ -69,21 +68,26 @@ class TestRunner:
|
|
69
68
|
"""直接存储args对象"""
|
70
69
|
self.args = args
|
71
70
|
self.allure_manager = AllureManager(self.args.port)
|
72
|
-
|
71
|
+
self.allure_results = str(Path.cwd().joinpath("allure_results"))
|
72
|
+
|
73
73
|
def run_pytest_tests(self) -> bool:
|
74
|
-
"""执行pytest测试"""
|
75
|
-
|
74
|
+
"""执行pytest测试"""
|
75
|
+
# 构建基础命令列表
|
76
76
|
cmd = [
|
77
77
|
"pytest",
|
78
|
-
"-m",
|
78
|
+
"-m", self.args.service.split('_')[0],
|
79
79
|
"--env", self.args.env,
|
80
80
|
"--app", self.args.app,
|
81
81
|
"--service", self.args.service,
|
82
82
|
"--project", self.args.project,
|
83
|
-
"--alluredir",
|
83
|
+
"--alluredir", self.allure_results
|
84
84
|
]
|
85
|
+
# 添加可选测试路径(如果存在)
|
86
|
+
if hasattr(self.args, 'testcase') and self.args.testcase:
|
87
|
+
cmd.insert(1, self.args.testcase)
|
88
|
+
print(f"run_pytest_tests Executing: {' '.join(cmd)}")
|
85
89
|
try:
|
86
|
-
logger.info(f"run_pytest_tests Executing: {' '.join(cmd)}")
|
90
|
+
# logger.info(f"run_pytest_tests Executing: {' '.join(cmd)}")
|
87
91
|
subprocess.run(cmd, check=True, timeout=3600)
|
88
92
|
except subprocess.CalledProcessError as e:
|
89
93
|
logger.error(f"Tests failed with exit code {e.returncode}")
|
@@ -93,13 +97,13 @@ class TestRunner:
|
|
93
97
|
def generate_allure_report(self) -> bool:
|
94
98
|
"""生成Allure报告"""
|
95
99
|
try:
|
96
|
-
cmd = [self.allure_manager.allure_path, "generate",
|
100
|
+
cmd = [self.allure_manager.allure_path, "generate", self.allure_results, "-o", self.args.report_dir, "--clean"]
|
97
101
|
subprocess.run(
|
98
102
|
cmd,
|
99
103
|
check=True,
|
100
104
|
timeout=300
|
101
105
|
)
|
102
|
-
logger.info(f"generate_allure_report Executing: {' '.join(cmd)}")
|
106
|
+
# logger.info(f"generate_allure_report Executing: {' '.join(cmd)}")
|
103
107
|
except subprocess.CalledProcessError as e:
|
104
108
|
logger.error(f"Report generation failed: {e}")
|
105
109
|
def _handle_allure_report(self) -> bool:
|
@@ -113,7 +117,6 @@ class TestRunner:
|
|
113
117
|
logger.info("Starting new Allure server...")
|
114
118
|
if self.allure_manager.start_server(self.args.report_dir):
|
115
119
|
webbrowser.open(f"http://localhost:{self.args.port}")
|
116
|
-
|
117
120
|
def run(self):
|
118
121
|
# 1. 运行测试
|
119
122
|
self.run_pytest_tests()
|
@@ -125,7 +128,8 @@ class TestRunner:
|
|
125
128
|
self._handle_allure_report()
|
126
129
|
logger.info(f"http://localhost:{self.args.port}")
|
127
130
|
return 0
|
128
|
-
|
131
|
+
|
132
|
+
if __name__ == "__main__":
|
129
133
|
try:
|
130
134
|
parser = argparse.ArgumentParser(description="Run tests with Allure reporting")
|
131
135
|
parser.add_argument("--env", required=True, help="Test environment")
|
@@ -134,6 +138,7 @@ def main():
|
|
134
138
|
parser.add_argument("--project", required=True, help="Project name")
|
135
139
|
parser.add_argument("--port", type=int, default=8883, help="Allure report port")
|
136
140
|
parser.add_argument("--report-dir", default="allure_report", help="Allure report directory")
|
141
|
+
parser.add_argument("--testcase", required=False, help='Specify the test case to run (e.g., "testcase/test_all.py::TestAqua::test_api[case_suite0]"')
|
137
142
|
args = parser.parse_args()
|
138
143
|
test_runner = TestRunner(args)
|
139
144
|
exit(test_runner.run())
|
@@ -142,6 +147,4 @@ def main():
|
|
142
147
|
exit(1)
|
143
148
|
except Exception as e:
|
144
149
|
logger.error(f"Unexpected error: {e}", exc_info=True)
|
145
|
-
exit(1)
|
146
|
-
if __name__ == "__main__":
|
147
|
-
main()
|
150
|
+
exit(1)
|
@@ -0,0 +1,16 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: WebsocketTest
|
3
|
+
Version: 1.0.5
|
4
|
+
Summary: websocket api autotest
|
5
|
+
Author: chencheng
|
6
|
+
Requires-Python: >=3.10
|
7
|
+
Requires-Dist: allure_python_commons==2.13.5
|
8
|
+
Requires-Dist: numpy==2.2.4
|
9
|
+
Requires-Dist: pandas==2.2.3
|
10
|
+
Requires-Dist: pytest==8.2.2
|
11
|
+
Requires-Dist: PyYAML==6.0.2
|
12
|
+
Requires-Dist: websockets==12.0
|
13
|
+
Dynamic: author
|
14
|
+
Dynamic: requires-dist
|
15
|
+
Dynamic: requires-python
|
16
|
+
Dynamic: summary
|
@@ -14,12 +14,12 @@ WebsocketTest.egg-info/top_level.txt
|
|
14
14
|
WebsocketTest/caseScript/Aqua.py
|
15
15
|
WebsocketTest/caseScript/Gateway.py
|
16
16
|
WebsocketTest/caseScript/__init__.py
|
17
|
+
WebsocketTest/commands/__init__.py
|
18
|
+
WebsocketTest/commands/startproject.py
|
19
|
+
WebsocketTest/commands/test.py
|
17
20
|
WebsocketTest/common/Assertion.py
|
18
21
|
WebsocketTest/common/WSBaseApi.py
|
19
|
-
WebsocketTest/common/WebSocketApi.py
|
20
22
|
WebsocketTest/common/__init__.py
|
21
23
|
WebsocketTest/common/assertUtils.py
|
22
24
|
WebsocketTest/common/logger.py
|
23
|
-
WebsocketTest/common/utils.py
|
24
|
-
WebsocketTest/testcase/__init__.py
|
25
|
-
WebsocketTest/testcase/test_all.py
|
25
|
+
WebsocketTest/common/utils.py
|
@@ -0,0 +1,43 @@
|
|
1
|
+
from setuptools import find_packages, setup
|
2
|
+
from setuptools.command.sdist import sdist
|
3
|
+
from setuptools.command.bdist_wheel import bdist_wheel
|
4
|
+
|
5
|
+
class CustomSdist(sdist):
|
6
|
+
def initialize_options(self):
|
7
|
+
super().initialize_options()
|
8
|
+
self.dist_dir = "setup_temp/dist" # 自定义sdist路径
|
9
|
+
|
10
|
+
class CustomBdistWheel(bdist_wheel):
|
11
|
+
def initialize_options(self):
|
12
|
+
super().initialize_options()
|
13
|
+
self.dist_dir = "setup_temp/dist" # 自定义wheel路径
|
14
|
+
|
15
|
+
setup(
|
16
|
+
cmdclass={
|
17
|
+
'sdist': CustomSdist,
|
18
|
+
'bdist_wheel': CustomBdistWheel
|
19
|
+
},
|
20
|
+
name="WebsocketTest",
|
21
|
+
version="1.0.5",
|
22
|
+
author='chencheng',
|
23
|
+
python_requires=">=3.10",
|
24
|
+
packages=find_packages(exclude=["WebsocketTest.allure_report", "WebsocketTest.logs", "WebsocketTest.allure_results", "WebsocketTest.config", "WebsocketTest.data","WebsocketTest.testcase"]),
|
25
|
+
description="websocket api autotest",
|
26
|
+
install_requires = [
|
27
|
+
"allure_python_commons==2.13.5",
|
28
|
+
"numpy==2.2.4",
|
29
|
+
"pandas==2.2.3",
|
30
|
+
"pytest==8.2.2",
|
31
|
+
"PyYAML==6.0.2",
|
32
|
+
"websockets==12.0"
|
33
|
+
],
|
34
|
+
entry_points={
|
35
|
+
'console_scripts': [
|
36
|
+
"ws=WebsocketTest.cli:main"
|
37
|
+
]
|
38
|
+
}
|
39
|
+
)
|
40
|
+
# import shutil
|
41
|
+
|
42
|
+
# # 清理 .egg-info 文件夹
|
43
|
+
# shutil.rmtree('WebsocketTest.egg-info', ignore_errors=True)
|
WebsocketTest-1.0.3/PKG-INFO
DELETED
@@ -1,56 +0,0 @@
|
|
1
|
-
import argparse
|
2
|
-
import enum
|
3
|
-
import sys
|
4
|
-
import pytest
|
5
|
-
|
6
|
-
def main_run(pytest_args: list) -> enum.IntEnum:
|
7
|
-
"""Run pytest with given arguments
|
8
|
-
|
9
|
-
Args:
|
10
|
-
pytest_args: List of arguments to pass to pytest
|
11
|
-
|
12
|
-
Returns:
|
13
|
-
pytest.ExitCode enum value
|
14
|
-
"""
|
15
|
-
print("Running pytest with args:", pytest_args)
|
16
|
-
return pytest.main(pytest_args)
|
17
|
-
|
18
|
-
def main():
|
19
|
-
"""API test: parse command line options and run commands."""
|
20
|
-
# 主解析器
|
21
|
-
parser = argparse.ArgumentParser(description="Run tests with Allure reporting")
|
22
|
-
|
23
|
-
# 添加必选参数
|
24
|
-
parser.add_argument("--env", required=True, help="Test environment")
|
25
|
-
parser.add_argument("--app", required=True, help="Application ID")
|
26
|
-
parser.add_argument("--service", required=True, help="Service name")
|
27
|
-
parser.add_argument("--project", required=True, help="Project name")
|
28
|
-
|
29
|
-
# 解析参数,分离已知参数和要传递给pytest的参数
|
30
|
-
args, pytest_args = parser.parse_known_args()
|
31
|
-
|
32
|
-
# 打印调试信息
|
33
|
-
print("Tool arguments:")
|
34
|
-
print(vars(args))
|
35
|
-
print("Pytest arguments:", pytest_args)
|
36
|
-
|
37
|
-
# 将工具参数转换为pytest可用的格式
|
38
|
-
pytest_args.extend([
|
39
|
-
f"--env={args.env}",
|
40
|
-
f"--app={args.app}",
|
41
|
-
f"--service={args.service}",
|
42
|
-
f"--project={args.project}"
|
43
|
-
])
|
44
|
-
|
45
|
-
# 运行测试
|
46
|
-
return_code = main_run(pytest_args)
|
47
|
-
|
48
|
-
# 返回退出码
|
49
|
-
sys.exit(return_code)
|
50
|
-
def main_run_alias():
|
51
|
-
""" command alias
|
52
|
-
prun = pastor run
|
53
|
-
"""
|
54
|
-
main()
|
55
|
-
if __name__ == "__main__":
|
56
|
-
main()
|
@@ -1,73 +0,0 @@
|
|
1
|
-
import _thread as thread
|
2
|
-
import logging
|
3
|
-
import websocket # 使用websocket_client
|
4
|
-
from common.utils import *
|
5
|
-
|
6
|
-
class WebSocketApi:
|
7
|
-
def __init__(self, url, request):
|
8
|
-
self.url = url
|
9
|
-
self.request = request
|
10
|
-
self.answer_text = ""
|
11
|
-
self.errcode = ""
|
12
|
-
self.response = {}
|
13
|
-
self.ws = None
|
14
|
-
|
15
|
-
def on_error(self, ws, error):
|
16
|
-
"""处理WebSocket错误"""
|
17
|
-
logging.error(f"### error: {error}")
|
18
|
-
self.errcode = str(error)
|
19
|
-
self.ws.close()
|
20
|
-
|
21
|
-
def on_close(self, ws, close_status_code, close_msg):
|
22
|
-
"""处理WebSocket关闭"""
|
23
|
-
logging.info(f"### ws closed with status {close_status_code} and message {close_msg}")
|
24
|
-
|
25
|
-
def on_open(self, ws):
|
26
|
-
"""处理WebSocket连接建立"""
|
27
|
-
thread.start_new_thread(self.run, (ws,))
|
28
|
-
|
29
|
-
def run(self, ws, *args):
|
30
|
-
"""发送请求"""
|
31
|
-
ws.send(self.request)
|
32
|
-
|
33
|
-
def on_message(self, ws, message: str):
|
34
|
-
"""处理WebSocket消息"""
|
35
|
-
try:
|
36
|
-
msg = json.loads(message)
|
37
|
-
code = safe_get(msg, ["header","code"])
|
38
|
-
if code != 0:
|
39
|
-
logging.error(f'请求错误: {code}, {msg}')
|
40
|
-
err_msg = safe_get(msg, ["header","message"])
|
41
|
-
self.errcode = f"{code}, error msg: {err_msg}"
|
42
|
-
self.ws.close()
|
43
|
-
else:
|
44
|
-
answer = safe_get(msg, ["payload","results","text","intent","answer"])
|
45
|
-
answerText = safe_get(answer, ["text"])
|
46
|
-
if answerText:
|
47
|
-
self.answer_text += answerText
|
48
|
-
if msg['header']['status']=="2" or msg['header']['status']=="3": # 返回结果接收完成
|
49
|
-
if self.answer_text:
|
50
|
-
answer["text"] = self.answer_text
|
51
|
-
self.response = msg
|
52
|
-
self.ws.close()
|
53
|
-
except json.JSONDecodeError as e:
|
54
|
-
logging.error(f"JSON解码错误: {e}")
|
55
|
-
self.errcode = f"JSON解码错误: {e}"
|
56
|
-
self.ws.close()
|
57
|
-
|
58
|
-
def start(self):
|
59
|
-
"""启动WebSocket客户端"""
|
60
|
-
websocket.enableTrace(False)
|
61
|
-
self.ws = websocket.WebSocketApp(self.url,
|
62
|
-
on_open=self.on_open,
|
63
|
-
on_error=self.on_error,
|
64
|
-
on_message=self.on_message,
|
65
|
-
on_close=self.on_close)
|
66
|
-
self.ws.run_forever()
|
67
|
-
|
68
|
-
|
69
|
-
def main(Spark_url, request: str):
|
70
|
-
"""主函数,启动WebSocket客户端并返回响应"""
|
71
|
-
client = WebSocketApi(Spark_url, request)
|
72
|
-
client.start()
|
73
|
-
return client.response
|
@@ -1,27 +0,0 @@
|
|
1
|
-
import os
|
2
|
-
import logging
|
3
|
-
from datetime import datetime
|
4
|
-
|
5
|
-
def configure_logging():
|
6
|
-
# 指定日志文件夹路径
|
7
|
-
log_dir = 'logs'
|
8
|
-
|
9
|
-
# 创建日志文件夹(如果它不存在)
|
10
|
-
os.makedirs(log_dir, exist_ok=True)
|
11
|
-
|
12
|
-
# 获取今天的日期,用于日志文件名
|
13
|
-
today_date = datetime.now().date()
|
14
|
-
|
15
|
-
# 配置日志记录
|
16
|
-
logging.basicConfig(
|
17
|
-
level=logging.INFO,
|
18
|
-
format='%(asctime)s.%(msecs)03d - %(levelname)s - %(name)s - %(message)s',
|
19
|
-
datefmt='%H:%M:%S',
|
20
|
-
handlers=[
|
21
|
-
logging.StreamHandler(), # 输出到控制台
|
22
|
-
logging.FileHandler(f'{log_dir}/{today_date}.log') # 输出到文件
|
23
|
-
]
|
24
|
-
)
|
25
|
-
|
26
|
-
# 调用函数以配置日志记录
|
27
|
-
configure_logging()
|
WebsocketTest-1.0.3/setup.py
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
from setuptools import find_packages, setup
|
2
|
-
|
3
|
-
|
4
|
-
setup(
|
5
|
-
name="WebsocketTest",
|
6
|
-
version="1.0.3",
|
7
|
-
author='chencheng',
|
8
|
-
python_requires=">=3.10",
|
9
|
-
packages=find_packages(exclude=["WebsocketTest.allure_report", "WebsocketTest.logs", "WebsocketTest.allure_results", "WebsocketTest.config", "WebsocketTest.data"]),
|
10
|
-
description="websocket api autotest",
|
11
|
-
# long_description=open('README.md','r',encoding='utf-8').read(),
|
12
|
-
long_description_content_type='text/markdown',
|
13
|
-
install_requires = [
|
14
|
-
"allure_python_commons==2.13.5",
|
15
|
-
"numpy==2.2.4",
|
16
|
-
"pandas==2.2.3",
|
17
|
-
"pytest==8.2.2",
|
18
|
-
"PyYAML==6.0.2",
|
19
|
-
"websockets==12.0"
|
20
|
-
],
|
21
|
-
entry_points={
|
22
|
-
'console_scripts': [
|
23
|
-
'wsrun=WebsocketTest.cli:main_run_alias'
|
24
|
-
]
|
25
|
-
}
|
26
|
-
)
|
File without changes
|
File without changes
|
File without changes
|
{WebsocketTest-1.0.3/WebsocketTest/common → websockettest-1.0.5/WebsocketTest/commands}/__init__.py
RENAMED
File without changes
|
{WebsocketTest-1.0.3/WebsocketTest/testcase → websockettest-1.0.5/WebsocketTest/common}/__init__.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|