agentsclimarketplace

Component test writer

Skill mytechsonamy/VibeFlow/skills/component-test-writer

Generates component-level unit tests from source files and (optionally) a scenario-set.md. Framework-aware (vitest | jest) via repo-fingerprint, never guesses. Enforces strict Arrange-Act-Assert structure, preserves every scenario as a test case, and refuses to overwrite existing tests. PIPELINE-1 step 4.From its SKILL.md

Install
npx -y skills add mytechsonamy/VibeFlow --skill component-test-writer

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

8.2 KB, as published. Nobody here has run it

Component Test Writer

Phase Contract

This skill runs in DEVELOPMENT or TESTING only. Before any other step, read vibeflow.config.json's currentPhase. If it is not in {DEVELOPMENT, TESTING}, emit:

component-test-writer is for DEVELOPMENT or TESTING phase; current is <phase>. Run /vibeflow:test-strategy-planner (PLANNING) first and /vibeflow:advance into DEVELOPMENT before writing tests.

…and stop. The PreToolUse phase-write-guard hook will also reject any test-file writes this skill attempts outside those phases.

An L1 Truth-Validation skill. Takes a source file (or a small set of files) and produces test files whose structure the reader can audit in fifteen seconds. This skill does not run tests — it only generates them.

When You're Invoked

  • During PIPELINE-1 step 4 after test-strategy-planner has produced a scenario-set.md. In that pipeline, this skill runs once per component in parallel with contract-test-writer, business-rule-validator, and test-data-manager.
  • On demand as /vibeflow:component-test-writer <path-or-glob>.

Input Contract

InputRequiredNotes
Source file(s)yesPath, glob, or directory. Non-test files only.
scenario-set.mdoptional but preferredOutput of test-strategy-planner; maps scenarios → test cases.
Framework configderivedRead from repo-fingerprint.json or detected via ci_analyze_structure. Never hardcoded.
Existing testsscannedEvery existing test file is read before writing a new one so we do not clobber human work.

Hard preconditions — refuse to run with a single blocks-merge finding rather than producing garbage:

  1. The source file(s) must exist and parse as the detected language.
  2. The framework must be known. If detection returns 0 runners, fail with remediation: "run /vibeflow:repo-fingerprint first, or add a vitest/jest config file to the repo root."
  3. A test file that already exists and was NOT previously generated by this skill is treated as sealed — we add cases by appending to it, never by rewriting the whole file.

Algorithm

Step 1 — Discover the framework

Order matters:

  1. Read .vibeflow/artifacts/repo-fingerprint.json if present.
  2. Otherwise call ci_analyze_structure on the codebase-intel MCP.
  3. Otherwise look for a vitest.config.* or jest.config.* file in the project root.
  4. Otherwise fail (see preconditions).

Record the chosen framework + the evidence path so the report can cite it. framework-recipes.md maps the detected framework to its import syntax, hook shape, and assertion library.

Step 2 — Read and classify the source

For each input source file, enumerate:

  • Exports (named functions, default class, constants)
  • Public API (what a caller could reasonably import and use)
  • Side effects (I/O, network, clock, RNG, globals)
  • Dependencies (imports that may need mocking)

Refuse to generate tests for files that have no exports or that only re-export — the right place for those is an integration test, not a component test.

Step 3 — Map scenarios to cases

If scenario-set.md exists, every scenario whose "target component" field matches the current source file becomes a candidate test case. A scenario becomes a test case only when:

  1. The scenario has a measurable expected outcome (an assertion the test can make).
  2. The scenario's inputs can be constructed from data already in fixtures OR can be generated by test-data-manager in a follow-up step. If not, mark the case as pending: "awaiting test-data" and emit it with it.skip — never invent fixture values.
  3. The scenario is not already covered by an existing test (simple substring match on the scenario id in the test file).

If scenario-set.md is absent, derive cases from the public API:

  • one happy path per exported function
  • one boundary case per numeric / string-length / array-length argument
  • one failure case per declared thrown error class
  • one concurrency case if the source uses async + shared state

Step 4 — Enforce Arrange-Act-Assert

Every generated it(...) block must have three comment-delimited sections in this exact order:

it("returns the zero value when the list is empty", () => {
  // Arrange
  const input: number[] = [];

  // Act
  const result = sumList(input);

  // Assert
  expect(result).toBe(0);
});

Rules:

  • Arrange MUST NOT call the system under test.
  • Act is exactly one line. If setup bleeds into Act, extract a helper.
  • Assert MUST NOT call the system under test — only check its output.
  • No bare expect.assertions(n) hacks to paper over async awaits.

See references/test-patterns.md for parametrized, table-driven, and mock-heavy variants; never deviate from the three-section shape.

Step 5 — Scenario traceability

Every generated it(...) title must start with the scenario id when one exists, e.g. it("SC-017: returns the zero value when the list is empty", ...). The it body ends with an explainability comment:

// trace: scenarios/SC-017 — "empty list aggregation"
// why: guards against a regression from PRD#3.2 (aggregation pipeline)

When the skill's output is later consumed by traceability-engine, the trace: line is the only thing the engine needs to wire the test back to the scenario and the PRD.

Step 6 — Write the test file

Target path convention: for source src/foo/bar.ts, write to src/foo/bar.test.ts (sibling-with-.test). If a project already uses a different layout (e.g. tests/ mirror), preserve that layout — check a few existing tests to decide.

Every generated file starts with a banner:

// @generated-by vibeflow:component-test-writer
// Regenerate with: /vibeflow:component-test-writer <source path>
// Do NOT edit the @generated regions by hand — they will be overwritten.

Regions between // @generated-start and // @generated-end markers are owned by the skill. Anything outside those markers is human-owned and will be preserved verbatim on re-run. This is how we keep regenerating tests safely.

Step 7 — Emit a run report

Append a summary to .vibeflow/reports/component-test-writer.md:

# Component Test Writer — <ISO timestamp>

## Target(s)
- src/foo/bar.ts (framework: vitest)

## Test file(s)
- src/foo/bar.test.ts (created | appended | no-op)

## Cases generated
- SC-017: returns the zero value when the list is empty → it(...)
- SC-018: sums a non-empty list                         → it(...)
- SC-019: rejects non-numeric input                     → it.skip (awaiting test-data)

## Scenarios skipped with reason
- SC-020 (target mismatch: scenario is for src/foo/baz.ts)

## Framework evidence
- repo-fingerprint.json (primary)

Output Contract

Every emitted test file:

  • has the @generated-by banner
  • wraps the skill-owned region with @generated-start / @generated-end
  • uses only the detected framework's imports (no mixing)
  • is runnable with zero edits (no TODO-comments blocking the build)
  • preserves pre-existing cases verbatim

Explainability contract applies to the run report, not to individual it blocks: each report entry records finding / why / impact / confidence for decisions the skill made (e.g. skipping a scenario, choosing an unusual mock strategy).

Non-Goals

  • Does NOT generate integration tests — that's contract-test-writer (for API contracts) or e2e-test-writer (Sprint 3).
  • Does NOT generate fixtures or factories — that's test-data-manager.
  • Does NOT run the generated tests — wire them into CI yourself.

Downstream Dependencies

  • traceability-engine — consumes the trace: lines to keep the RTM current
  • test-priority-engine — uses the generated file list to rank affected tests
  • mutation-test-runner — runs mutations against the generated assertions

Keep looking

Skills are one crate of 627,801. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.