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.
Files changed (110) hide show
  1. {cli_test_framework-0.5.0/src/cli_test_framework.egg-info → cli_test_framework-0.5.1}/PKG-INFO +1 -1
  2. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/docs/user_manual.md +137 -8
  3. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/setup.py +1 -1
  4. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/cli.py +8 -3
  5. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/core/base_runner.py +19 -1
  6. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/core/parallel_runner.py +9 -2
  7. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/core/test_case.py +2 -0
  8. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/runners/json_runner.py +3 -2
  9. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/runners/parallel_json_runner.py +4 -2
  10. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/runners/yaml_runner.py +3 -2
  11. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1/src/cli_test_framework.egg-info}/PKG-INFO +1 -1
  12. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework.egg-info/SOURCES.txt +7 -1
  13. cli_test_framework-0.5.1/tests/integration/__pycache__/test_sequence.cpython-312-pytest-7.4.4.pyc +0 -0
  14. cli_test_framework-0.5.1/tests/integration/__pycache__/test_sequence.cpython-312-pytest-9.0.3.pyc +0 -0
  15. cli_test_framework-0.5.1/tests/integration/test_sequence.py +298 -0
  16. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/run_all.py +4 -4
  17. cli_test_framework-0.5.1/tests/unit/runners/__pycache__/test_test_case_filter.cpython-312-pytest-7.4.4.pyc +0 -0
  18. cli_test_framework-0.5.1/tests/unit/runners/__pycache__/test_test_case_filter.cpython-312-pytest-9.0.3.pyc +0 -0
  19. cli_test_framework-0.5.1/tests/unit/runners/test_test_case_filter.py +193 -0
  20. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/MANIFEST.in +0 -0
  21. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/README.md +0 -0
  22. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/pyproject.toml +0 -0
  23. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/setup.cfg +0 -0
  24. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/__init__.py +0 -0
  25. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/commands/__init__.py +0 -0
  26. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/commands/compare.py +0 -0
  27. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/core/__init__.py +0 -0
  28. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/core/assertions.py +0 -0
  29. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/core/execution.py +0 -0
  30. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/core/process_worker.py +0 -0
  31. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/core/setup.py +0 -0
  32. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/core/types.py +0 -0
  33. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/file_comparator/__init__.py +0 -0
  34. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/file_comparator/base_comparator.py +0 -0
  35. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/file_comparator/binary_comparator.py +0 -0
  36. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/file_comparator/csv_comparator.py +0 -0
  37. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/file_comparator/factory.py +0 -0
  38. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/file_comparator/h5_comparator.py +0 -0
  39. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/file_comparator/json_comparator.py +0 -0
  40. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/file_comparator/result.py +0 -0
  41. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/file_comparator/text_comparator.py +0 -0
  42. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/file_comparator/xml_comparator.py +0 -0
  43. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/runners/__init__.py +0 -0
  44. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/utils/__init__.py +0 -0
  45. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/utils/path_resolver.py +0 -0
  46. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework/utils/report_generator.py +0 -0
  47. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework.egg-info/dependency_links.txt +0 -0
  48. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework.egg-info/entry_points.txt +0 -0
  49. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework.egg-info/requires.txt +0 -0
  50. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/src/cli_test_framework.egg-info/top_level.txt +0 -0
  51. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/README.md +0 -0
  52. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/__init__.py +0 -0
  53. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/__pycache__/__init__.cpython-312.pyc +0 -0
  54. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/__pycache__/__init__.cpython-39.pyc +0 -0
  55. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/__pycache__/conftest.cpython-312-pytest-7.4.4.pyc +0 -0
  56. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/__pycache__/conftest.cpython-312-pytest-9.0.3.pyc +0 -0
  57. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/__pycache__/conftest.cpython-39-pytest-8.3.4.pyc +0 -0
  58. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/__pycache__/run_all.cpython-312.pyc +0 -0
  59. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/__pycache__/run_all.cpython-39.pyc +0 -0
  60. {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
  61. {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
  62. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/conftest.py +0 -0
  63. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/demos/h5_filter_demo.py +0 -0
  64. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/demos/manual_report_example.py +0 -0
  65. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/demos/perf_parallel.py +0 -0
  66. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/e2e/__init__.py +0 -0
  67. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/e2e/__pycache__/__init__.cpython-312.pyc +0 -0
  68. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/e2e/__pycache__/__init__.cpython-39.pyc +0 -0
  69. {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
  70. {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
  71. {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
  72. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/e2e/test_user_flows.py +0 -0
  73. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/fixtures/test_cases.json +0 -0
  74. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/fixtures/test_cases.yaml +0 -0
  75. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/fixtures/test_cases1.json +0 -0
  76. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/fixtures/test_with_setup.json +0 -0
  77. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/fixtures/test_with_setup.yaml +0 -0
  78. {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
  79. {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
  80. {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
  81. {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
  82. {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
  83. {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
  84. {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
  85. {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
  86. {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
  87. {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
  88. {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
  89. {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
  90. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/integration/file_compare/test_binary_compare.py +0 -0
  91. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/integration/file_compare/test_h5_compare.py +0 -0
  92. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/integration/file_compare/test_json_compare.py +0 -0
  93. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/integration/file_compare/test_text_compare.py +0 -0
  94. {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
  95. {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
  96. {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
  97. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/integration/parallel/test_parallel_runner.py +0 -0
  98. {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
  99. {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
  100. {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
  101. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/integration/path_handling/test_spaces_in_paths.py +0 -0
  102. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/test_report.txt +0 -0
  103. {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
  104. {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
  105. {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
  106. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/unit/core/test_setup.py +0 -0
  107. {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
  108. {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
  109. {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
  110. {cli_test_framework-0.5.0 → cli_test_framework-0.5.1}/tests/unit/runners/test_json_yaml_runner.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cli-test-framework
3
- Version: 0.5.0
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. [File Comparison](#file-comparison)
11
- 8. [Advanced Features](#advanced-features)
12
- 9. [Troubleshooting](#troubleshooting)
13
- 10. [API Reference](#api-reference)
14
- 11. [Examples](#examples)
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, debug=False):
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 debug: Enable debug mode
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.0",
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}")
@@ -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
 
@@ -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
 
@@ -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)
@@ -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
- super().__init__(config_file, workspace)
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() # 用于控制输出顺序
@@ -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
- super().__init__(config_file, workspace)
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
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cli-test-framework
3
- Version: 0.5.0
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
@@ -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