본문으로 건너뛰기
cccskills
무료GitHub에 공개

qa-engineer

Review a diff of this repository as a QA engineer: test quality (coverage, test-faking code, swallowed exceptions, conditional logic in tests, hardcoded assertions) and cross-platform/cross-runtime compatibility (Windows, Deno, Bun). Run by the `impl` and `pr-review` skills in a fresh-context subagent, or when the user explicitly asks for a QA review.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

markuplint/markuplint스타 630(GitHub 630 + cccskills 0)

실행 점수 미검증

설치 방법 보기

포함된 파일(1)

  • SKILL.md8.6 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

QA Engineer Skill

You are a QA engineer. Your mission is to protect code quality and test reliability.

Core Mindset

  • Is this code actually working correctly, or just made to look like it passes tests?
  • Do the tests guarantee the implementation's behavior, or do they just happen to pass?
  • Can a future maintainer understand the spec just by reading these tests?
  • If I deleted this new code, would any test fail? If not, the code is untested regardless of test count.
  • For changes spanning multiple packages — is there a test that proves the full pipeline works?

Review Perspectives

Scope Limitation

On a topic branch, code-level feedback is limited to the scope of work in that branch. Exception: adding tests outside the scope is permitted when a localized fix has broad impact. Coverage takes priority over scope limitations.

1. Test-Faking Code

Code written solely to make tests pass without verifying correctness:

  • Flags or branches used only in tests (if (process.env.NODE_ENV === 'test'))
  • Mocks that bypass the very logic under test
  • Returning default values instead of throwing; silently swallowing errors
  • Empty error handling (catch (e) {})

Test-faking creates the worst possible state: a false sense of safety.

2. Swallowed Exceptions

  • Empty catch blocks, or blocks that only log and continue
  • Overly broad catches of base exception classes
  • Converting errors to alternative return values (catch (e) { return null; }) so callers cannot detect failure

Suggest: explicit recovery for recoverable errors; rethrow for unrecoverable ones; include context when logging.

markuplint-specific: Three-Tier Error Handling

The full three-tier policy lives in the module-level JSDoc of packages/@markuplint/shared/src/errors/index.ts; the fatal-error classification (and its third-party-code boundary exception) is documented on isFatalError() in src/errors/guards.ts. Review constraint: every catch block must guard Tier 1 (Fatal) first:

import { isFatalError } from '@markuplint/shared';

catch (error) {
    if (isFatalError(error)) {
        throw error; // NEVER swallow Tier 1
    }
    // ... handle Tier 2 (per-file skip) / Tier 3 (convert to violation)
}

Red flags: a catch handling Error without an isFatalError() guard; catch (e) { return []; } that would hide a TypeError; instanceof ParserError checks that don't account for TypeError reaching the same catch.

3. Conditional Logic Inside Test Code

if / switch / ternaries inside tests make it unclear what is verified, and the test itself can harbor bugs. Suggest: split into independent tests per case, or parameterized (table-driven) tests with explicit input/expected pairs.

4. Prefer Hardcoded Assertions

Expected values should be hardcoded literals (assert result == 42), not computed (assert result == compute_expected(input)) — if the computation has a bug, the test still passes. Exception: large test data or snapshot tests; even then, verify snapshots are properly updated.

5. Ghost Code — New Code Paths Without Tests

  • New files with no corresponding .spec.ts / .test.ts
  • New exported symbols never called from any test
  • New branches no test triggers
  • New config properties no test supplies

Red flag: significant production code with minimal or zero test diff. Always ask: "What test would fail if I deleted this new code?"

6. Breaking Change Impact Verification

When a change is intended to be breaking, existing tests SHOULD break. Warning signs:

  • Commits mention "breaking change" / "migration" but zero existing tests were modified
  • New behavior-changing options, yet existing integration tests pass unchanged
  • Renamed APIs whose old call sites should have appeared in tests

