cli-test-framework 0.5.0__tar.gz → 0.5.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.5.0/src/cli_test_framework.egg-info → cli_test_framework-0.5.1}/PKG-INFO +1 -1
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/docs/user_manual.md +137 -8
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/setup.py +1 -1
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/cli.py +8 -3
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/core/base_runner.py +19 -1
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/core/parallel_runner.py +9 -2
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/core/test_case.py +2 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/runners/json_runner.py +3 -2
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/runners/parallel_json_runner.py +4 -2
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/runners/yaml_runner.py +3 -2
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1/src/cli_test_framework.egg-info}/PKG-INFO +1 -1
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework.egg-info/SOURCES.txt +7 -1
- cli_test_framework-0.5.1/tests/integration/__pycache__/test_sequence.cpython-312-pytest-7.4.4.pyc +0 -0
- cli_test_framework-0.5.1/tests/integration/__pycache__/test_sequence.cpython-312-pytest-9.0.3.pyc +0 -0
- cli_test_framework-0.5.1/tests/integration/test_sequence.py +298 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/run_all.py +4 -4
- cli_test_framework-0.5.1/tests/unit/runners/__pycache__/test_test_case_filter.cpython-312-pytest-7.4.4.pyc +0 -0
- cli_test_framework-0.5.1/tests/unit/runners/__pycache__/test_test_case_filter.cpython-312-pytest-9.0.3.pyc +0 -0
- cli_test_framework-0.5.1/tests/unit/runners/test_test_case_filter.py +193 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/MANIFEST.in +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/README.md +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/pyproject.toml +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/setup.cfg +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/__init__.py +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/commands/__init__.py +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/commands/compare.py +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/core/__init__.py +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/core/assertions.py +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/core/execution.py +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/core/process_worker.py +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/core/setup.py +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/core/types.py +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/file_comparator/__init__.py +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/file_comparator/base_comparator.py +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/file_comparator/binary_comparator.py +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/file_comparator/csv_comparator.py +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/file_comparator/factory.py +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/file_comparator/h5_comparator.py +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/file_comparator/json_comparator.py +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/file_comparator/result.py +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/file_comparator/text_comparator.py +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/file_comparator/xml_comparator.py +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/runners/__init__.py +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/utils/__init__.py +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/utils/path_resolver.py +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/utils/report_generator.py +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework.egg-info/dependency_links.txt +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework.egg-info/entry_points.txt +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework.egg-info/requires.txt +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework.egg-info/top_level.txt +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/README.md +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/__init__.py +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/__pycache__/__init__.cpython-312.pyc +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/__pycache__/__init__.cpython-39.pyc +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/__pycache__/conftest.cpython-312-pytest-7.4.4.pyc +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/__pycache__/conftest.cpython-312-pytest-9.0.3.pyc +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/__pycache__/conftest.cpython-39-pytest-8.3.4.pyc +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/__pycache__/run_all.cpython-312.pyc +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/__pycache__/run_all.cpython-39.pyc +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/__pycache__/test_parallel_runner.cpython-312-pytest-7.4.4.pyc +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/__pycache__/test_setup_module.cpython-312-pytest-7.4.4.pyc +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/conftest.py +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/demos/h5_filter_demo.py +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/demos/manual_report_example.py +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/demos/perf_parallel.py +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/e2e/__init__.py +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/e2e/__pycache__/__init__.cpython-312.pyc +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/e2e/__pycache__/__init__.cpython-39.pyc +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/e2e/__pycache__/test_user_flows.cpython-312-pytest-7.4.4.pyc +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/e2e/__pycache__/test_user_flows.cpython-312-pytest-9.0.3.pyc +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/e2e/__pycache__/test_user_flows.cpython-39-pytest-8.3.4.pyc +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/e2e/test_user_flows.py +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/fixtures/test_cases.json +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/fixtures/test_cases.yaml +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/fixtures/test_cases1.json +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/fixtures/test_with_setup.json +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/fixtures/test_with_setup.yaml +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/integration/file_compare/__pycache__/test_binary_compare.cpython-312-pytest-7.4.4.pyc +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/integration/file_compare/__pycache__/test_binary_compare.cpython-312-pytest-9.0.3.pyc +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/integration/file_compare/__pycache__/test_binary_compare.cpython-39-pytest-8.3.4.pyc +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/integration/file_compare/__pycache__/test_h5_compare.cpython-312-pytest-7.4.4.pyc +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/integration/file_compare/__pycache__/test_h5_compare.cpython-312-pytest-9.0.3.pyc +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/integration/file_compare/__pycache__/test_h5_compare.cpython-39-pytest-8.3.4.pyc +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/integration/file_compare/__pycache__/test_json_compare.cpython-312-pytest-7.4.4.pyc +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/integration/file_compare/__pycache__/test_json_compare.cpython-312-pytest-9.0.3.pyc +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/integration/file_compare/__pycache__/test_json_compare.cpython-39-pytest-8.3.4.pyc +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/integration/file_compare/__pycache__/test_text_compare.cpython-312-pytest-7.4.4.pyc +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/integration/file_compare/__pycache__/test_text_compare.cpython-312-pytest-9.0.3.pyc +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/integration/file_compare/__pycache__/test_text_compare.cpython-39-pytest-8.3.4.pyc +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/integration/file_compare/test_binary_compare.py +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/integration/file_compare/test_h5_compare.py +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/integration/file_compare/test_json_compare.py +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/integration/file_compare/test_text_compare.py +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/integration/parallel/__pycache__/test_parallel_runner.cpython-312-pytest-7.4.4.pyc +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/integration/parallel/__pycache__/test_parallel_runner.cpython-312-pytest-9.0.3.pyc +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/integration/parallel/__pycache__/test_parallel_runner.cpython-39-pytest-8.3.4.pyc +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/integration/parallel/test_parallel_runner.py +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/integration/path_handling/__pycache__/test_spaces_in_paths.cpython-312-pytest-7.4.4.pyc +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/integration/path_handling/__pycache__/test_spaces_in_paths.cpython-312-pytest-9.0.3.pyc +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/integration/path_handling/__pycache__/test_spaces_in_paths.cpython-39-pytest-8.3.4.pyc +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/integration/path_handling/test_spaces_in_paths.py +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/test_report.txt +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/unit/core/__pycache__/test_setup.cpython-312-pytest-7.4.4.pyc +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/unit/core/__pycache__/test_setup.cpython-312-pytest-9.0.3.pyc +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/unit/core/__pycache__/test_setup.cpython-39-pytest-8.3.4.pyc +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/unit/core/test_setup.py +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/unit/runners/__pycache__/test_json_yaml_runner.cpython-312-pytest-7.4.4.pyc +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/unit/runners/__pycache__/test_json_yaml_runner.cpython-312-pytest-9.0.3.pyc +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/unit/runners/__pycache__/test_json_yaml_runner.cpython-39-pytest-8.3.4.pyc +0 -0
- {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/unit/runners/test_json_yaml_runner.py +0 -0
{cli_test_framework-0.5.0/src/cli_test_framework.egg-info → cli_test_framework-0.5.1}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cli-test-framework
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.1
|
|
4
4
|
Summary: A powerful command line testing framework in Python with setup modules, parallel execution, and file comparison capabilities.
|
|
5
5
|
Home-page: https://github.com/ozil111/cli-test-framework
|
|
6
6
|
Author: Xiaotong Wang
|
|
@@ -7,11 +7,14 @@
|
|
|
7
7
|
4. [Test Case Definition](#test-case-definition)
|
|
8
8
|
5. [Setup Module](#setup-module)
|
|
9
9
|
6. [Parallel Testing](#parallel-testing)
|
|
10
|
-
7. [
|
|
11
|
-
8. [
|
|
12
|
-
9. [
|
|
13
|
-
10. [
|
|
14
|
-
11. [
|
|
10
|
+
7. [Sequence Testing](#sequence-testing)
|
|
11
|
+
8. [File Comparison](#file-comparison)
|
|
12
|
+
9. [Advanced Features](#advanced-features)
|
|
13
|
+
10. [Troubleshooting](#troubleshooting)
|
|
14
|
+
11. [API Reference](#api-reference)
|
|
15
|
+
12. [Examples](#examples)
|
|
16
|
+
|
|
17
|
+
|
|
15
18
|
|
|
16
19
|
## Introduction
|
|
17
20
|
|
|
@@ -19,6 +22,7 @@ The CLI Testing Framework is a powerful tool designed for testing command-line a
|
|
|
19
22
|
|
|
20
23
|
### Key Features
|
|
21
24
|
- Parallel test execution with thread and process support
|
|
25
|
+
- Sequence test execution with multi-step fail-fast
|
|
22
26
|
- JSON/YAML test case definition
|
|
23
27
|
- Advanced file comparison capabilities
|
|
24
28
|
- Comprehensive reporting
|
|
@@ -74,6 +78,18 @@ runner = JSONRunner(
|
|
|
74
78
|
success = runner.run_tests()
|
|
75
79
|
```
|
|
76
80
|
|
|
81
|
+
3. Run only specified test case(s):
|
|
82
|
+
```python
|
|
83
|
+
from cli_test_framework.runners import JSONRunner
|
|
84
|
+
|
|
85
|
+
runner = JSONRunner(
|
|
86
|
+
config_file="test_cases.json",
|
|
87
|
+
workspace="/path/to/workspace",
|
|
88
|
+
test_case_filter=["test_ls_command", "test_echo_command"]
|
|
89
|
+
)
|
|
90
|
+
success = runner.run_tests()
|
|
91
|
+
```
|
|
92
|
+
|
|
77
93
|
### Using the Command Line
|
|
78
94
|
|
|
79
95
|
```bash
|
|
@@ -82,6 +98,12 @@ cli-test run test_cases.json
|
|
|
82
98
|
|
|
83
99
|
# Run tests in parallel
|
|
84
100
|
cli-test run test_cases.json --parallel --workers 4
|
|
101
|
+
|
|
102
|
+
# Run only specified test case(s)
|
|
103
|
+
cli-test run test_cases.json --test-case test_ls_command
|
|
104
|
+
|
|
105
|
+
# Run multiple specified test cases
|
|
106
|
+
cli-test run test_cases.json -t test_ls_command -t test_echo_command
|
|
85
107
|
```
|
|
86
108
|
|
|
87
109
|
## Test Case Definition
|
|
@@ -292,6 +314,54 @@ runner = ParallelJSONRunner(
|
|
|
292
314
|
success = runner.run_tests()
|
|
293
315
|
```
|
|
294
316
|
|
|
317
|
+
## Sequence Testing
|
|
318
|
+
|
|
319
|
+
Sequence testing allows a single test case to contain multiple ordered steps that execute sequentially. If any step fails, subsequent steps are skipped (fail-fast).
|
|
320
|
+
|
|
321
|
+
### JSON Format
|
|
322
|
+
|
|
323
|
+
```json
|
|
324
|
+
{
|
|
325
|
+
"test_cases": [
|
|
326
|
+
{
|
|
327
|
+
"name": "Multi-step Test",
|
|
328
|
+
"steps": [
|
|
329
|
+
{
|
|
330
|
+
"command": "echo",
|
|
331
|
+
"args": ["step1"],
|
|
332
|
+
"expected": { "return_code": 0, "output_contains": ["step1"] }
|
|
333
|
+
},
|
|
334
|
+
{
|
|
335
|
+
"command": "echo",
|
|
336
|
+
"args": ["step2"],
|
|
337
|
+
"expected": { "return_code": 0, "output_contains": ["step2"] }
|
|
338
|
+
}
|
|
339
|
+
]
|
|
340
|
+
}
|
|
341
|
+
]
|
|
342
|
+
}
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
### YAML Format
|
|
346
|
+
|
|
347
|
+
```yaml
|
|
348
|
+
test_cases:
|
|
349
|
+
- name: Multi-step Test
|
|
350
|
+
steps:
|
|
351
|
+
- command: echo
|
|
352
|
+
args: ["step1"]
|
|
353
|
+
expected:
|
|
354
|
+
return_code: 0
|
|
355
|
+
output_contains: ["step1"]
|
|
356
|
+
- command: echo
|
|
357
|
+
args: ["step2"]
|
|
358
|
+
expected:
|
|
359
|
+
return_code: 0
|
|
360
|
+
output_contains: ["step2"]
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
Each step supports `command`, `args`, `expected`, and `timeout` fields. When a step fails, the overall result reports which step failed (e.g., "Failed at step 2/3: ...").
|
|
364
|
+
|
|
295
365
|
## File Comparison
|
|
296
366
|
|
|
297
367
|
### Basic File Comparison
|
|
@@ -355,6 +425,52 @@ compare-files binary1.bin binary2.bin --chunk-size 16384
|
|
|
355
425
|
|
|
356
426
|
## Advanced Features
|
|
357
427
|
|
|
428
|
+
### Specifying Test Cases
|
|
429
|
+
|
|
430
|
+
You can run only specific test cases by name using the `test_case_filter` parameter (Python API) or the `--test-case` / `-t` flag (CLI).
|
|
431
|
+
|
|
432
|
+
#### CLI Usage
|
|
433
|
+
|
|
434
|
+
```bash
|
|
435
|
+
# Run a single test case by name
|
|
436
|
+
cli-test run test_cases.json --test-case test_ls_command
|
|
437
|
+
|
|
438
|
+
# Run multiple test cases (repeat the flag)
|
|
439
|
+
cli-test run test_cases.json -t test_ls_command -t test_echo_command
|
|
440
|
+
|
|
441
|
+
# Works with parallel mode too
|
|
442
|
+
cli-test run test_cases.json --parallel --test-case test_ls_command
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
#### Python API Usage
|
|
446
|
+
|
|
447
|
+
```python
|
|
448
|
+
from cli_test_framework.runners import JSONRunner, ParallelJSONRunner, YAMLRunner
|
|
449
|
+
|
|
450
|
+
# With JSONRunner
|
|
451
|
+
runner = JSONRunner(
|
|
452
|
+
config_file="test_cases.json",
|
|
453
|
+
test_case_filter=["test_ls_command", "test_echo_command"]
|
|
454
|
+
)
|
|
455
|
+
|
|
456
|
+
# With YAMLRunner
|
|
457
|
+
runner = YAMLRunner(
|
|
458
|
+
config_file="test_cases.yaml",
|
|
459
|
+
test_case_filter=["test_case_1"]
|
|
460
|
+
)
|
|
461
|
+
|
|
462
|
+
# With ParallelJSONRunner
|
|
463
|
+
runner = ParallelJSONRunner(
|
|
464
|
+
config_file="test_cases.json",
|
|
465
|
+
test_case_filter=["heavy_test"],
|
|
466
|
+
max_workers=4
|
|
467
|
+
)
|
|
468
|
+
|
|
469
|
+
success = runner.run_tests()
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
If a specified test case name is not found, a warning will be printed. The filter matches test case names exactly.
|
|
473
|
+
|
|
358
474
|
### Custom Assertions
|
|
359
475
|
```python
|
|
360
476
|
from cli_test_framework.assertions import BaseAssertion
|
|
@@ -422,24 +538,37 @@ runner = JSONRunner(
|
|
|
422
538
|
#### JSONRunner
|
|
423
539
|
```python
|
|
424
540
|
class JSONRunner:
|
|
425
|
-
def __init__(self, config_file, workspace=None,
|
|
541
|
+
def __init__(self, config_file, workspace=None, test_case_filter=None):
|
|
426
542
|
"""
|
|
427
543
|
Initialize JSONRunner
|
|
428
544
|
:param config_file: Path to JSON test case file
|
|
429
545
|
:param workspace: Working directory for test execution
|
|
430
|
-
:param
|
|
546
|
+
:param test_case_filter: Optional list of test case names to run (runs all if None)
|
|
547
|
+
"""
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
#### YAMLRunner
|
|
551
|
+
```python
|
|
552
|
+
class YAMLRunner:
|
|
553
|
+
def __init__(self, config_file, workspace=None, test_case_filter=None):
|
|
554
|
+
"""
|
|
555
|
+
Initialize YAMLRunner
|
|
556
|
+
:param config_file: Path to YAML test case file
|
|
557
|
+
:param workspace: Working directory for test execution
|
|
558
|
+
:param test_case_filter: Optional list of test case names to run (runs all if None)
|
|
431
559
|
"""
|
|
432
560
|
```
|
|
433
561
|
|
|
434
562
|
#### ParallelJSONRunner
|
|
435
563
|
```python
|
|
436
564
|
class ParallelJSONRunner:
|
|
437
|
-
def __init__(self, config_file, max_workers=None, execution_mode="thread"):
|
|
565
|
+
def __init__(self, config_file, max_workers=None, execution_mode="thread", test_case_filter=None):
|
|
438
566
|
"""
|
|
439
567
|
Initialize ParallelJSONRunner
|
|
440
568
|
:param config_file: Path to JSON test case file
|
|
441
569
|
:param max_workers: Maximum number of parallel workers
|
|
442
570
|
:param execution_mode: "thread" or "process"
|
|
571
|
+
:param test_case_filter: Optional list of test case names to run (runs all if None)
|
|
443
572
|
"""
|
|
444
573
|
```
|
|
445
574
|
|
|
@@ -8,7 +8,7 @@ with open(os.path.join(this_directory, 'README.md'), encoding='utf-8') as f:
|
|
|
8
8
|
|
|
9
9
|
setup(
|
|
10
10
|
name="cli-test-framework",
|
|
11
|
-
version="0.5.
|
|
11
|
+
version="0.5.1",
|
|
12
12
|
author="Xiaotong Wang",
|
|
13
13
|
author_email="xiaotongwang98@gmail.com",
|
|
14
14
|
description="A powerful command line testing framework in Python with setup modules, parallel execution, and file comparison capabilities.",
|
|
@@ -40,6 +40,8 @@ Examples:
|
|
|
40
40
|
help='Parallel execution mode (default: thread)')
|
|
41
41
|
run_parser.add_argument('--output-format', choices=['text', 'json', 'html'], default='text',
|
|
42
42
|
help='Output format for test results')
|
|
43
|
+
run_parser.add_argument('--test-case', '-t', action='append', default=None,
|
|
44
|
+
help='Run only specified test case(s) by name (can be used multiple times)')
|
|
43
45
|
run_parser.add_argument('--verbose', '-v', action='store_true', help='Enable verbose output')
|
|
44
46
|
run_parser.add_argument('--debug', action='store_true', help='Enable debug mode')
|
|
45
47
|
|
|
@@ -64,19 +66,22 @@ def run_tests(args):
|
|
|
64
66
|
config_file=str(config_file),
|
|
65
67
|
workspace=args.workspace,
|
|
66
68
|
max_workers=args.workers,
|
|
67
|
-
execution_mode=args.execution_mode
|
|
69
|
+
execution_mode=args.execution_mode,
|
|
70
|
+
test_case_filter=args.test_case
|
|
68
71
|
)
|
|
69
72
|
else:
|
|
70
73
|
# Use appropriate single-threaded runner
|
|
71
74
|
if file_ext in ['.json']:
|
|
72
75
|
runner = JSONRunner(
|
|
73
76
|
config_file=str(config_file),
|
|
74
|
-
workspace=args.workspace
|
|
77
|
+
workspace=args.workspace,
|
|
78
|
+
test_case_filter=args.test_case
|
|
75
79
|
)
|
|
76
80
|
elif file_ext in ['.yaml', '.yml']:
|
|
77
81
|
runner = YAMLRunner(
|
|
78
82
|
config_file=str(config_file),
|
|
79
|
-
workspace=args.workspace
|
|
83
|
+
workspace=args.workspace,
|
|
84
|
+
test_case_filter=args.test_case
|
|
80
85
|
)
|
|
81
86
|
else:
|
|
82
87
|
print(f"Error: Unsupported configuration file format: {file_ext}")
|
{cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/core/base_runner.py
RENAMED
|
@@ -7,13 +7,15 @@ from .setup import SetupManager, EnvironmentSetup
|
|
|
7
7
|
from .execution import execute_single_test_case
|
|
8
8
|
|
|
9
9
|
class BaseRunner(ABC):
|
|
10
|
-
def __init__(self, config_file: str, workspace: Optional[str] = None
|
|
10
|
+
def __init__(self, config_file: str, workspace: Optional[str] = None,
|
|
11
|
+
test_case_filter: Optional[List[str]] = None):
|
|
11
12
|
if workspace:
|
|
12
13
|
self.workspace = Path(workspace)
|
|
13
14
|
else:
|
|
14
15
|
self.workspace = Path(__file__).parent.parent.parent
|
|
15
16
|
self.config_path = self.workspace / config_file
|
|
16
17
|
self.test_cases: List[TestCase] = []
|
|
18
|
+
self.test_case_filter: Optional[List[str]] = test_case_filter
|
|
17
19
|
self.results: Dict[str, Any] = {
|
|
18
20
|
"total": 0,
|
|
19
21
|
"passed": 0,
|
|
@@ -44,12 +46,28 @@ class BaseRunner(ABC):
|
|
|
44
46
|
# # 动态加载自定义setup插件
|
|
45
47
|
# pass
|
|
46
48
|
|
|
49
|
+
def _apply_test_case_filter(self) -> None:
|
|
50
|
+
"""根据 test_case_filter 过滤测试用例"""
|
|
51
|
+
if self.test_case_filter:
|
|
52
|
+
original_count = len(self.test_cases)
|
|
53
|
+
self.test_cases = [tc for tc in self.test_cases if tc.name in self.test_case_filter]
|
|
54
|
+
filtered_out = original_count - len(self.test_cases)
|
|
55
|
+
if filtered_out > 0:
|
|
56
|
+
print(f"Filtered out {filtered_out} test case(s). Running {len(self.test_cases)} specified case(s).")
|
|
57
|
+
if not self.test_cases:
|
|
58
|
+
print(f"Warning: No matching test cases found for: {self.test_case_filter}")
|
|
59
|
+
|
|
47
60
|
def run_tests(self) -> bool:
|
|
48
61
|
"""Run all test cases and return whether all tests passed"""
|
|
49
62
|
try:
|
|
50
63
|
self.load_test_cases()
|
|
64
|
+
self._apply_test_case_filter()
|
|
51
65
|
self.results["total"] = len(self.test_cases)
|
|
52
66
|
|
|
67
|
+
if self.results["total"] == 0:
|
|
68
|
+
print("No test cases to run.")
|
|
69
|
+
return False
|
|
70
|
+
|
|
53
71
|
# 执行setup任务
|
|
54
72
|
self.setup_manager.setup_all()
|
|
55
73
|
|
{cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/core/parallel_runner.py
RENAMED
|
@@ -12,7 +12,8 @@ class ParallelRunner(BaseRunner):
|
|
|
12
12
|
|
|
13
13
|
def __init__(self, config_file: str, workspace: Optional[str] = None,
|
|
14
14
|
max_workers: Optional[int] = None,
|
|
15
|
-
execution_mode: str = "thread"
|
|
15
|
+
execution_mode: str = "thread",
|
|
16
|
+
test_case_filter: Optional[List[str]] = None):
|
|
16
17
|
"""
|
|
17
18
|
初始化并行运行器
|
|
18
19
|
|
|
@@ -21,8 +22,9 @@ class ParallelRunner(BaseRunner):
|
|
|
21
22
|
workspace: 工作目录
|
|
22
23
|
max_workers: 最大并发数,默认为CPU核心数
|
|
23
24
|
execution_mode: 执行模式,'thread'(线程) 或 'process'(进程)
|
|
25
|
+
test_case_filter: 只运行指定名称的测试用例
|
|
24
26
|
"""
|
|
25
|
-
super().__init__(config_file, workspace)
|
|
27
|
+
super().__init__(config_file, workspace, test_case_filter)
|
|
26
28
|
self.max_workers = max_workers
|
|
27
29
|
self.execution_mode = execution_mode
|
|
28
30
|
self.lock = threading.Lock() # 用于线程安全的结果更新
|
|
@@ -31,8 +33,13 @@ class ParallelRunner(BaseRunner):
|
|
|
31
33
|
"""并行运行所有测试用例"""
|
|
32
34
|
try:
|
|
33
35
|
self.load_test_cases()
|
|
36
|
+
self._apply_test_case_filter()
|
|
34
37
|
self.results["total"] = len(self.test_cases)
|
|
35
38
|
|
|
39
|
+
if self.results["total"] == 0:
|
|
40
|
+
print("No test cases to run.")
|
|
41
|
+
return False
|
|
42
|
+
|
|
36
43
|
# 执行setup任务
|
|
37
44
|
self.setup_manager.setup_all()
|
|
38
45
|
|
{cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/core/test_case.py
RENAMED
|
@@ -4,6 +4,7 @@ from typing import List, Dict, Any, Optional
|
|
|
4
4
|
@dataclass
|
|
5
5
|
class TestCaseStep:
|
|
6
6
|
"""A single step within a sequence test case."""
|
|
7
|
+
__test__ = False
|
|
7
8
|
command: str
|
|
8
9
|
args: List[str]
|
|
9
10
|
expected: Dict[str, Any]
|
|
@@ -11,6 +12,7 @@ class TestCaseStep:
|
|
|
11
12
|
|
|
12
13
|
@dataclass
|
|
13
14
|
class TestCase:
|
|
15
|
+
__test__ = False
|
|
14
16
|
name: str
|
|
15
17
|
command: str = ""
|
|
16
18
|
args: List[str] = field(default_factory=list)
|
{cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/runners/json_runner.py
RENAMED
|
@@ -8,8 +8,9 @@ import json
|
|
|
8
8
|
import sys
|
|
9
9
|
|
|
10
10
|
class JSONRunner(BaseRunner):
|
|
11
|
-
def __init__(self, config_file="test_cases.json", workspace: Optional[str] = None
|
|
12
|
-
|
|
11
|
+
def __init__(self, config_file="test_cases.json", workspace: Optional[str] = None,
|
|
12
|
+
test_case_filter: Optional[list] = None):
|
|
13
|
+
super().__init__(config_file, workspace, test_case_filter)
|
|
13
14
|
# Backward-compatible attribute for tests that patch path_resolver
|
|
14
15
|
self.path_resolver = PathResolver(self.workspace)
|
|
15
16
|
|
|
@@ -13,7 +13,8 @@ class ParallelJSONRunner(ParallelRunner):
|
|
|
13
13
|
"""并行JSON测试运行器"""
|
|
14
14
|
|
|
15
15
|
def __init__(self, config_file="test_cases.json", workspace: Optional[str] = None,
|
|
16
|
-
max_workers: Optional[int] = None, execution_mode: str = "thread"
|
|
16
|
+
max_workers: Optional[int] = None, execution_mode: str = "thread",
|
|
17
|
+
test_case_filter: Optional[list] = None):
|
|
17
18
|
"""
|
|
18
19
|
初始化并行JSON运行器
|
|
19
20
|
|
|
@@ -22,6 +23,7 @@ class ParallelJSONRunner(ParallelRunner):
|
|
|
22
23
|
workspace: 工作目录
|
|
23
24
|
max_workers: 最大并发数
|
|
24
25
|
execution_mode: 执行模式,'thread' 或 'process'
|
|
26
|
+
test_case_filter: 只运行指定名称的测试用例
|
|
25
27
|
"""
|
|
26
28
|
# 1. 自动感知:获取物理核心数
|
|
27
29
|
# 如果获取失败默认为 4,留 2 个核给系统/Python (防止 GUI 卡死)
|
|
@@ -34,7 +36,7 @@ class ParallelJSONRunner(ParallelRunner):
|
|
|
34
36
|
if max_workers is None:
|
|
35
37
|
max_workers = self.total_physical
|
|
36
38
|
|
|
37
|
-
super().__init__(config_file, workspace, max_workers, execution_mode)
|
|
39
|
+
super().__init__(config_file, workspace, max_workers, execution_mode, test_case_filter)
|
|
38
40
|
# Backward-compatible attribute for potential external patches/tests
|
|
39
41
|
self.path_resolver = PathResolver(self.workspace)
|
|
40
42
|
self._print_lock = threading.Lock() # 用于控制输出顺序
|
{cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/runners/yaml_runner.py
RENAMED
|
@@ -7,8 +7,9 @@ from ..utils.path_resolver import PathResolver, parse_command_string, resolve_pa
|
|
|
7
7
|
import sys
|
|
8
8
|
|
|
9
9
|
class YAMLRunner(BaseRunner):
|
|
10
|
-
def __init__(self, config_file="test_cases.yaml", workspace: Optional[str] = None
|
|
11
|
-
|
|
10
|
+
def __init__(self, config_file="test_cases.yaml", workspace: Optional[str] = None,
|
|
11
|
+
test_case_filter: Optional[list] = None):
|
|
12
|
+
super().__init__(config_file, workspace, test_case_filter)
|
|
12
13
|
# Backward-compatible attribute for tests that patch path_resolver
|
|
13
14
|
self.path_resolver = PathResolver(self.workspace)
|
|
14
15
|
|
{cli_test_framework-0.5.0 → cli_test_framework-0.5.1/src/cli_test_framework.egg-info}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cli-test-framework
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.1
|
|
4
4
|
Summary: A powerful command line testing framework in Python with setup modules, parallel execution, and file comparison capabilities.
|
|
5
5
|
Home-page: https://github.com/ozil111/cli-test-framework
|
|
6
6
|
Author: Xiaotong Wang
|
{cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework.egg-info/SOURCES.txt
RENAMED
|
@@ -68,6 +68,9 @@ tests/fixtures/test_cases.yaml
|
|
|
68
68
|
tests/fixtures/test_cases1.json
|
|
69
69
|
tests/fixtures/test_with_setup.json
|
|
70
70
|
tests/fixtures/test_with_setup.yaml
|
|
71
|
+
tests/integration/test_sequence.py
|
|
72
|
+
tests/integration/__pycache__/test_sequence.cpython-312-pytest-7.4.4.pyc
|
|
73
|
+
tests/integration/__pycache__/test_sequence.cpython-312-pytest-9.0.3.pyc
|
|
71
74
|
tests/integration/file_compare/test_binary_compare.py
|
|
72
75
|
tests/integration/file_compare/test_h5_compare.py
|
|
73
76
|
tests/integration/file_compare/test_json_compare.py
|
|
@@ -97,6 +100,9 @@ tests/unit/core/__pycache__/test_setup.cpython-312-pytest-7.4.4.pyc
|
|
|
97
100
|
tests/unit/core/__pycache__/test_setup.cpython-312-pytest-9.0.3.pyc
|
|
98
101
|
tests/unit/core/__pycache__/test_setup.cpython-39-pytest-8.3.4.pyc
|
|
99
102
|
tests/unit/runners/test_json_yaml_runner.py
|
|
103
|
+
tests/unit/runners/test_test_case_filter.py
|
|
100
104
|
tests/unit/runners/__pycache__/test_json_yaml_runner.cpython-312-pytest-7.4.4.pyc
|
|
101
105
|
tests/unit/runners/__pycache__/test_json_yaml_runner.cpython-312-pytest-9.0.3.pyc
|
|
102
|
-
tests/unit/runners/__pycache__/test_json_yaml_runner.cpython-39-pytest-8.3.4.pyc
|
|
106
|
+
tests/unit/runners/__pycache__/test_json_yaml_runner.cpython-39-pytest-8.3.4.pyc
|
|
107
|
+
tests/unit/runners/__pycache__/test_test_case_filter.cpython-312-pytest-7.4.4.pyc
|
|
108
|
+
tests/unit/runners/__pycache__/test_test_case_filter.cpython-312-pytest-9.0.3.pyc
|