MCP HubMCP Hub
스킬 목록으로 돌아가기

test-cli-application

pjt222
업데이트됨 2 days ago
17
2
17
GitHub에서 보기
테스팅testingapidesign

정보

이 스킬은 Node.js CLI 애플리케이션을 내장된 `node:test` 모듈로 통합 테스트를 작성하는 패턴을 제공합니다. 출력 검증, 파일시스템 확인, 오류 케이스 테스트, 상태 정리 등 주요 테스트 시나리오를 다룹니다. 기존 CLI에 테스트를 추가하거나, 새로운 명령어를 테스트하거나, CLI 도구의 CI 파이프라인을 설정할 때 활용하세요.

빠른 설치

Claude Code

추천
기본
npx skills add pjt222/agent-almanac -a claude-code
플러그인 명령대체
/plugin add https://github.com/pjt222/agent-almanac
Git 클론대체
git clone https://github.com/pjt222/agent-almanac.git ~/.claude/skills/test-cli-application

Claude Code에서 이 명령을 복사하여 붙여넣어 스킬을 설치하세요

문서

試 CLI 之應用

以內置 node:test 之模與 execSync 撰 Node.js CLI 之合試。

用時

  • 加試於既存之 CLI 應用乃用
  • 試新立之命乃用
  • 驗適器/插件於諸目框之行乃用
  • 立 CI 以驗 CLI 之正乃用
  • 重構 CLI 之內後捕回乃用

  • 必要:CLI 入點之路(如 cli/index.js
  • 必要:所試之命
  • 可選:所試之框適器(dry-run 模)
  • 可選:清之求(試所立之文/符鏈)

第一步:立試之基

import { describe, it, before, after } from 'node:test';
import assert from 'node:assert/strict';
import { execSync } from 'child_process';
import { existsSync, rmSync } from 'fs';
import { resolve } from 'path';

const CLI = 'node cli/index.js';
const ROOT = process.cwd();

function run(args) {
  return execSync(`${CLI} ${args}`, {
    cwd: ROOT,
    encoding: 'utf8',
    timeout: 10000,
  });
}

要設之決:

  • node:test 為內置——無須試行依
  • execSync 行 CLI 為子程——試實之二進,非內函
  • 十秒超時防於互動之掛
  • encoding: 'utf8' 給字符出為正則匹
  • 諸路相對於 ROOT 為可復

得:自 node:test 引之試文,有可行之 run() 助。

敗則:若 node:test 不可得,Node.js 之版於 18 以下。升或用墊。

第二步:撰煙試

煙試驗 CLI 啟、析參、生期之出形:

describe('meta', () => {
  it('shows version', () => {
    const out = run('--version');
    assert.match(out, /\d+\.\d+\.\d+/);
  });

  it('shows help with all commands', () => {
    const out = run('--help');
    assert.match(out, /install/);
    assert.match(out, /list/);
    assert.match(out, /detect/);
  });
});

describe('registry', () => {
  it('list shows expected counts', () => {
    const out = run('list --domains');
    assert.match(out, /\d+ domains/);
  });

  it('search finds known items', () => {
    const out = run('search "docker"');
    assert.match(out, /result\(s\) for "docker"/);
  });

  it('search returns 0 for nonsense', () => {
    const out = run('search "xyzzy-nonexistent"');
    assert.match(out, /0 result/);
  });
});

煙試之模:

  • --version--help 恆行
  • 註冊載驗資之全
  • 以已知與未知詞搜

得:煙試確 CLI 可行而資已載。

敗則:若註冊計頻變,用 \d+ 而非硬編號。

第三步:撰生命試

生命試驗 create → verify → delete 之序與清:

describe('install', () => {
  const testPath = resolve(ROOT, '.agents/skills/commit-changes');

  after(() => {
    // Always clean up, even if tests fail
    try { rmSync(testPath); } catch {}
    try { rmSync(resolve(ROOT, '.agents/skills'), { recursive: true }); } catch {}
    try { rmSync(resolve(ROOT, '.agents'), { recursive: true }); } catch {}
  });

  it('dry-run does not create files', () => {
    const out = run('install commit-changes --dry-run');
    assert.match(out, /DRY RUN/);
    assert.ok(!existsSync(testPath));
  });

  it('installs creates the target', () => {
    run('install commit-changes');
    assert.ok(existsSync(testPath));
  });

  it('skips already installed', () => {
    const out = run('install commit-changes');
    assert.match(out, /skipped/);
  });

  it('uninstall removes the target', () => {
    run('uninstall commit-changes');
    assert.ok(!existsSync(testPath));
  });
});

清之則:

  • after() 而非 afterEach()——生命試相建
  • 包清於 try/catch——清不可敗試套
  • 自葉至根清(文 → 父目 → 祖目)
  • 若試動共態(符鏈、配文),復之

得:試於 describe 內順行,敗時清亦行。

敗則:若試並行(node:test 默非),以 { concurrency: 1 } 強為序。

第四步:為各適器撰 dry-run 試

試各適器之目路而不變:

describe('adapter: cursor (dry-run)', () => {
  it('targets .cursor/skills/ path', () => {
    const out = run('install commit-changes --framework cursor --dry-run');
    assert.match(out, /\.cursor\/skills/i);
  });
});

describe('adapter: copilot (dry-run)', () => {
  it('targets .github/ path', () => {
    const out = run('install commit-changes --framework copilot --dry-run');
    assert.match(out, /\.github/i);
  });
});

此模可廣於任數適器。各試:

  • --framework 越自察
  • --dry-run 不立文
  • 斷目路現於出

得:每適器一 describe 塊,各至少有路斷。

敗則:若適器於項目不存,試敗於「Unknown framework」。此正——適器試唯為已實之適器存。

第五步:撰誤之試

describe('errors', () => {
  it('rejects unknown items', () => {
    assert.throws(
      () => run('install nonexistent-skill-xyz'),
      /No matching items|Unknown/,
    );
  });

  it('rejects unknown framework', () => {
    assert.throws(
      () => run('install commit-changes --framework nonexistent'),
      /Unknown framework/,
    );
  });

  it('handles missing state gracefully', () => {
    assert.throws(
      () => run('scatter nonexistent-team'),
      /not burning|Unknown/,
    );
  });
});

誤試之模:

  • assert.throwsexecSync 之非零出碼
  • 正則匹於誤辭(自 stderr 取)
  • 試「物未現」與「無效選項」二誤
  • 驗誤辭薦修之動

得:諸誤路生非零出碼與助辭。

敗則:execSync 於非零出投。誤之 stderrstdout 含辭。若 assert.throws 之正則不匹,察 error.stdout

第六步:撰 JSON 出之試

describe('json output', () => {
  it('campfire --json outputs valid JSON', () => {
    const out = run('campfire --json');
    const data = JSON.parse(out);
    assert.ok(typeof data.totalTeams === 'number');
    assert.ok(Array.isArray(data.fires));
  });

  it('gather --dry-run --json outputs structured data', () => {
    const out = run('gather tending --dry-run --json');
    // JSON may follow a DRY RUN header — extract from first '{'
    const jsonStart = out.indexOf('{');
    assert.ok(jsonStart >= 0, 'Should contain JSON');
    const data = JSON.parse(out.slice(jsonStart));
    assert.equal(data.team, 'tending');
  });
});

JSON 試之患:

  • 某命前綴 JSON 以人讀文(如 DRY RUN 之頭)
  • 取 JSON 由尋首 { 字符
  • 驗構(鍵存、型),非具值
  • 計等值或隨容加而變

得:JSON 之出可析而含期之鍵。

敗則:若 JSON.parse 敗,命或混人文於 JSON。或修命使 --json 模出純 JSON,或取 JSON 之子串。

第七步:治清與態復

describe('stateful commands', () => {
  const stateDir = resolve(ROOT, '.agent-almanac');

  after(() => {
    // Remove state file created by tests
    try { rmSync(stateDir, { recursive: true }); } catch {}
  });

  // Tests that create/modify state...
});

// Restore symlinks that destructive tests may remove
describe('destructive tests', () => {
  after(() => {
    // Restore symlinks that scatter/uninstall removed
    const skills = ['heal', 'meditate', 'remote-viewing'];
    for (const skill of skills) {
      const link = resolve(ROOT, `.claude/skills/${skill}`);
      if (!existsSync(link)) {
        try {
          execSync(`ln -s ../../skills/${skill} ${link}`, { cwd: ROOT });
        } catch {}
      }
    }
  });
});

態復之則:

  • 態文(.agent-almanac/state.json)試後須清
  • scatteruninstall 除之符鏈須復
  • init 立之清單文(agent-almanac.yml)須除
  • 序:after() 鉤反聲明序行——復鉤宜末聲

得:試套留項目於初狀。

敗則:若 CI 報試後留文,加清於 after()。試後用 git status 察漏態。

  • 試文以 node --test cli/test/cli.test.js
  • 諸試皆過(0 敗)
  • 煙試覆 --version--help、註冊載
  • 生命試驗 create → verify → delete 與清
  • 每實之適器至少一 dry-run 試
  • 誤例試非零出碼與辭匹
  • JSON 出試析實出(非模)
  • After 鉤復試所改之諸態

  • 硬編計而碎:註冊總隨容加而變。用 \d+ 正則或動讀計,非斷 329 skills
  • 依執序之試node:test 默以聲序行套,然套內試或不。用生命套(create → verify → delete)於單 describe 以保序。
  • 試敗時無清:若試於生命中敗,after() 仍行。然若於 before() 投,後試與 after() 或不行。before() 宜小。
  • 互動掛試:有確認提之命掛 execSync。或管 echo y | 或恆於試傳 --yes
  • CI 中以實裝試:立文於 .claude/skills/.agents/skills/ 之試動工樹。CI 或敗於「dirty working directory」之察。恆清。

  • scaffold-cli-command — 建此試所驗之命
  • build-cli-plugin — 建第四步所試之適器
  • design-cli-output — 試所斷之出模

GitHub 저장소

pjt222/agent-almanac
경로: i18n/wenyan/skills/test-cli-application
0
agentsagentskillsai-assisted-developmentclaude-codeskillsteams

연관 스킬

evaluating-llms-harness

테스팅

이 Claude Skill은 MMLU, GSM8K를 포함한 60개 이상의 표준화된 학술 과제에서 LLM 성능을 벤치마크하기 위해 lm-evaluation-harness를 실행합니다. 개발자들이 모델 품질을 비교하고, 학습 진행 상황을 추적하거나 학술 결과를 보고할 수 있도록 설계되었습니다. 이 도구는 HuggingFace와 vLLM 모델을 포함한 다양한 백엔드를 지원합니다.

스킬 보기

cloudflare-cron-triggers

테스팅

이 스킬은 cron 표현식을 사용하여 Worker를 스케줄링하기 위한 Cloudflare Cron Triggers 구현에 관한 포괄적인 지식을 제공합니다. 주기적 작업, 유지보수 작업, 자동화된 워크플로우 설정 방법을 다루며, 잘못된 cron 표현식이나 시간대 문제 같은 일반적인 이슈들을 해결하는 방법을 포함합니다. 개발자들은 이를 통해 스케줄된 핸들러 구성, cron 트리거 테스트, Workflows 및 Green Compute와의 연동 작업을 수행할 수 있습니다.

스킬 보기

webapp-testing

테스팅

이 Claude Skill은 Python 스크립트를 통해 로컬 웹 애플리케이션을 테스트하기 위한 Playwright 기반 툴킷을 제공합니다. 프론트엔드 검증, UI 디버깅, 스크린샷 캡처, 로그 확인 기능을 지원하며 서버 라이프사이클을 관리합니다. 브라우저 자동화 작업에 사용하되 컨텍스트 오염을 방지하기 위해 소스 코드를 읽지 않고 스크립트를 직접 실행하세요.

스킬 보기

finishing-a-development-branch

테스팅

이 스킬은 테스트 통과를 확인한 후 체계적인 통합 옵션을 제시하여 개발자가 완성된 작업을 마무리하도록 돕습니다. 구현이 완료된 후 머지, PR 생성, 브랜치 정리와 같은 워크플로우를 안내합니다. 코드가 준비되고 테스트가 완료되었을 때 개발 프로세스를 체계적으로 마무리하기 위해 사용하세요.

스킬 보기