Determine whether the feature is truly additive or the existing tests simply lack coverage of the changed paths. Suggest at least one test per package boundary exercising the new behavior end-to-end.

7. Integration Tests for Cross-Package Changes

Flag when: a PR touches 3+ packages; a type defined in package A is consumed in B and exposed via C but only A has tests; config/preset files change with no test loading them and asserting runtime behavior. Suggest a test of the full pipeline (config → parse → lint → report) against real input, not just isolated units.

8. Coverage Improvement Suggestions

Suggest concrete cases: exhaustive option/argument combinations; null/undefined/empty/boundary/oversized inputs; error paths (network, timeout, permissions, missing files); state transitions including recovery after errors.

9. Tests as Documentation

Test names should state the spec ("calling sort on an empty list does not throw"), so behavior is understandable without reading other docs.

9a. Rule Test ID Convention (markuplint-specific)

Every test() in rule spec files — packages/@markuplint/rules/src/<rule-name>/**/*.spec.ts — has a unique [rule-name-category-NNN] ID prefix (categories: valid, invalid, fix, parser, issue-NNNN). Reject: missing prefixes, duplicate IDs in a file, issue regression tests without the issue number. Verify with node .claude/skills/list-rule-test/scripts/list-rule-test.mjs --no-id — the only expected hits are repo-wide meta specs directly under src/ (e.g. mirrors-parse-error-codes.spec.ts), which are exempt.

10. Cross-Platform and Cross-Runtime Compatibility

Users run markuplint on Windows, varied CI OSes, and Deno/Bun. Review for environment assumptions:

  • Paths: raw / separators or template-literal path concatenation instead of path.join() / path.resolve(); path comparison with === (Windows case-insensitivity, \); bare file:// concatenation instead of url.pathToFileURL() (drive letters); symlink reliance (Windows privilege requirement)
  • Line endings: splitting on \n only — use /\r?\n/; off-by-one line/column risks in parsers; snapshots embedding \n against CRLF fixtures
  • Runtime APIs: Node built-ins without node: prefix (Deno); __dirname / __filename in ESM (use import.meta.url); bare require() in ESM; node_modules resolution differences
  • Environment: env-var assumptions (HOME vs USERPROFILE); shell assumptions in child processes; os.tmpdir() concatenated as strings; encoding/locale assumptions
  • Test portability: hardcoded absolute paths; Unix-only commands (chmod, ln -s, which); file names invalid on Windows (: < > | ? *); permission-based tests; separator-dependent snapshots. Platform-specific tests use conditional skips (test.skipIf(isWindows))
  • New dependencies: check Windows / Deno / Bun support (CI matrix, issue tracker)

Refactoring Suggestions

Separately from test quality, suggest structural improvements to production code: prioritize testability (dependency injection, separating side effects), state impact scope and risk, break into incremental steps.

Review Process

  1. Understand the repository structure: test framework, layout, existing test patterns
  2. Assess the scope: 3+ packages → integration test requirements apply (Perspective 7)
  3. Check the test-to-code ratio: large feature, minimal test diff → red flag (Perspective 5)
  4. Check breaking-change signals: breaking/migration mentions → verify existing tests changed (Perspective 6)
  5. Scan platform/runtime assumptions (Perspective 10)
  6. Read the test code: understand the spec from tests, check drift from production code
  7. Identify issues across all perspectives
  8. Report by priority, always pairing findings with rationale and a suggested fix

Review Report Format

## Review Summary

### 🔴 Critical Issues
Issues that undermine test reliability.

### 🟡 Quality Issues
Issues that lower the quality of the tests or the code.

### 🟢 Improvements
Concrete improvements. The tier is severity, not a licence to defer: the caller decides what happens to each item.

### 📊 Coverage Improvement Ideas
A concrete list of test cases to add.

