页面加载中...
一套贴合 ISTQB 基础级认证(CTFL)标准的手工 + 自动化测试质量保障工具集。适用于需要输出测试计划、测试策略、测试条件、测试用例、缺陷报告、缺陷日志、回归测试套件、可追溯矩阵、探索性测试章程等场景。支持基于风险的测试、各类测试设计技术(等价类划分、边界值分析、判定表、状态迁移)、测试工作量预估、静态测试评审以及全测试流程管理,同时内置基于 Playwright 开展测试落地的自动化实操指引。
Complete ISTQB Foundation Level (CTFL) aligned workflow for QA test engineers covering: Test Planning → Test Analysis → Test Design → Test Implementation → Test Execution → Test Completion
| Requirement | Notes |
|---|---|
| Node.js 18+ | Required for CLI script and Playwright |
| Playwright | npm init playwright@latest for automation |
| Text editor | For creating/editing markdown and CSV artifacts |
| Git | Recommended for testware version control |
templates/test-plan.md as a starting point.templates/test-summary-report.md.templates/test-cases.csv and fill it from the test basis (requirements, user stories, acceptance criteria).templates/bug-report.md.templates/bug-log.csv.templates/traceability-matrix.csv.templates/regression-suite.md.templates/playwright-spec.ts and adapt to the system under test.templates/exploratory-charter.md to timebox and capture outcomes.If running locally, generate artifacts with the bundled CLI:
node scripts/qa_artifacts.mjs list node scripts/qa_artifacts.mjs create test-plan --out specs --project "My App" --release "R1" node scripts/qa_artifacts.mjs create test-cases --out specs --feature "Checkout" node scripts/qa_artifacts.mjs create bug-report --out specs/bugs --title "Search returns 500"
references/test-design-techniques.md).Use: templates/test-plan.md (detailed sections + checklists).
templates/exploratory-charter.md).references/automation-playwright-best-practices.md).Use: templates/test-cases.csv.
getByTestId) over brittle selectors.@smoke, @regression) so suites are runnable via --grep.Use: templates/playwright-spec.ts and references/automation-playwright-best-practices.md.
Use: templates/regression-suite.md and references/regression-suite-strategy.md.
Use: templates/bug-report.md and references/bug-report-quality.md.
references/static-testing.md).Use: references/static-testing.md for review checklists and techniques.
references/test-estimation.md):
Use: references/test-estimation.md for techniques and formulas.
Use: references/test-monitoring-metrics.md for metrics definitions and dashboards.
| Problem | Cause | Solution |
|---|---|---|
| Test cases lack traceability | Missing requirement IDs | Add requirement_id column; link to user stories/ACs |
| Bug reports get rejected | Insufficient reproduction steps | Use minimal steps; include exact data and environment |
| Regression suite too slow | Too many tests, no prioritization | Apply risk-based selection; tier into smoke/sanity/full |
| Flaky automated tests | Unstable locators or timing | Use data-testid; avoid sleeps; use Playwright auto-waits |
| Test estimates are wrong | Scope creep, missing risks | Add contingency; re-estimate when scope changes |
| Reviews find no defects | Superficial review | Use checklists; allocate sufficient time; rotate reviewers |
| Unclear test oracles | Missing expected results | Define oracles from requirements, rules, or reference systems |
templates/)| Template | Purpose |
|---|---|
test-plan.md | ISTQB-aligned test plan structure |
test-summary-report.md | End-of-cycle summary and sign-off |
test-cases.csv | Test case repository with traceability |
test-conditions.md | Test conditions derived from test basis |
traceability-matrix.csv | Requirements ↔ tests ↔ defects mapping |
bug-report.md | Detailed defect report |
bug-log.csv | Defect tracking log |
regression-suite.md | Suite definition and selection rules |
exploratory-charter.md | Session-based exploratory testing |
playwright-spec.ts | Playwright test scaffold |
test-environment-checklist.md | Environment readiness verification |
risk-assessment-matrix.md | Quality risk identification and prioritization |
references/)| Reference | Content |
|---|---|
test-design-techniques.md | EP, BVA, decision tables, state transitions, use cases |
experience-based-techniques.md | Error guessing, checklist-based, exploratory |
static-testing.md | Reviews, walkthroughs, inspections |
test-levels-types.md | Unit, integration, system, acceptance; functional, non-functional |
test-estimation.md | Estimation techniques and factors |
test-monitoring-metrics.md | Progress tracking and quality metrics |
risk-based-testing.md | Risk identification, analysis, mitigation |
istqb-glossary.md | Key ISTQB terminology |
test-process-and-deliverables.md | Test process phases and outputs |
automation-playwright-best-practices.md | Playwright implementation guidance |
regression-suite-strategy.md | Suite management and optimization |
bug-report-quality.md | Effective defect reporting |
defect-lifecycle.md | Defect states and workflow |
scripts/)| Script | Purpose |
|---|---|
qa_artifacts.mjs | CLI tool to generate QA artifacts from templates |
Common shortcuts and "good enough" excuses that erode test quality — and the reality behind each.
| Rationalization | Reality |
|---|---|
| "ISTQB theory doesn't apply in practice" | Equivalence partitioning and boundary value analysis directly reduce test count while maintaining coverage. |
| "We don't need test plans for small projects" | Even small projects benefit from structured testing. A lightweight test plan prevents scope creep. |
| "Exploratory testing isn't real testing" | Exploratory testing finds bugs that scripted tests never will. It's a disciplined technique, not ad-hoc clicking. |
| "Risk-based testing means testing less" | It means testing smarter — focusing effort where failure impact is highest, not testing everything equally. |
| "Traceability matrices are bureaucratic overhead" | They prove coverage, support audit readiness, and reveal gaps between requirements and tests. |
| "Manual testing is obsolete" | Manual testing catches usability, visual, and accessibility issues that automation misses entirely. |
After completing this skill's workflow, confirm:
import fs from 'node:fs';
import path from 'node:path';
import process from 'node:process';
import { fileURLToPath } from 'node:url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const SKILL_ROOT = path.resolve(__dirname, '..');
const TEMPLATE_DIR = path.join(SKILL_ROOT, 'assets', 'templates');
function usage(exitCode = 0) {
const text = `
qa_artifacts.mjs - ISTQB QA Artifacts Generator
Usage:
node scripts/qa_artifacts.mjs list
node scripts/qa_artifacts.mjs create <artifact> [options]
Options:
--out <dir> Output directory (default: current directory)
--force Overwrite existing files
--project <name> Project name
--release <id> Release/version identifier
--feature <name> Feature name
--title <text> Title (for bug reports)
--owner <name> Document owner
--approvers <text> Approvers list
--env <text> Environment details
Artifacts:
test-plan ISTQB-aligned test plan document
test-summary End-of-cycle test summary report
test-cases Test cases CSV with traceability
test-conditions Test conditions derived from test basis
traceability Requirements-to-tests traceability matrix
bug-report Detailed defect report
bug-log Defect tracking log CSV
regression-suite Regression suite definition
playwright-spec Playwright test file scaffold
exploratory-charter Session-based exploratory testing charter
environment-checklist Test environment readiness checklist
risk-assessment Quality risk assessment matrix
Examples:
node scripts/qa_artifacts.mjs create test-plan --project "MyApp" --release "v1.0"
node scripts/qa_artifacts.mjs create bug-report --title "Login fails on Safari" --out ./bugs
node scripts/qa_artifacts.mjs create risk-assessment --project "MyApp" --release "v1.0"
`.trim();
// eslint-disable-next-line no-console
console.log(text);
process.exit(exitCode);
}
function parseArgs(argv) {
const args = { _: [] };
for (let i = 0; i < argv.length; i += 1) {
const value = argv[i];
if (!value.startsWith('--')) {
args._.push(value);
continue;
}
const key = value.slice(2);
if (key === 'force') {
args.force = true;
continue;
}
const next = argv[i + 1];
if (!next || next.startsWith('--')) {
throw new Error(`Missing value for --${key}`);
}
args[key] = next;
i += 1;
}
return args;
}
function nowISODate() {
return new Date().toISOString().slice(0, 10);
}
function slugify(value) {
const raw = String(value ?? '').trim().toLowerCase();
const slug = raw
.replaceAll(/[^a-z0-9]+/g, '-')
.replaceAll(/^-+|-+$/g, '')
.slice(0, 80);
return slug || 'item';
}
function ensureDir(dirPath) {
fs.mkdirSync(dirPath, { recursive: true });
}
function renderTemplate(templateText, replacements) {
let text = templateText;
for (const [key, value] of Object.entries(replacements)) {
text = text.replaceAll(`{{${key}}}`, value ?? '');
}
return text;
}
function artifactConfig(artifact, opts) {
const date = nowISODate();
const project = opts.project ?? 'Project';
const release = opts.release ?? 'Release';
const feature = opts.feature ?? 'Feature';
const title = opts.title ?? 'Bug title';
const releaseSlug = slugify(release);
const featureSlug = slugify(feature);
const titleSlug = slugify(title);
const common = {
date,
project,
release,
feature,
title,
owner: opts.owner ?? '',
approvers: opts.approvers ?? '',
reported_by: opts.reported_by ?? '',
env: opts.env ?? '',
};
switch (artifact) {
case 'test-plan':
return {
template: 'test-plan.md',
defaultName: `test-plan-${releaseSlug}.md`,
replacements: common,
};
case 'test-summary':
return {
template: 'test-summary-report.md',
defaultName: `test-summary-${releaseSlug}.md`,
replacements: common,
};
case 'test-cases':
return {
template: 'test-cases.csv',
defaultName: `test-cases-${featureSlug}.csv`,
replacements: common,
};
case 'traceability':
return {
template: 'traceability-matrix.csv',
defaultName: `traceability-${featureSlug}.csv`,
replacements: common,
};
case 'bug-report':
return {
template: 'bug-report.md',
defaultName: `bug-${date}-${titleSlug}.md`,
replacements: common,
};
case 'bug-log':
return {
template: 'bug-log.csv',
defaultName: `bug-log-${releaseSlug}.csv`,
replacements: common,
};
case 'regression-suite':
return {
template: 'regression-suite.md',
defaultName: 'regression-suite.md',
replacements: common,
};
case 'playwright-spec':
return {
template: 'playwright-spec.ts',
defaultName: `${featureSlug}.spec.ts`,
replacements: common,
};
case 'exploratory-charter':
return {
template: 'exploratory-charter.md',
defaultName: `exploratory-charter-${featureSlug}.md`,
replacements: common,
};
case 'test-conditions':
return {
template: 'test-conditions.md',
defaultName: `test-conditions-${featureSlug}.md`,
replacements: common,
};
case 'environment-checklist':
return {
template: 'test-environment-checklist.md',
defaultName: `environment-checklist-${releaseSlug}.md`,
replacements: common,
};
case 'risk-assessment':
return {
template: 'risk-assessment-matrix.md',
defaultName: `risk-assessment-${releaseSlug}.md`,
replacements: common,
};
default:
throw new Error(`Unknown artifact: ${artifact}`);
}
}
function listArtifacts() {
// eslint-disable-next-line no-console
console.log(
[
'test-plan - ISTQB-aligned test plan',
'test-summary - End-of-cycle summary report',
'test-cases - Test cases CSV',
'test-conditions - Test conditions from test basis',
'traceability - Requirements traceability matrix',
'bug-report - Detailed defect report',
'bug-log - Defect tracking log',
'regression-suite - Regression suite definition',
'playwright-spec - Playwright test scaffold',
'exploratory-charter - Exploratory testing charter',
'environment-checklist - Environment readiness checklist',
'risk-assessment - Quality risk assessment matrix',
].join('\n'),
);
}
function createArtifact(artifact, opts) {
const config = artifactConfig(artifact, opts);
const templatePath = path.join(TEMPLATE_DIR, config.template);
const outDir = path.resolve(opts.out ?? process.cwd());
const outPath = path.join(outDir, config.defaultName);
if (!fs.existsSync(templatePath)) {
throw new Error(`Template not found: ${templatePath}`);
}
if (fs.existsSync(outPath) && !opts.force) {
throw new Error(`Refusing to overwrite existing file: ${outPath} (use --force)`);
}
ensureDir(outDir);
const raw = fs.readFileSync(templatePath, 'utf8');
const rendered = renderTemplate(raw, config.replacements);
fs.writeFileSync(outPath, rendered, 'utf8');
// eslint-disable-next-line no-console
console.log(outPath);
}
function main() {
const argv = process.argv.slice(2);
if (argv.length === 0 || argv.includes('--help') || argv.includes('-h')) usage(0);
const [command, ...rest] = argv;
const args = parseArgs(rest);
if (command === 'list') {
listArtifacts();
return;
}
if (command === 'create') {
const artifact = args._[0];
if (!artifact) usage(2);
createArtifact(artifact, args);
return;
}
usage(2);
}
try {
main();
} catch (err) {
// eslint-disable-next-line no-console
console.error(err?.message ?? err);
process.exit(1);
}来源:用户上传
用户上传标准 Skill 文件夹。