Files
cleveragents-core/features/plan_cli_coverage_boost.feature
T
hurui200320 2005b8ef82
CI / push-validation (push) Successful in 18s
CI / build (push) Successful in 19s
CI / helm (push) Successful in 24s
CI / lint (push) Successful in 29s
CI / security (push) Successful in 1m11s
CI / e2e_tests (push) Successful in 2m56s
CI / quality (push) Successful in 3m40s
CI / typecheck (push) Successful in 3m59s
CI / integration_tests (push) Successful in 4m3s
CI / unit_tests (push) Successful in 4m55s
CI / docker (push) Successful in 10s
CI / coverage (push) Successful in 10m44s
CI / status-check (push) Successful in 1s
CI / benchmark-regression (push) Has been skipped
CI / benchmark-publish (push) Successful in 1h13m28s
feat(tests): replace all @skip tags with proper @tdd_expected_fail tags or remove them across the entire codebase (#7221)
## Summary

Replaces all 234 bare `@skip` occurrences across 82 Behave feature files with the correct TDD issue-capture tagging system described in CONTRIBUTING.md § Bug Fix Workflow.

Previously, the noxfile ran Behave with `--tags=not @skip`, silently excluding all `@skip`-tagged scenarios from every CI run. These tests never ran, never inverted results via the `@tdd_expected_fail` mechanism, and never contributed to coverage — defeating the purpose of TDD issue-capture testing. Every `@skip` occurrence had a commented-out hint line immediately above it showing the intended proper tags (e.g., `# @tdd_issue @tdd_issue_4272 @tdd_expected_fail @skip`), confirming they were all intended for conversion.

## Changes

### Mechanical conversion (234 replacements across 82 files)
- Extracted the proper TDD tags from the comment hint above each `@skip` line, removed `@skip` from the tag set, and replaced the `@skip` line with those tags.
- Removed the now-redundant comment hint lines alongside each replacement.

### Bug-fixed scenarios — `@tdd_expected_fail` removed (84 scenarios)
- After conversion, ran `nox -s unit_tests` to identify which newly-enabled `@tdd_expected_fail` scenarios now **pass** (their referenced bugs have already been fixed). Removed `@tdd_expected_fail` from those 84 scenarios and their corresponding feature-level tags, leaving only the permanent `@tdd_issue @tdd_issue_<N>` regression-guard tags.
- Affected features include: `tdd_tool_runner_env_precedence`, `tdd_automation_profile_session_leak`, `tls_certificate_check`, `project_create_persist`, `resource_type_bootstrap_*`, and 18 others.

### Noxfile cleanup
- Removed all four `--tags=not @skip` arguments from `noxfile.py` (unit_tests and coverage sessions). With zero `@skip` tags remaining in the codebase, this filter was dead code and its presence would mislead future maintainers into thinking `@skip` is still a supported escape mechanism.

### Regression guard files
- Split the regression guards into two focused files:
  - `tdd_regression_guards_exec_env.feature` for bug #4281 (exec-env precedence)
  - `tdd_regression_guards_session_list.feature` for bug #4271 (session list summary)
- Each file carries only its own `@tdd_issue` tags at the feature level, avoiding cross-contamination via Behave tag inheritance. The `Background` step (`session-list-summary mock`) only appears in the session-list file where it is actually needed.

### Duplicate tag cleanup
- Removed duplicate `@tdd_issue @tdd_issue_4287` tag lines in `tdd_skill_add_regression.feature` (lines 20 and 29).

### Inline comment for retained `@tdd_expected_fail`
- Added inline comment in `ci_workflow_validation.feature:134` explaining why this specific #4227 scenario retains `@tdd_expected_fail` despite #4227 being closed (CI YAML does not encode threshold as a machine-readable value).

### Known edge cases — `@tdd_expected_fail` retained (closed issues, fix on master, scenarios still fail)
The following issues are **closed** and their fixes **are on master**, but the specific test assertions still fail because the fixes address other aspects of the bugs. The `@tdd_expected_fail` tags are functionally correct and must remain until the specific scenario assertions pass:
- `tdd_exec_env_resolution_precedence.feature` — bug #1080 (closed 2026-03-31). The precedence-level-2-vs-4 scenario still fails.
- `session_list_summary_dedup.feature` — bug #3046 (closed 2026-04-05). The dedup-consistency scenarios still fail.
- `actor_add_update_enforcement.feature` — bug #2609 (closed 2026-04-05). The enforcement scenarios still fail.
- `ci_workflow_validation.feature:134` — #4227 (closed 2026-04-08). The CI YAML threshold assertion still fails.

## Verification

- `grep -r "@skip" features/ --include="*.feature"` → **zero results** ✓
- `grep -n "tags=not @skip" noxfile.py` → **zero results** ✓
- `nox -s unit_tests` → **629 features passed, 0 failed** ✓ (up from ~545 before this PR)
- CI all green (coverage ≥ 97%) ✓
- Integration tests (Robot Framework) do not use `@skip` — confirmed no action needed ✓
- E2E tests (Robot Framework) do not use `@skip` — confirmed no action needed ✓
- `CHANGELOG.md` updated with entry for this change ✓
- `CONTRIBUTORS.md` — Rui Hu already listed ✓

## Issues Addressed

Closes #7025

Co-authored-by: CleverThis <hal9000@cleverthis.com>
Reviewed-on: #7221
Reviewed-by: HAL 9000 <HAL9000@cleverthis.com>
Reviewed-by: HAL9001 <hal9001@cleverthis.com>
Co-authored-by: Rui Hu <rui.hu@cleverthis.com>
Co-committed-by: Rui Hu <rui.hu@cleverthis.com>
2026-04-13 04:56:01 +00:00

172 lines
8.0 KiB
Gherkin

Feature: Plan CLI coverage boost
As a developer
I want to exercise uncovered branches in plan.py
So that code coverage is improved for the plan CLI module
# ---- _plan_spec_dict helper ----
Scenario: _plan_spec_dict returns error_message when truthy
Given a v3 Plan with error_message set to "Strategy failed"
When I call _plan_spec_dict on the plan
Then the spec dict should contain key "error_message" with value "Strategy failed"
Scenario: _plan_spec_dict falls back to legacy format for non-Plan objects
Given a non-Plan object with string value "legacy plan data"
When I call _plan_spec_dict on the object
Then the spec dict should equal {"plan": "legacy plan data"}
Scenario: _plan_spec_dict omits error_message when it is None
Given a v3 Plan with error_message set to None
When I call _plan_spec_dict on the plan
Then the spec dict should not contain key "error_message"
# ---- _print_lifecycle_plan helper ----
Scenario: _print_lifecycle_plan prints all optional timestamps
Given a v3 Plan with all timestamps populated
When I call _print_lifecycle_plan on the plan
Then the printed output should contain "Strategize Started"
And the printed output should contain "Strategize Completed"
And the printed output should contain "Execute Started"
And the printed output should contain "Execute Completed"
And the printed output should contain "Applied At"
Scenario: _print_lifecycle_plan prints estimation_actor when set
Given a v3 Plan with estimation_actor set to "local/cost-estimator"
When I call _print_lifecycle_plan on the plan
Then the printed output should contain "Estimation Actor"
And the printed output should contain "local/cost-estimator"
Scenario: _print_lifecycle_plan prints invariant_actor when set
Given a v3 Plan with invariant_actor set to "local/invariant-checker"
When I call _print_lifecycle_plan on the plan
Then the printed output should contain "Invariant Actor"
And the printed output should contain "local/invariant-checker"
Scenario: _print_lifecycle_plan falls back for non-Plan objects
Given a non-Plan object with string value "legacy-plan-object"
When I call _print_lifecycle_plan on the object
Then the printed output should contain "legacy-plan-object"
# ---- execute_plan non-rich format ----
Scenario: execute_plan outputs JSON when format is json
Given a plan lifecycle CLI runner for coverage
And a mocked lifecycle service for plan coverage commands
And the service has a complete strategize plan for execute
When I invoke execute with "--format" "json" and plan id
Then the plan coverage command should succeed
And the plan coverage output should contain "plan_id"
And the plan coverage output should contain "sandbox"
And the plan coverage output should contain "worker"
And the plan coverage output should contain "progress"
And the plan coverage output should contain "strategy_summary"
And the plan coverage output should contain "command"
And the plan coverage output should contain "exit_code"
@tdd_issue @tdd_issue_4251 @tdd_expected_fail
Scenario: execute_plan JSON output has spec-required envelope structure
Given a plan lifecycle CLI runner for coverage
And a mocked lifecycle service for plan coverage commands
And the service has a complete strategize plan for execute
When I invoke execute with "--format" "json" and plan id
Then the plan coverage command should succeed
And the execute JSON output has the spec-required envelope fields
And the execute JSON output data has sandbox with strategy field
And the execute JSON output data has progress list with label and status
# ---- apply_plan non-rich format ----
Scenario: apply_plan outputs JSON when format is json
Given a plan lifecycle CLI runner for coverage
And a mocked lifecycle service for plan coverage commands
And the service has a complete execute plan for apply
When I invoke apply with "--format" "json" and plan id
Then the plan coverage command should succeed
And the plan coverage output should contain "plan_id"
# ---- list_plans regex and state/processing_state filtering ----
Scenario: list_plans filters by regex pattern
Given a plan lifecycle CLI runner for coverage
And a mocked lifecycle service for plan coverage commands
And the service has multiple plans for lifecycle list
When I invoke list with regex "alpha"
Then the plan coverage command should succeed
And the plan coverage output should contain "alpha"
And the plan coverage output should not contain "beta"
Scenario: list_plans filters by state
Given a plan lifecycle CLI runner for coverage
And a mocked lifecycle service for plan coverage commands
And the service has plans in different processing states
When I invoke list with "--state" "processing"
Then the plan coverage command should succeed
Scenario: list_plans filters by processing_state alias
Given a plan lifecycle CLI runner for coverage
And a mocked lifecycle service for plan coverage commands
And the service has plans in different processing states
When I invoke list with "--processing-state" "complete"
Then the plan coverage command should succeed
Scenario: list_plans rejects invalid regex
Given a plan lifecycle CLI runner for coverage
And a mocked lifecycle service for plan coverage commands
And the service has multiple plans for lifecycle list
When I invoke list with regex "[invalid"
Then the plan coverage command should abort
And the plan coverage output should contain "Invalid regex"
Scenario: list_plans filters by action name
Given a plan lifecycle CLI runner for coverage
And a mocked lifecycle service for plan coverage commands
And the service has multiple plans for lifecycle list
When I invoke list with "--action" "local/test-action"
Then the plan coverage command should succeed
Scenario: list_plans outputs JSON when format is json
Given a plan lifecycle CLI runner for coverage
And a mocked lifecycle service for plan coverage commands
And the service has multiple plans for lifecycle list
When I invoke list with "--format" "json"
Then the plan coverage command should succeed
And the plan coverage output should contain "plan_id"
# ---- cancel_plan ----
Scenario: cancel_plan in non-rich format without reason
Given a plan lifecycle CLI runner for coverage
And a mocked lifecycle service for plan coverage commands
And the service can cancel a plan
When I invoke cancel with "--format" "json" and no reason
Then the plan coverage command should succeed
And the plan coverage output should contain "plan_id"
And the plan coverage output should not contain "cancel_reason"
Scenario: cancel_plan in non-rich format with reason
Given a plan lifecycle CLI runner for coverage
And a mocked lifecycle service for plan coverage commands
And the service can cancel a plan
When I invoke cancel with "--format" "json" and reason "not needed"
Then the plan coverage command should succeed
And the plan coverage output should contain "cancel_reason"
And the plan coverage output should contain "not needed"
Scenario: cancel_plan in rich format with reason
Given a plan lifecycle CLI runner for coverage
And a mocked lifecycle service for plan coverage commands
And the service can cancel a plan
When I invoke cancel in rich format with reason "obsolete"
Then the plan coverage command should succeed
And the plan coverage output should contain "Plan cancelled"
And the plan coverage output should contain "Reason: obsolete"
Scenario: cancel_plan in rich format without reason
Given a plan lifecycle CLI runner for coverage
And a mocked lifecycle service for plan coverage commands
And the service can cancel a plan
When I invoke cancel in rich format without reason
Then the plan coverage command should succeed
And the plan coverage output should contain "Plan cancelled"