$npx -y skills add larksuite/cli --skill cli-e2e-testcase-writerUse when adding or updating Go CLI E2E coverage for one tests/cli_e2e/{domain} domain of the compiled lark-cli, especially when the work requires live --help or schema exploration, scenario-based clie2e.RunCmd workflows, and per-domain coverage.md maintenance.
| 1 | # CLI E2E Testcase Writer |
| 2 | |
| 3 | Work on one domain per run. Produce exactly two artifacts for that domain: |
| 4 | - workflow testcase files under `tests/cli_e2e/{domain}/` |
| 5 | - `tests/cli_e2e/{domain}/coverage.md` |
| 6 | |
| 7 | Focus on domain testcase files. Do not change shared E2E support code such as `tests/cli_e2e/core.go` unless the user explicitly asks. Treat `tests/cli_e2e/demo/` as reference only. |
| 8 | |
| 9 | ## Core standard |
| 10 | |
| 11 | - Make the testcase scenario-based and self-contained. |
| 12 | - Prove one workflow end to end: create plus follow-up read, or mutate plus teardown. |
| 13 | - Prefer one file per workflow or one closely related feature. |
| 14 | - For mutable flows, prove persisted state with read-after-write assertions, not just exit code. |
| 15 | - Leave prerequisite-heavy paths uncovered when they cannot be proven, and explain why in `coverage.md`. |
| 16 | |
| 17 | ## Workflow |
| 18 | |
| 19 | ### 1. Explore the live CLI before writing code |
| 20 | |
| 21 | ```bash |
| 22 | lark-cli --help |
| 23 | lark-cli <domain> --help |
| 24 | lark-cli <domain> +<shortcut> -h |
| 25 | lark-cli <domain> <group> --help |
| 26 | lark-cli <domain> <group> <method> -h |
| 27 | lark-cli schema <domain>.<group>.<method> |
| 28 | ``` |
| 29 | |
| 30 | ### 2. Count leaf commands for the denominator |
| 31 | |
| 32 | - A leaf command is one that executes an action — it has no further subcommands. |
| 33 | - If `lark-cli <domain> <group> --help` lists no subcommands, `<group>` itself is the leaf. |
| 34 | - Count `task +create` as one leaf and `task tasks get` as one leaf. |
| 35 | - Do not count parameter combinations. |
| 36 | - Reuse coverage already present under `tests/cli_e2e/{domain}/`. Do not count `tests/cli_e2e/demo/`. |
| 37 | |
| 38 | ### 3. Choose the proof surface before editing |
| 39 | |
| 40 | Identify the provable risks for the touched workflow: invalid input, missing prerequisite, identity or permission, state transition, output shape, cleanup safety. If only the happy path is testable, document the blocked risk areas in `coverage.md`. |
| 41 | |
| 42 | ### 4. Add or update the workflow testcase |
| 43 | |
| 44 | - Use `clie2e.RunCmd(ctx, clie2e.Request{...})`. |
| 45 | - Put command path and plain flags in `Args`; put JSON in `Params` (URL/path parameters) and `Data` (request body). |
| 46 | - Prefer one top-level test per workflow with `t.Run` substeps. |
| 47 | - Register teardown on `parentT.Cleanup` so it survives subtest failures. |
| 48 | - When touching an existing command, verify the JSON response shape is stable: assert status type, field paths, and identifiers consumed by later steps before changing assertions. |
| 49 | |
| 50 | ### 5. Run and iterate |
| 51 | |
| 52 | Run `go test ./tests/cli_e2e/{domain} -count=1` while iterating and before finishing. If command shape or behavior is unclear, re-check help or schema (step 1) before changing assertions. |
| 53 | |
| 54 | ### 6. Refresh the domain outputs |
| 55 | |
| 56 | - Update the workflow testcase files. |
| 57 | - Update `coverage.md`: recompute the denominator from live help output, mark each command as `shortcut` or `api`, and keep one command table for the whole domain. |
| 58 | |
| 59 | ## Testcase rules |
| 60 | |
| 61 | - Override `BinaryPath`, `DefaultAs`, or `Format` on `clie2e.Request` only when the testcase truly needs it. |
| 62 | - Use `require.NoError`, `result.AssertExitCode`, `result.AssertStdoutStatus`, `assert`, and `gjson`. |
| 63 | - Shortcut responses (`{ok: bool}`) assert `true`; API responses (`{code: int}`) assert `0`. |
| 64 | - Use `t.Helper()` only for setup or assertion helpers that are called from multiple tests. |
| 65 | - Use table-driven tests only when the scenario shape repeats across inputs. |
| 66 | - For expected failures, assert stderr content and exit code when the environment makes them deterministic. |
| 67 | - If identity or external fixtures cannot be proven, leave the command uncovered and document the prerequisite rather than faking confidence. |
| 68 | |
| 69 | ## coverage.md |
| 70 | |
| 71 | Keep `coverage.md` brief and mechanical. Include: |
| 72 | - a domain-specific H1 title |
| 73 | - a metrics section with denominator, covered count, and coverage rate |
| 74 | - a summary section restating each `Test...` workflow, key `t.Run(...)` proof points, and main blockers |
| 75 | - one command table for all commands |
| 76 | |
| 77 | Recommended structure: |
| 78 | |
| 79 | ```markdown |
| 80 | # <Domain> CLI E2E Coverage |
| 81 | |
| 82 | ## Metrics |
| 83 | - Denominator: N leaf commands |
| 84 | - Covered: N |
| 85 | - Coverage: N% |
| 86 | |
| 87 | ## Summary |
| 88 | - TestXxx: ... key `t.Run(...)` proof points ... |
| 89 | - Blocked area: ... |
| 90 | |
| 91 | ## Command Table |
| 92 | | Status | Cmd | Type | Testcase | Key parameter shapes | Notes / uncovered reason | |
| 93 | | --- | --- | --- | --- | --- | --- | |
| 94 | | ✓ | task +create | shortcut | task_status_workflow_test.go::TestTask_StatusWorkflow | basic create; create with due | | |
| 95 | | ✕ | task +assign | shortcut | | none | requires real user open_id | |
| 96 | ``` |
| 97 | |
| 98 | - Mark each command `shortcut` or `api`. |
| 99 | - Write testcase entries in `go test -run` friendly form. |
| 100 | - Commands only exercised in `parentT.Cleanup` teardown are not counted as covered. |
| 101 | - Do not split covered and uncovered commands into separate se |