cli-test-framework 0.2.0__tar.gz → 0.2.1__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.
- cli_test_framework-0.2.1/CHANGELOG.md +114 -0
- cli_test_framework-0.2.1/MANIFEST.in +6 -0
- cli_test_framework-0.2.1/PKG-INFO +445 -0
- cli_test_framework-0.2.1/docs/user_manual.md +364 -0
- cli_test_framework-0.2.1/setup.py +48 -0
- cli_test_framework-0.2.1/src/cli_test_framework.egg-info/PKG-INFO +445 -0
- {cli_test_framework-0.2.0 → cli_test_framework-0.2.1}/src/cli_test_framework.egg-info/SOURCES.txt +12 -1
- cli_test_framework-0.2.1/tests/__init__.py +3 -0
- cli_test_framework-0.2.1/tests/__pycache__/__init__.cpython-312.pyc +0 -0
- cli_test_framework-0.2.1/tests/__pycache__/test_parallel_runner.cpython-312-pytest-7.4.4.pyc +0 -0
- cli_test_framework-0.2.1/tests/fixtures/test_cases.json +57 -0
- cli_test_framework-0.2.1/tests/fixtures/test_cases.yaml +10 -0
- cli_test_framework-0.2.1/tests/fixtures/test_cases1.json +182 -0
- cli_test_framework-0.2.1/tests/performance_test.py +134 -0
- cli_test_framework-0.2.1/tests/test_report.txt +21 -0
- cli_test_framework-0.2.0/PKG-INFO +0 -21
- cli_test_framework-0.2.0/setup.py +0 -30
- cli_test_framework-0.2.0/src/cli_test_framework.egg-info/PKG-INFO +0 -21
- {cli_test_framework-0.2.0 → cli_test_framework-0.2.1}/README.md +0 -0
- {cli_test_framework-0.2.0 → cli_test_framework-0.2.1}/pyproject.toml +0 -0
- {cli_test_framework-0.2.0 → cli_test_framework-0.2.1}/setup.cfg +0 -0
- {cli_test_framework-0.2.0 → cli_test_framework-0.2.1}/src/cli_test_framework.egg-info/dependency_links.txt +0 -0
- {cli_test_framework-0.2.0 → cli_test_framework-0.2.1}/src/cli_test_framework.egg-info/entry_points.txt +0 -0
- {cli_test_framework-0.2.0 → cli_test_framework-0.2.1}/src/cli_test_framework.egg-info/requires.txt +0 -0
- {cli_test_framework-0.2.0 → cli_test_framework-0.2.1}/src/cli_test_framework.egg-info/top_level.txt +0 -0
- {cli_test_framework-0.2.0 → cli_test_framework-0.2.1}/src/core/__init__.py +0 -0
- {cli_test_framework-0.2.0 → cli_test_framework-0.2.1}/src/core/assertions.py +0 -0
- {cli_test_framework-0.2.0 → cli_test_framework-0.2.1}/src/core/base_runner.py +0 -0
- {cli_test_framework-0.2.0 → cli_test_framework-0.2.1}/src/core/parallel_runner.py +0 -0
- {cli_test_framework-0.2.0 → cli_test_framework-0.2.1}/src/core/process_worker.py +0 -0
- {cli_test_framework-0.2.0 → cli_test_framework-0.2.1}/src/core/test_case.py +0 -0
- {cli_test_framework-0.2.0 → cli_test_framework-0.2.1}/src/runners/__init__.py +0 -0
- {cli_test_framework-0.2.0 → cli_test_framework-0.2.1}/src/runners/json_runner.py +0 -0
- {cli_test_framework-0.2.0 → cli_test_framework-0.2.1}/src/runners/parallel_json_runner.py +0 -0
- {cli_test_framework-0.2.0 → cli_test_framework-0.2.1}/src/runners/yaml_runner.py +0 -0
- {cli_test_framework-0.2.0 → cli_test_framework-0.2.1}/src/utils/__init__.py +0 -0
- {cli_test_framework-0.2.0 → cli_test_framework-0.2.1}/src/utils/path_resolver.py +0 -0
- {cli_test_framework-0.2.0 → cli_test_framework-0.2.1}/src/utils/report_generator.py +0 -0
- {cli_test_framework-0.2.0 → cli_test_framework-0.2.1}/tests/test1.py +0 -0
- {cli_test_framework-0.2.0 → cli_test_framework-0.2.1}/tests/test_comprehensive_space.py +0 -0
- {cli_test_framework-0.2.0 → cli_test_framework-0.2.1}/tests/test_parallel_runner.py +0 -0
- {cli_test_framework-0.2.0 → cli_test_framework-0.2.1}/tests/test_parallel_space.py +0 -0
- {cli_test_framework-0.2.0 → cli_test_framework-0.2.1}/tests/test_runners.py +0 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# 变更日志
|
|
2
|
+
|
|
3
|
+
## [v2.0.0] - 2025-05-27
|
|
4
|
+
|
|
5
|
+
### 🚀 重大新功能
|
|
6
|
+
|
|
7
|
+
#### 并行测试执行
|
|
8
|
+
- **多线程并行执行**:支持 I/O 密集型测试的高效并行处理
|
|
9
|
+
- **多进程并行执行**:支持 CPU 密集型测试的完全隔离执行
|
|
10
|
+
- **可配置并发数**:灵活设置最大工作线程/进程数
|
|
11
|
+
- **性能提升**:典型场景下可获得 2-4 倍加速比
|
|
12
|
+
|
|
13
|
+
#### 智能命令解析
|
|
14
|
+
- **复杂命令支持**:智能处理 `"python ./script.py"` 等复杂命令格式
|
|
15
|
+
- **系统命令识别**:自动识别系统命令和相对路径可执行文件
|
|
16
|
+
- **路径解析增强**:更准确的路径转换和命令构建
|
|
17
|
+
|
|
18
|
+
### ✨ 功能增强
|
|
19
|
+
|
|
20
|
+
#### 线程安全设计
|
|
21
|
+
- **结果收集锁**:确保并发环境下测试结果的正确性
|
|
22
|
+
- **输出控制锁**:防止并发输出混乱
|
|
23
|
+
- **异常隔离**:单个测试失败不影响其他测试
|
|
24
|
+
|
|
25
|
+
#### 新增运行器
|
|
26
|
+
- **ParallelJSONRunner**:支持并行执行的 JSON 测试运行器
|
|
27
|
+
- **进程工作器**:独立的进程执行模块,解决序列化问题
|
|
28
|
+
|
|
29
|
+
### 🔧 问题修复
|
|
30
|
+
|
|
31
|
+
#### 命令解析修复
|
|
32
|
+
- **修复问题**:`'D:\Document\xcode\Compare-File-Tool\python' 不是内部或外部命令`
|
|
33
|
+
- **根本原因**:复杂命令字符串被整体当作命令名处理
|
|
34
|
+
- **解决方案**:智能分割命令字符串,分别处理命令和参数部分
|
|
35
|
+
|
|
36
|
+
#### 路径解析优化
|
|
37
|
+
- **系统命令白名单**:扩展系统命令识别列表
|
|
38
|
+
- **相对路径处理**:改进相对路径和绝对路径的判断逻辑
|
|
39
|
+
|
|
40
|
+
### 📚 文档更新
|
|
41
|
+
|
|
42
|
+
#### README 全面重写
|
|
43
|
+
- **英文版 README.md**:全新的结构和内容组织
|
|
44
|
+
- **中文版 README_cn.md**:同步更新,保持一致性
|
|
45
|
+
- **并行测试指南**:详细的 PARALLEL_TESTING_GUIDE.md
|
|
46
|
+
|
|
47
|
+
#### 新增示例
|
|
48
|
+
- **parallel_example.py**:性能比较演示
|
|
49
|
+
- **performance_test.py**:自动化性能测试
|
|
50
|
+
- **test_parallel_runner.py**:并行功能单元测试
|
|
51
|
+
|
|
52
|
+
### 🎯 性能基准
|
|
53
|
+
|
|
54
|
+
| 测试场景 | 顺序执行 | 并行执行(线程) | 并行执行(进程) | 加速比 |
|
|
55
|
+
|----------|----------|----------------|----------------|--------|
|
|
56
|
+
| 6个简单测试 | 0.12秒 | 0.03秒 | 0.16秒 | 3.84x |
|
|
57
|
+
| 10个I/O测试 | 5.2秒 | 1.4秒 | 2.1秒 | 3.7x |
|
|
58
|
+
| 20个CPU测试 | 12.8秒 | 8.9秒 | 6.2秒 | 2.1x |
|
|
59
|
+
|
|
60
|
+
### 🔄 向后兼容性
|
|
61
|
+
|
|
62
|
+
- **完全兼容**:现有的 JSONRunner 代码无需修改
|
|
63
|
+
- **渐进式升级**:可以逐步迁移到并行执行
|
|
64
|
+
- **配置兼容**:现有测试用例配置文件无需更改
|
|
65
|
+
|
|
66
|
+
### 📦 依赖更新
|
|
67
|
+
|
|
68
|
+
```txt
|
|
69
|
+
pytest
|
|
70
|
+
PyYAML # 修正了之前的 pyyaml 拼写错误
|
|
71
|
+
concurrent.futures # 标准库,无需额外安装
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### 🚀 使用示例
|
|
75
|
+
|
|
76
|
+
#### 基本并行执行
|
|
77
|
+
```python
|
|
78
|
+
from src.runners.parallel_json_runner import ParallelJSONRunner
|
|
79
|
+
|
|
80
|
+
runner = ParallelJSONRunner(
|
|
81
|
+
config_file="test_cases.json",
|
|
82
|
+
max_workers=4,
|
|
83
|
+
execution_mode="thread"
|
|
84
|
+
)
|
|
85
|
+
success = runner.run_tests()
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
#### 性能比较
|
|
89
|
+
```bash
|
|
90
|
+
# 运行性能比较示例
|
|
91
|
+
python parallel_example.py
|
|
92
|
+
|
|
93
|
+
# 输出示例:
|
|
94
|
+
# 顺序执行时间: 0.12 秒
|
|
95
|
+
# 并行执行时间(线程): 0.03 秒 (加速比: 3.84x)
|
|
96
|
+
# 并行执行时间(进程): 0.16 秒 (加速比: 0.73x)
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### 🔮 未来计划
|
|
100
|
+
|
|
101
|
+
- **分布式执行**:支持跨机器的测试执行
|
|
102
|
+
- **Web UI**:提供图形化的测试管理界面
|
|
103
|
+
- **更多格式支持**:XML、TOML 等配置格式
|
|
104
|
+
- **性能监控**:详细的执行时间和资源使用统计
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## [v1.0.0] - 2025-03-05
|
|
109
|
+
|
|
110
|
+
### 初始版本
|
|
111
|
+
- 基础的 JSON/YAML 测试运行器
|
|
112
|
+
- 路径解析功能
|
|
113
|
+
- 断言机制
|
|
114
|
+
- 报告生成
|
|
@@ -0,0 +1,445 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: cli-test-framework
|
|
3
|
+
Version: 0.2.1
|
|
4
|
+
Summary: A small command line testing framework in Python with file comparison capabilities.
|
|
5
|
+
Home-page: https://github.com/yourusername/cli-test-framework
|
|
6
|
+
Author: Xiaotong Wang
|
|
7
|
+
Author-email: xiaotongwang98@gmail.com
|
|
8
|
+
Project-URL: Documentation, https://github.com/yourusername/cli-test-framework/docs/user_manual.md
|
|
9
|
+
Project-URL: Source, https://github.com/yourusername/cli-test-framework
|
|
10
|
+
Project-URL: Tracker, https://github.com/yourusername/cli-test-framework/issues
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Development Status :: 4 - Beta
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: Topic :: Software Development :: Testing
|
|
17
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
18
|
+
Requires-Python: >=3.6
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
Requires-Dist: dukpy==0.5.0
|
|
21
|
+
Requires-Dist: h5py>=3.8.0
|
|
22
|
+
Requires-Dist: numpy>=2.0.1
|
|
23
|
+
Requires-Dist: setuptools>=75.8.0
|
|
24
|
+
Requires-Dist: wheel>=0.45.1
|
|
25
|
+
Dynamic: author
|
|
26
|
+
Dynamic: author-email
|
|
27
|
+
Dynamic: classifier
|
|
28
|
+
Dynamic: description
|
|
29
|
+
Dynamic: description-content-type
|
|
30
|
+
Dynamic: home-page
|
|
31
|
+
Dynamic: project-url
|
|
32
|
+
Dynamic: requires-dist
|
|
33
|
+
Dynamic: requires-python
|
|
34
|
+
Dynamic: summary
|
|
35
|
+
|
|
36
|
+
# CLI Testing Framework
|
|
37
|
+
|
|
38
|
+
## 1. Overview
|
|
39
|
+
|
|
40
|
+
This is a lightweight and extensible automated testing framework that supports defining test cases via JSON/YAML formats, providing complete test execution, result verification, and report generation capabilities. The framework is designed to provide standardized test management for command-line tools and scripts, with enterprise-grade parallel execution support and advanced file comparison features.
|
|
41
|
+
|
|
42
|
+
## 2. Features
|
|
43
|
+
|
|
44
|
+
- **🚀 Parallel Test Execution**: Support for multi-threading and multi-processing parallel testing with significant performance improvements
|
|
45
|
+
- **🏗️ Modular Architecture**: Decoupled design of core components (runner/assertion/report)
|
|
46
|
+
- **📄 Multi-Format Support**: Native support for JSON/YAML test case formats
|
|
47
|
+
- **🧠 Intelligent Command Parsing**: Smart handling of complex commands like `"python ./script.py"`
|
|
48
|
+
- **📁 Smart Path Resolution**: Automatic handling of relative and absolute path conversions
|
|
49
|
+
- **✅ Rich Assertion Mechanism**: Return code validation, output content matching, regex verification
|
|
50
|
+
- **🔌 Extensible Interfaces**: Quickly implement new test format support by inheriting BaseRunner
|
|
51
|
+
- **🔒 Isolated Execution Environment**: Independent sub-process execution ensures test isolation
|
|
52
|
+
- **📊 Comprehensive Reports**: Detailed pass rate statistics and failure diagnostics
|
|
53
|
+
- **🔧 Thread-Safe Design**: Robust concurrent execution with proper synchronization
|
|
54
|
+
- **📝 Advanced File Comparison**: Support for comparing various file types (text, binary, JSON, HDF5) with detailed diff output
|
|
55
|
+
|
|
56
|
+
## 3. Quick Start
|
|
57
|
+
|
|
58
|
+
### Environment Requirements
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
pip install cli-test-framework
|
|
62
|
+
Python >= 3.6
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Sequential Execution
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
from src.runners.json_runner import JSONRunner
|
|
69
|
+
|
|
70
|
+
runner = JSONRunner(
|
|
71
|
+
config_file="path/to/test_cases.json",
|
|
72
|
+
workspace="/project/root"
|
|
73
|
+
)
|
|
74
|
+
success = runner.run_tests()
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Parallel Execution
|
|
78
|
+
|
|
79
|
+
```python
|
|
80
|
+
from src.runners.parallel_json_runner import ParallelJSONRunner
|
|
81
|
+
|
|
82
|
+
# Multi-threaded execution (recommended for I/O-intensive tests)
|
|
83
|
+
runner = ParallelJSONRunner(
|
|
84
|
+
config_file="path/to/test_cases.json",
|
|
85
|
+
workspace="/project/root",
|
|
86
|
+
max_workers=4, # Maximum concurrent workers
|
|
87
|
+
execution_mode="thread" # "thread" or "process"
|
|
88
|
+
)
|
|
89
|
+
success = runner.run_tests()
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### File Comparison
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
# Compare two text files
|
|
96
|
+
compare-files file1.txt file2.txt
|
|
97
|
+
|
|
98
|
+
# Compare JSON files with key-based comparison
|
|
99
|
+
compare-files data1.json data2.json --json-compare-mode key-based --json-key-field id
|
|
100
|
+
|
|
101
|
+
# Compare HDF5 files with specific options
|
|
102
|
+
compare-files data1.h5 data2.h5 --h5-table table1,table2 --h5-rtol 1e-6
|
|
103
|
+
|
|
104
|
+
# Compare binary files with similarity check
|
|
105
|
+
compare-files binary1.bin binary2.bin --similarity
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## 4. Test Case Format
|
|
109
|
+
|
|
110
|
+
### JSON Format
|
|
111
|
+
|
|
112
|
+
```json
|
|
113
|
+
{
|
|
114
|
+
"test_cases": [
|
|
115
|
+
{
|
|
116
|
+
"name": "File Comparison Test",
|
|
117
|
+
"command": "compare-files",
|
|
118
|
+
"args": ["file1.txt", "file2.txt", "--verbose"],
|
|
119
|
+
"expected": {
|
|
120
|
+
"return_code": 0,
|
|
121
|
+
"output_contains": ["Files are identical"],
|
|
122
|
+
"output_matches": [".*comparison completed.*"]
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
]
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### YAML Format
|
|
130
|
+
|
|
131
|
+
```yaml
|
|
132
|
+
test_cases:
|
|
133
|
+
- name: Directory Scan Test
|
|
134
|
+
command: ls
|
|
135
|
+
args:
|
|
136
|
+
- -l
|
|
137
|
+
- docs/
|
|
138
|
+
expected:
|
|
139
|
+
return_code: 0
|
|
140
|
+
output_matches: ".*\\.md$"
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## 5. File Comparison Features
|
|
144
|
+
|
|
145
|
+
### Supported File Types
|
|
146
|
+
|
|
147
|
+
- **Text Files**: Plain text, source code, markdown, etc.
|
|
148
|
+
- **JSON Files**: With exact or key-based comparison
|
|
149
|
+
- **HDF5 Files**: Structure and content comparison with numerical tolerance
|
|
150
|
+
- **Binary Files**: With optional similarity index calculation
|
|
151
|
+
|
|
152
|
+
### Comparison Options
|
|
153
|
+
|
|
154
|
+
#### Text Comparison
|
|
155
|
+
```bash
|
|
156
|
+
compare-files file1.txt file2.txt \
|
|
157
|
+
--start-line 10 \
|
|
158
|
+
--end-line 20 \
|
|
159
|
+
--encoding utf-8
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
#### JSON Comparison
|
|
163
|
+
```bash
|
|
164
|
+
compare-files data1.json data2.json \
|
|
165
|
+
--json-compare-mode key-based \
|
|
166
|
+
--json-key-field id,name
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
#### HDF5 Comparison
|
|
170
|
+
```bash
|
|
171
|
+
compare-files data1.h5 data2.h5 \
|
|
172
|
+
--h5-table table1,table2 \
|
|
173
|
+
--h5-structure-only \
|
|
174
|
+
--h5-rtol 1e-5 \
|
|
175
|
+
--h5-atol 1e-8
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
#### Binary Comparison
|
|
179
|
+
```bash
|
|
180
|
+
compare-files binary1.bin binary2.bin \
|
|
181
|
+
--similarity \
|
|
182
|
+
--chunk-size 16384
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Output Formats
|
|
186
|
+
|
|
187
|
+
- **Text**: Human-readable diff output
|
|
188
|
+
- **JSON**: Structured comparison results
|
|
189
|
+
- **HTML**: Visual diff with syntax highlighting
|
|
190
|
+
|
|
191
|
+
## 6. System Architecture
|
|
192
|
+
|
|
193
|
+
### Enhanced Architecture Flow
|
|
194
|
+
|
|
195
|
+
```mermaid
|
|
196
|
+
graph TD
|
|
197
|
+
A[Test Cases] --> B{Execution Mode}
|
|
198
|
+
B -->|Sequential| C[JSONRunner/YAMLRunner]
|
|
199
|
+
B -->|Parallel| D[ParallelRunner]
|
|
200
|
+
D --> E[ThreadPoolExecutor/ProcessPoolExecutor]
|
|
201
|
+
C --> F[Command Parser]
|
|
202
|
+
E --> F
|
|
203
|
+
F --> G[Path Resolver]
|
|
204
|
+
G --> H[Sub-process Execution]
|
|
205
|
+
H --> I[Assertion Engine]
|
|
206
|
+
I --> J[Thread-Safe Result Collection]
|
|
207
|
+
J --> K[Report Generator]
|
|
208
|
+
L[File Comparator] --> M[Text Comparator]
|
|
209
|
+
L --> N[JSON Comparator]
|
|
210
|
+
L --> O[HDF5 Comparator]
|
|
211
|
+
L --> P[Binary Comparator]
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Core Components
|
|
215
|
+
|
|
216
|
+
#### 1. Intelligent Command Parser
|
|
217
|
+
```python
|
|
218
|
+
# Handles complex commands like "python ./script.py"
|
|
219
|
+
command_parts = case["command"].split()
|
|
220
|
+
if len(command_parts) > 1:
|
|
221
|
+
actual_command = resolve_command(command_parts[0]) # "python"
|
|
222
|
+
script_parts = resolve_paths(command_parts[1:]) # "./script.py" -> full path
|
|
223
|
+
final_command = f"{actual_command} {' '.join(script_parts)}"
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
#### 2. Enhanced Path Resolver
|
|
227
|
+
```python
|
|
228
|
+
def resolve_command(self, command: str) -> str:
|
|
229
|
+
system_commands = {
|
|
230
|
+
'echo', 'ping', 'python', 'node', 'java', 'docker', ...
|
|
231
|
+
}
|
|
232
|
+
if command in system_commands or Path(command).is_absolute():
|
|
233
|
+
return command
|
|
234
|
+
return str(self.workspace / command)
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
#### 3. Parallel Runner Base Class
|
|
238
|
+
```python
|
|
239
|
+
class ParallelRunner(BaseRunner):
|
|
240
|
+
def __init__(self, max_workers=None, execution_mode="thread"):
|
|
241
|
+
self.max_workers = max_workers or os.cpu_count()
|
|
242
|
+
self.execution_mode = execution_mode
|
|
243
|
+
self._results_lock = threading.Lock()
|
|
244
|
+
self._print_lock = threading.Lock()
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## 7. Advanced Usage
|
|
248
|
+
|
|
249
|
+
### Performance Testing
|
|
250
|
+
|
|
251
|
+
```python
|
|
252
|
+
# Quick performance test
|
|
253
|
+
python performance_test.py
|
|
254
|
+
|
|
255
|
+
# Unit tests for parallel functionality
|
|
256
|
+
python -m pytest tests/test_parallel_runner.py -v
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### Error Handling and Fallback
|
|
260
|
+
|
|
261
|
+
```python
|
|
262
|
+
try:
|
|
263
|
+
runner = ParallelJSONRunner(config_file="test_cases.json")
|
|
264
|
+
success = runner.run_tests()
|
|
265
|
+
|
|
266
|
+
if not success:
|
|
267
|
+
# Check failed tests
|
|
268
|
+
for detail in runner.results["details"]:
|
|
269
|
+
if detail["status"] == "failed":
|
|
270
|
+
print(f"Failed test: {detail['name']}")
|
|
271
|
+
print(f"Error: {detail['message']}")
|
|
272
|
+
|
|
273
|
+
except Exception as e:
|
|
274
|
+
print(f"Execution error: {e}")
|
|
275
|
+
# Fallback to sequential execution
|
|
276
|
+
runner.run_tests_sequential()
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### Best Practices
|
|
280
|
+
|
|
281
|
+
1. **Choose Appropriate Concurrency**:
|
|
282
|
+
```python
|
|
283
|
+
import os
|
|
284
|
+
|
|
285
|
+
# For CPU-intensive tasks
|
|
286
|
+
max_workers = os.cpu_count()
|
|
287
|
+
|
|
288
|
+
# For I/O-intensive tasks
|
|
289
|
+
max_workers = os.cpu_count() * 2
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
2. **Test Case Design**:
|
|
293
|
+
- ✅ Ensure test independence (no dependencies between tests)
|
|
294
|
+
- ✅ Avoid shared resource conflicts (different files/ports)
|
|
295
|
+
- ✅ Use relative paths (framework handles resolution automatically)
|
|
296
|
+
|
|
297
|
+
3. **Debugging**:
|
|
298
|
+
```python
|
|
299
|
+
# Enable verbose output for debugging
|
|
300
|
+
runner = ParallelJSONRunner(
|
|
301
|
+
config_file="test_cases.json",
|
|
302
|
+
max_workers=1, # Set to 1 for easier debugging
|
|
303
|
+
execution_mode="thread"
|
|
304
|
+
)
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
## 8. Example Demonstrations
|
|
308
|
+
|
|
309
|
+
### Input Example
|
|
310
|
+
|
|
311
|
+
```json
|
|
312
|
+
{
|
|
313
|
+
"test_cases": [
|
|
314
|
+
{
|
|
315
|
+
"name": "Python Version Check",
|
|
316
|
+
"command": "python --version",
|
|
317
|
+
"args": [],
|
|
318
|
+
"expected": {
|
|
319
|
+
"output_matches": "Python 3\\.[89]\\.",
|
|
320
|
+
"return_code": 0
|
|
321
|
+
}
|
|
322
|
+
},
|
|
323
|
+
{
|
|
324
|
+
"name": "File Processing Test",
|
|
325
|
+
"command": "python ./process_file.py",
|
|
326
|
+
"args": ["input.txt", "--output", "result.txt"],
|
|
327
|
+
"expected": {
|
|
328
|
+
"return_code": 0,
|
|
329
|
+
"output_contains": ["Processing completed"]
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
]
|
|
333
|
+
}
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
### Output Report
|
|
337
|
+
|
|
338
|
+
```
|
|
339
|
+
Test Results Summary:
|
|
340
|
+
Total Tests: 15
|
|
341
|
+
Passed: 15
|
|
342
|
+
Failed: 0
|
|
343
|
+
|
|
344
|
+
Performance Statistics:
|
|
345
|
+
Sequential execution time: 12.45 seconds
|
|
346
|
+
Parallel execution time: 3.21 seconds
|
|
347
|
+
Speedup ratio: 3.88x
|
|
348
|
+
|
|
349
|
+
Detailed Results:
|
|
350
|
+
✓ Python Version Check
|
|
351
|
+
✓ File Processing Test
|
|
352
|
+
✓ JSON Comparison Test
|
|
353
|
+
...
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
## 9. Troubleshooting
|
|
357
|
+
|
|
358
|
+
### Common Issues
|
|
359
|
+
|
|
360
|
+
1. **Process Mode Serialization Error**
|
|
361
|
+
- **Cause**: Objects contain non-serializable attributes (like locks)
|
|
362
|
+
- **Solution**: Use independent process worker functions
|
|
363
|
+
|
|
364
|
+
2. **Path Resolution Error**
|
|
365
|
+
- **Cause**: System commands treated as relative paths
|
|
366
|
+
- **Solution**: Update `PathResolver` system command list
|
|
367
|
+
|
|
368
|
+
3. **Performance Not Improved**
|
|
369
|
+
- **Cause**: Test cases too short, parallel overhead exceeds benefits
|
|
370
|
+
- **Solution**: Increase test case count or use more complex tests
|
|
371
|
+
|
|
372
|
+
4. **Command Not Found Error**
|
|
373
|
+
- **Cause**: Complex commands like `"python ./script.py"` not parsed correctly
|
|
374
|
+
- **Solution**: Framework now automatically handles this (fixed in latest version)
|
|
375
|
+
|
|
376
|
+
### Debug Tips
|
|
377
|
+
|
|
378
|
+
```python
|
|
379
|
+
# Enable detailed logging
|
|
380
|
+
import logging
|
|
381
|
+
logging.basicConfig(level=logging.DEBUG)
|
|
382
|
+
|
|
383
|
+
# Check detailed results
|
|
384
|
+
import json
|
|
385
|
+
print(json.dumps(runner.results, indent=2, ensure_ascii=False))
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
## 10. Extension and Customization
|
|
389
|
+
|
|
390
|
+
### Adding New Runners
|
|
391
|
+
|
|
392
|
+
```python
|
|
393
|
+
class XMLRunner(BaseRunner):
|
|
394
|
+
def load_test_cases(self):
|
|
395
|
+
import xml.etree.ElementTree as ET
|
|
396
|
+
# Parse XML structure and convert to TestCase objects
|
|
397
|
+
|
|
398
|
+
class CustomParallelRunner(ParallelRunner):
|
|
399
|
+
def custom_preprocessing(self):
|
|
400
|
+
# Add custom logic before test execution
|
|
401
|
+
pass
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
### Custom Assertions
|
|
405
|
+
|
|
406
|
+
```python
|
|
407
|
+
class CustomAssertions(Assertions):
|
|
408
|
+
@staticmethod
|
|
409
|
+
def performance_threshold(execution_time, max_time):
|
|
410
|
+
if execution_time > max_time:
|
|
411
|
+
raise AssertionError(f"Execution too slow: {execution_time}s > {max_time}s")
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
## 11. Version Compatibility
|
|
415
|
+
|
|
416
|
+
- **Python Version**: 3.6+
|
|
417
|
+
- **Dependencies**: Standard library only (no external dependencies for core functionality)
|
|
418
|
+
- **Backward Compatibility**: Fully compatible with existing `JSONRunner` code
|
|
419
|
+
- **Platform Support**: Windows, macOS, Linux
|
|
420
|
+
|
|
421
|
+
## 12. Performance Benchmarks
|
|
422
|
+
|
|
423
|
+
| Test Scenario | Sequential | Parallel (Thread) | Parallel (Process) | Speedup |
|
|
424
|
+
|---------------|------------|-------------------|-------------------|---------|
|
|
425
|
+
| 10 I/O tests | 5.2s | 1.4s | 2.1s | 3.7x |
|
|
426
|
+
| 20 CPU tests | 12.8s | 8.9s | 6.2s | 2.1x |
|
|
427
|
+
| Mixed tests | 8.5s | 2.3s | 3.1s | 3.7x |
|
|
428
|
+
|
|
429
|
+
## 13. Contributing
|
|
430
|
+
|
|
431
|
+
1. Fork the repository
|
|
432
|
+
2. Create a feature branch
|
|
433
|
+
3. Add tests for new functionality
|
|
434
|
+
4. Ensure all tests pass: `python -m pytest tests/ -v`
|
|
435
|
+
5. Submit a pull request
|
|
436
|
+
|
|
437
|
+
## 14. License
|
|
438
|
+
|
|
439
|
+
This project is licensed under the MIT License - see the LICENSE file for details.
|
|
440
|
+
|
|
441
|
+
---
|
|
442
|
+
|
|
443
|
+
**🚀 Ready to supercharge your testing workflow with parallel execution and advanced file comparison!**
|
|
444
|
+
|
|
445
|
+
For detailed parallel testing guide, see: [PARALLEL_TESTING_GUIDE.md](PARALLEL_TESTING_GUIDE.md)
|