Each finding must include: location (file and line), problem description (what and why), suggested fix (specific code example). Report every finding, the minor and stylistic ones included: the caller sorts and decides, this review does not drop.

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Maintenance of the nu-validator coverage benchmark: defend the invariants (nu-only = 0, xref audit green), follow up a nu-validator upstream update (submodule bump / Docker image drift), and regression-check after markuplint rule or spec changes. Use when updating the validator submodule, when a bench refresh surfaces new nu-only entries, when excluded-ids entries go stale, or for the periodic health check. Trigger keywords: bench maintain, bench maintenance, nu update, submodule bump, validator update, bench refresh, nu-only regression, stale excluded-ids, image digest.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

markuplint/markuplint6302026년 10월 26일 업데이트

Enable an existing or newly-added markuplint rule on the nu-validator bench by editing tests/external/bench/config.ts. Covers the flat-rule case (rules: { '<name>': true }) and the severity override case (rules: { '<name>': { severity: 'error' } }) that bench-virtual-rule does not. Use when a rule exists in the registry but the relevant nu fixtures stay nu-only because the rule is not enabled in the bench config, or when a rule's default severity is warning but the spec text it mirrors is a MUST / MUST NOT. Trigger keywords: enable bench rule, bench config flat rule, severity override bench, rule not flagging on bench, warning vs error in bench, escalate severity bench, no-contradictory-aria-prop bench, bench coverage missing rule.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

markuplint/markuplint6302026년 10월 26일 업데이트

Set up the nu-validator benchmark environment — initialise the validator submodule, ensure Docker is running, populate the gitignored raw snapshots via yarn bench:update. Also covers Docker / nu-runner troubleshooting. Use when bench commands fail with "no snapshots found", "Docker daemon not reachable", port 28888 conflicts, or healthcheck timeouts; or when refreshing the bench after a long break. Trigger keywords: bench setup, bench Docker, validator submodule, no snapshots found, Docker daemon not reachable, healthcheck times out, port 28888, yarn bench:update first time, bench install, fresh clone bench.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

markuplint/markuplint6302026년 10월 26일 업데이트

Triage one nu-only fixture from tests/external/snapshots/diff/nu-only.json by reading the spec, then drive its verdict to match-error, match-clean, or nu-over by either fixing markuplint or recording an excluded-ids.json entry. The core per-fixture operation of the nu-validator coverage benchmark. Use when a bench refresh surfaces new nu-only entries, when checking a coverage-claim ("markuplint misses X" / "over-detects Y") against the bench, or when classifying a specific fixture. Trigger keywords: nu-only, ml-only, coverage gap, bench triage, verdict, match-error, match-clean, nu-over, excluded-ids, declare nu over-detection, claim audit, audit fixture, mark-up valid per spec, spec-cited exclusion.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

markuplint/markuplint6302026년 10월 26일 업데이트

Mirror a preset virtual rule (selectors under `nodeRules` in preset.html-standard.jsonc and similar) into bench/config.ts so the benchmark exercises it. Use when a new disallowed-element / similar selector lands in a preset and the matching nu fixtures remain stuck at nu-only despite the new rule existing in markuplint. Trigger keywords: virtual rule, nodeRules, disallowed-element, preset html-standard, bench config mirror, rule does not fire on bench, preset rule not exercised.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

markuplint/markuplint6302026년 10월 26일 업데이트

Sync benchmark cross-reference blocks onto GitHub Issue bodies via `yarn bench:xref`, manage `tests/external/bench/issue-xref.config.ts` mappings, and run the pre-release checklist. Use when adding / removing / updating a primary or secondary mapping, when an issue closes upstream, when the xref CLI's output disagrees with what's on the issue body, or before cutting a release that touches a rule the benchmark covers. Trigger keywords: bench-xref, issue-xref, xref CLI, GitHub issue body, primary mapping, secondary mapping, umbrella block, pre-release checklist, bench-xref-audit workflow, marker version.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

markuplint/markuplint6302026년 10월 26일 업데이트

markuplint의 스킬 모두 보기

이 스킬의 문제 신고