agentsclimarketplace

Test writing

Skill kwhorne/elyra-skills/skills/test-writing

Decide what to test, structure tests with arrange/act/assert, and avoid common pitfalls. Use when the user asks to write, add, or improve tests for existing code, or wants test coverage for a new feature.From its SKILL.md

Install
npx -y skills add kwhorne/elyra-skills --skill test-writing

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.

What its file declares

Copied from the file, not written here

The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.

SKILL.md

4.5 KB, ~1.1k tokens by cl100k_base, as published. Nobody here has run it

Test Writing

Tests exist to catch regressions and document intent. Coverage numbers are a side effect, not a goal.

When to use

  • "Write tests for this function/class/module"
  • "Add tests for the new feature"
  • "Improve test coverage in X"
  • "This isn't tested — fix that"

Procedure

1. Detect the stack

Find the existing test framework and conventions before writing anything new:

# Quick stack sniff
ls package.json composer.json pyproject.toml Cargo.toml go.mod 2>/dev/null
grep -l 'vitest\|jest\|pytest\|phpunit\|pest\|mocha\|rspec' \
  package.json composer.json pyproject.toml 2>/dev/null

Then read one existing test file to match style: file location, naming (*.test.ts vs *_test.go vs test_*.py), helpers, factories.

Always match existing conventions. A "better" test style in an inconsistent codebase is a worse test.

2. Decide what to test

For each unit under test, ask:

CategoryExamples
Happy pathTypical input → expected output
Edge casesEmpty, null, zero, one, max, boundary, off-by-one
Error pathsBad input, missing dependency, network/IO failure
BranchesEvery meaningful if / switch / match arm
InvariantsThings that must always be true (idempotency, sort order, …)

Don't test:

  • Trivial getters/setters
  • Third-party library internals
  • Generated code
  • Implementation details (private methods, internal call order)

3. Structure each test: Arrange / Act / Assert

def test_user_can_redeem_valid_coupon():
    # Arrange — set up the world
    user = make_user()
    coupon = make_coupon(code="SAVE10", percent=10)

    # Act — do the one thing
    result = redeem(user, coupon)

    # Assert — check the outcome
    assert result.discount == 10
    assert coupon.used_by == user.id

One Act per test. If you have two, it's two tests.

4. Name tests for behavior, not implementation

Test names are sentences the codebase tells you when something breaks.

  • redeem_marks_coupon_as_used_for_redeeming_user
  • it returns 404 when product does not exist
  • test_redeem_1
  • testRedeemFunction

5. Assert on observable behavior

Tests should fail when the behavior changes, not when the code structure changes.

  • ✅ "After register(), the user can log in with that email"
  • ❌ "After register(), userRepository.save was called once with {email: ...}"

The second one breaks the moment you rename a repo, even though behavior is unchanged.

6. Run and iterate

  • Run the new test → it must pass
  • Break the code under test deliberately → the test must fail (otherwise it doesn't actually test anything)
  • Run the full suite → must still pass

Common pitfalls

PitfallWhy it hurtsFix
Testing mocks instead of behaviorRefactors break tests even when behavior is preservedAssert on outputs/state, not on mock calls
Shared mutable fixturesTests pass/fail depending on orderFresh setup per test, or explicit factories
Time-dependent testsFlaky on slow CI / different timezonesInject a clock, freeze time
Hitting the network / real DBSlow + flakyIn-memory DB, recorded fixtures, contract tests
Asserting too muchBrittle to unrelated changesAssert only what the test name claims
Asserting too littleTest passes even when brokenMutation test: break the code, watch the test fail
Sleep/setTimeout in testsFlakyPoll with timeout, or use the framework's async primitives

Output format

Report:

## Tests added: <scope>

**Framework:** <pytest / vitest / phpunit / …>

**Coverage:**
- ✅ Happy path: …
- ✅ Edge cases: …
- ✅ Error paths: …

**Deliberately not covered (and why):**
- …

**How to run:**
\`\`\`
<exact command>
\`\`\`

Anti-patterns

  • ❌ Writing tests after deploying — you tested in prod, then doubled down
  • ❌ Chasing 100% coverage by testing trivia
  • ❌ One giant test that does seven things
  • ❌ Tests that pass without an assertion (yes, this happens)
  • ❌ Skipped/commented-out tests left in the codebase

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 326,782. 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.