Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Execute multi-level exploratory testing of the app covering basic functionality, complex operations, adversarial testing, and cross-cutting scenarios, plus usability observations through a UX lens reported separately from defects. Deeper than /smoke-test. Use when the user asks to "exploratory test", "test thoroughly", "test all scenarios", "deep test", "test edge cases", "test everything", "break it", "find bugs by testing", "test usability", or "check the UX while testing".
.claude/skills/tobihagemann-exploratory-test/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-09 | ✗→✓ | ▲ Improved | 79% | 0% |
| case-10 | ✗→✓ | ▲ Improved | 43% | 0% |
| case-12 | ✗→✓ | ▲ Improved | 88% | 0% |
| case-13 | ✗→✓ | ▲ Improved | 89% | 0% |
| case-16 | ✗→✓ | ▲ Improved | 35% | 0% |
Execute multi-level exploratory testing that goes beyond smoke testing to actively find bugs through escalating test scenarios.
At the start, use update_plan to track each step, restating any remaining steps of a parent workflow alongside them:
$user-experience skill (when user-facing)Resolve the test plan using these rules in order:
.turbo/test-plans/<slug>.md.turbo/test-plans/<that-slug>.md when that file exists.turbo/test-plans/*.md. If exactly one file exists, use it.turbo/test-plan.md if .turbo/test-plans/ does not exist$create-test-plan skill first, then use the plan it writesIf multiple test plans exist and the most-recent choice is non-obvious, use request_user_input to let the user pick from the candidates.
Read the resolved test plan and state its path.
Unless an explicit path or slug was passed, confirm the resolved plan still describes the work under test:
When a signal fires, output the signal and the scenarios it affects as text. For a superseded Context, name the scenarios that exercise the reversed or removed work. Then use request_user_input to offer:
$create-test-plan skill with the resolved path, and use the plan it writesIf the user specifies a narrower scope, filter the plan to relevant scenarios rather than executing all of them. Reserve filtering for that case: a superseded plan keeps scenarios that each look plausible alone, so trimming it preserves the wrong ones.
Use the approach specified in the test plan. If the plan does not specify one, determine it using the same logic as $create-test-plan Step 2.
$user-experience Skill (When User-Facing)If the app has a user-facing surface (UI, screens, commands, messages, or any behavior a user sees or does), run the $user-experience skill to load the UX lens before executing tests, so usability concerns surface while interacting with the app. When it is unclear whether the surface is user-facing, use request_user_input to ask rather than skipping silently. Skip this step for test targets with no user-facing behavior (internal library or infrastructure).
Work through each level sequentially. Complete all tests in a level before moving to the next.
When a scenario's preconditions need privileged state or a second participant (an entitlement or plan tier, an elevated role, seed data, a second concurrent client or session), provision it through a path the project already exposes for development and run the scenario. Record PARTIAL only after an attempt to provision failed, naming the precondition that could not be provisioned and what was tried.
When the scenario's output is consumed by another system, withhold PASS until that system accepts it. Decoding a token, reading a response body, or confirming a row exists shows only that the artifact was produced. Stand up the consumer under the same isolation and cleanup rules as any other service this run starts, and exercise its own flow. When standing it up is not possible, record PARTIAL and name which half is unproven. PARTIAL counts as not passed everywhere a verdict is tallied or gated.
request_user_input to ask whether to continue. Basic failures may indicate the feature is too broken for deeper testing.If a project-specific testing skill or MCP tool was identified in Step 2, use that. The paths below are fallbacks.
Reuse a running dev server only when this session started it. Otherwise start one on a port this run selected and wait for it to be ready. Confirm it bound to that port before sending it traffic — a failed bind leaves another agent's service answering. Move to another port when the port is taken; report the error and stop when the server itself failed to start. Use the browser-use@openai-bundled plugin to interact with the app.
Launch the app. Use the computer-use@openai-bundled plugin to interact with the UI.
Run commands directly.
Present results organized by level:
Exploratory Test Results:
## Level 1: Basic Functionality (X/Y passed)
- [PASS] Test name: description
- [FAIL] Test name: description — [what went wrong]
- [PARTIAL] Test name: description — [which half is unproven]
## Level 2: Complex Operations (X/Y passed)
- [PASS] Test name: description
- [FAIL] Test name: description — [what went wrong]
- [PARTIAL] Test name: description — [which half is unproven]
## Level 3: Adversarial Testing (X/Y passed)
- [PASS] Test name: description
- [FAIL] Test name: description — [what went wrong]
- [PARTIAL] Test name: description — [which half is unproven]
## Level 4: Cross-Cutting Scenarios (X/Y passed)
- [PASS] Test name: description
- [FAIL] Test name: description — [what went wrong]
- [PARTIAL] Test name: description — [which half is unproven]
Overall: X/Y passed across all levelsReport usability observations from the UX lens below the level results, separately from the defects. A scenario can pass every functional check and still surface a usability concern.
## Usability Observations
- [UX] <observation> — names the UX context it touches (Understanding, Bridging, or Flowing) and the goal mismatch or friction it createsFor each failure, include the relevant screenshot, output, or state observation.
When the change under test spans several repositories, add a per-repo view of the findings below the usability observations, naming a suggested fix site for each.
Update the resolved test plan file by checking off completed tests and annotating results.
Then call update_plan to mark this step completed and continue with the next step of the active workflow.
tmux -L <name>), give each browser session a unique name so cleanup can target only its own, and write screenshots and other scratch state to absolute paths under a unique scratch directory outside the repository under test. Derive each such identifier once and reuse that exact value in every later command, writing it as a literal or reading it back from a note under the run's scratch directory. A value recomputed per shell, such as $$, differs between the command that creates a resource and the command that releases it, so cleanup releases something it never created and reports success while the real resource leaks. A port picked as unique may already be held by a concurrent agent, so check it before binding and move to another when it is taken, leaving the incumbent running.$investigate skill on the test report.| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 28,564 | 29,118 | +2% | 1 | 1 | 0% | 4,553 | 2,698 | -41% | 0 | 0 | — |
case-02 | fail→fail | 4,743 | 7,030 | +48% | 1 | 1 | 0% | 297 | 2,676 | +801% | 0 | 0 | — |
case-03 | pass→fail | 43,856 | 7,743 | -82% | 1 | 1 | 0% | 7,402 | 2,619 | -65% | 0 | 0 | — |
case-04 | fail→fail | 24,129 | 31,784 | +32% | 1 | 1 | 0% | 2,282 | 2,821 | +24% | 0 | 0 | — |
case-05 | fail→fail | 19,852 | 13,874 | -30% | 1 | 1 | 0% | 170 | 3,063 | +1702% | 0 | 0 | — |
case-06 | fail→fail | 5,060 | 9,712 | +92% | 1 | 1 | 0% | 300 | 2,755 | +818% | 0 | 0 | — |
case-07 | pass→pass | 4,961 | 3,130 | -37% | 1 | 1 | 0% | 772 | 2,758 | +257% | 0 | 0 | — |
case-08 | fail→fail | 6,086 | 3,518 | -42% | 1 | 1 | 0% | 933 | 2,783 | +198% | 0 | 0 | — |
case-09 | fail→pass | 10,530 | 5,010 | -52% | 1 | 1 | 0% | 1,676 | 3,007 | +79% | 0 | 0 | — |
case-10 | fail→pass | 12,465 | 2,154 | -83% | 1 | 1 | 0% | 1,826 | 2,606 | +43% | 0 | 0 | — |
case-11 | fail→fail | 13,857 | 14,078 | +2% | 1 | 1 | 0% | 2,118 | 3,341 | +58% | 0 | 0 | — |
case-12 | fail→pass | 24,466 | 3,645 | -85% | 1 | 1 | 0% | 1,468 | 2,757 | +88% | 0 | 0 | — |
case-13 | fail→pass | 9,566 | 3,232 | -66% | 1 | 1 | 0% | 1,409 | 2,658 | +89% | 0 | 0 | — |
case-14 | pass→pass | 56,970 | 3,876 | -93% | 1 | 1 | 0% | 1,727 | 2,817 | +63% | 0 | 0 | — |
case-15 | fail→fail | 9,371 | 3,356 | -64% | 1 | 1 | 0% | 1,555 | 2,787 | +79% | 0 | 0 | — |
case-16 | fail→pass | 15,162 | 7,261 | -52% | 1 | 1 | 0% | 2,492 | 3,366 | +35% | 0 | 0 | — |
case-17 | pass→pass | 12,700 | 3,324 | -74% | 1 | 1 | 0% | 1,915 | 2,697 | +41% | 0 | 0 | — |
case-18 | fail→pass | 6,242 | 2,998 | -52% | 1 | 1 | 0% | 942 | 2,678 | +184% | 0 | 0 | — |
case-19 | fail→pass | 14,197 | 3,728 | -74% | 1 | 1 | 0% | 2,351 | 2,753 | +17% | 0 | 0 | — |
case-20 | fail→pass | 14,931 | 15,780 | +6% | 1 | 1 | 0% | 2,317 | 4,193 | +81% | 0 | 0 | — |
case-21 | fail→fail | 13,094 | 8,061 | -38% | 1 | 1 | 0% | 1,908 | 3,190 | +67% | 0 | 0 | — |
case-22 | pass→pass | 17,580 | 4,760 | -73% | 1 | 1 | 0% | 2,281 | 3,028 | +33% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 15 counted toward the lift figure. The other 7 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +32 percentage points is the difference between those two pass rates over the 15 comparable cases. 3 cases got worse with the skill loaded, and they are included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
| Model | Method | Date | Lift |
|---|---|---|---|
| gemini-3.6-flash | verified | 8/21/2026 | +39% |
Other measured skills in the registry, with their headline benchmark lift.