Communitygithub.com

beraki/my-code-factory-skills

UI 동작을 테스트하는 동안 화면을 녹화하여 시각적 증거를 기록합니다. 에이전트가 컴퓨터 사용을 통해 앱을 직접 테스트하고, 구조화된 테스트/어설션 주석이 포함된 화면 녹화로 세션을 캡처한 후, PR과 트래커 이슈에 비디오와 결과 요약을 게시합니다. 주장 대신 변경 사항이 실제로 작동한다는 검증 가능한 증거가 필요할 때마다 사용합니다.

my-code-factory-skills란 무엇인가요?

이 스킬은 UI 동작 테스트에 대한 시각적 증거를 자동으로 생성하고 기록하는 Evidence-Driven Testing(증거 기반 테스트) 도구입니다. 개발자나 AI 에이전트가 컴퓨터 사용(computer use)을 통해 앱을 직접 조작하며 테스트하는 과정을 FFmpeg 기반으로 녹화하고, `setup`, `test_start`, `assertion` 등의 주석을 타임스탬프와 함께 비디오에 오버레이합니다. 지원 플랫폼은 Linux(X11, Wayland), macOS, Windows입니다. GUI가 없는 헤드리스 환경에서는 Playwright나 스크립트 기반 캡처로 대체하며, API/성능 변경에도 측정값과 출력 페어를 캡처하도록 요구합니다. 녹화가 완료되면 `evidence.mp4`, `report.md`, `manifest.json`을 생성하고, PR 코멘트와 트래커 이슈에 증거를 게시하는 워크플로우를 제공합니다. crash-safe한 MPEG-TS(raw.ts) 캡처, pidfd 기반 안전한 시그널링, `cua-driver`를 통한 대체 입력 방식 등이 특징입니다. 최종 목표는 '주장하지 말고 증명하라'는 원칙 아래 모든 변경 사항에 재현 가능한 시각적 증거를 첨부하는 것입니다.

지원 대상✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/beraki/my-code-factory-skills/tree/HEAD/evidence-driven-testing

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

증거 기반 테스트(Evidence-Driven Testing)

동작에 대한 주석이 포함된 증거를 기록한 다음, 이를 PR과 트래커 이슈에 첨부하세요.

녹화는 컴퓨터 사용(computer use)을 통해 앱을 테스트하는 과정을 캡처한 것입니다: 레코더를 시작한 다음, 각 테스트 대상을 직접 앱을 조작(클릭, 타이핑, 탐색)하며 테스트하세요. 비디오의 모든 동작은 실제로 수행된 테스트입니다. 대화형 세션이 표시되지 않으면 녹화는 증거로서 가치가 없습니다. 컴퓨터 사용 도구가 없지만 GUI가 존재하는 경우, 대신 cua-driver를 사용하여 앱을 조작하세요(아래 참조). 그래도 여전히 실시간 세션입니다.

번들로 제공되는 레코더 scripts/evidence.py는 Linux, macOS, Windows에서 FFmpeg로 디스플레이를 캡처하고, 테스트 중 추가하는 각 주석에 타임스탬프를 부여하며, 정지 시 주석을 비디오에 굽고 ffprobe로 결과를 검증합니다. 세션 폴더에 evidence.mp4, report.md, manifest.json을 기록합니다.

입력

  • 테스트 대상(필수): 검증할 동작/흐름. 테스트 가능한 명제로 표현합니다.
  • PR / 이슈(선택): 증거를 게시할 위치. 생략하면 요청자에게만 전달합니다.

레코더

아래 EVIDENCE는 이 스킬 폴더 내 scripts/evidence.py의 경로입니다(스킬이 설치된 위치, 예: ~/.claude/skills/evidence-driven-testing/scripts/evidence.py). Python 3와 FFmpeg만 있으면 됩니다.

  • 먼저 확인: python3 $EVIDENCE doctor — ffmpeg, ffprobe, libx264, ass 필터(ready)를 검증하고, 이 머신에서 작동하는 화면 캡처 소스(capture_ready 및 소스 auto가 선택)를 확인합니다. 도구 체인이 없을 때만 0이 아닌 종료 코드를 반환합니다. 녹화 전에 capture_ready를 읽으세요.

  • 플랫폼(--source auto는 사용 가능한 첫 번째 소스를 선택):

    OS소스필요 사항
    Linux X11 / XWaylandx11 (x11grab)DISPLAY 설정
    Linux Waylandwayland (wf-recorder)WAYLAND_DISPLAY 설정, wf-recorder가 PATH에 있고, wlr-screencopy를 지원하는 합성기가 확인됨 — 알려진 wlroots 기반(Sway, Hyprland, river, Wayfire, labwc, dwl, niri)이거나 wayland-info로 확인. GNOME 및 KDE Wayland는 이 방법으로 캡처 불가능; doctor가 알려줍니다. X11 앱은 XWayland를 통해 x11을 사용하거나, 대체 레코더를 사용하세요. --source wayland는 여전히 강제 적용합니다
    macOSavfoundation터미널/에이전트 호스트 앱에 화면 녹화 권한 부여; doctor가 --screen-index용 화면 인덱스를 나열합니다
    Windowsgdigrab표준 ffmpeg 빌드; 프로세스 확인용 powershell

    기본적으로 전체 화면을 캡처합니다. --geometry WxH와 --offset X,Y로 x11, wayland, gdigrab에서 영역을 자를 수 있습니다. XWayland는 X11 창만 볼 수 있으므로, 테스트 대상 앱이 Wayland 네이티브라면 wayland 소스를 선호하세요.

  • 충돌 안전 원시 캡처: 원시 녹화는 MPEG-TS(raw.ts)이므로, 레코더가 강제 종료되거나 충돌해도 캡처된 내용은 프로브 및 렌더링이 가능합니다. stop은 이를 표준 evidence.mp4로 리먹싱하거나 재인코딩합니다.

  • 정지 작동 방식: Linux에서 레코더는 pidfd를 통해 신호를 받습니다. macOS와 Windows에서 start는 ffmpeg 자식 프로세스를 소유하는 작은 감독자 프로세스를 시작하고, stop은 (세션 폴더의 stop.request를 통해) 감독자에게 인터럽트, 종료, 강제 종료를 요청합니다. 완료되면 recorder-exit.json을 기록합니다. 절대 원시 PID에 신호를 보내지 않으므로 재활용된 PID를 건드릴 일이 없습니다. 레코더가 아직 실행 중인데 감독자가 죽으면, stop은 거부하고 직접 중지해야 할 PID를 알려줍니다. 감독자가 시작한 프로세스를 기록하기 전에 죽었다면, stop은 직접 떠돌이 레코더를 확인하고 --accept-untracked-recorder로 다시 실행할 때까지 차단됩니다. 그러면 보고서에 그 주의사항이 포함됩니다.

  • 대체 레코더(doctor가 캡처 소스가 없다고 보고할 때(예: wf-recorder 없는 Wayland): cua-driver recording start <dir> / stop (cua-driver 섹션 참조) 또는 OS 레코더(macOS: screencapture -v out.mov). 이 경로에는 주석 오버레이가 없으므로, 파일로 주석 프로토콜을 유지하세요. 각 setup / test_start / assertion과 그 결과 및 대략적인 비디오 타임스탬프를 나열한 assertions.md 파일입니다. 헤드리스 경로와 정확히 같습니다.

  • 절대 --source test(합성 패턴 생성기)를 UI 증거로 제시하지 마세요. 이는 도구 체인을 스모크 테스트하기 위한 것입니다. 저장소의 tests/test_evidence.py가 이를 실행합니다.

지침

1. 화면 준비

  • 브라우저/앱 창을 최대화하세요. 팝업, 알림 및 추가 패널을 닫습니다.
  • 녹화 전에 시작 상태(로그인, 올바른 페이지)로 이동하세요. 설정 자체가 테스트 대상인 경우는 예외입니다.
  • 테스트 중인 정확한 리비전을 기록하세요: git rev-parse HEAD 및 git branch --show-current(또는 배포 URL). 레코더가 이를 보고서에 기록합니다.

2. 녹화 시작

  • 첫 번째 의미 있는 동작 전에 화면 녹화를 시작하세요:

    python3 $EVIDENCE start \
      --output .artifacts/<task-name> \
      --title "<검증할 내용>" \
      --commit "$(git rev-parse HEAD)" --branch "$(git branch --show-current)" \
      --environment "<OS / 브라우저 / 디스플레이 / 배포>"
    

    session 경로와 선택된 source가 포함된 JSON을 출력합니다. 모든 후속 명령을 위해 경로를 유지하세요(SESSION=...). 소스는 자동 감지되며 전체 화면이 캡처됩니다. doctor나 상황이 요구할 때만 --source, --geometry, --offset, --display/--xauthority(X11), --screen-index(macOS), --output-name(Wayland)을 전달하세요.

  • 시작 컨텍스트를 설명하는 setup 주석을 추가하세요:

    python3 $EVIDENCE annotate "$SESSION" --type setup \
      --message "로그인 상태, 커넥터 페이지로 이동 중"
    

3. 컴퓨터 사용을 통해 테스트하고, 진행하면서 주석 추가

  • 라이브 앱에서 컴퓨터 사용을 통해 모든 상호작용을 수행하세요. 녹화가 당신의 세션을 캡처하므로 테스트와 증거는 동일한 행위입니다. 시청 가능한 속도로 작업하세요. 각 동작 후 UI가 안정될 때까지 기다려 상태 변경이 비디오에서 보이도록 하세요.

  • 각 명명된 테스트 시작 시, Jest 스타일로 test_start 주석을 추가하세요:

    python3 $EVIDENCE annotate "$SESSION" --type test_start \
      --message "권한이 'always'일 때 도구를 직접 실행해야 함"
    
  • 각 확인 후, --result passed, failed 또는 untested와 함께 assertion 주석을 추가하세요:

    python3 $EVIDENCE annotate "$SESSION" --type assertion --result passed \
      --message "권한 프롬프트 없이 도구가 실행됨"
    
  • 어설션 규칙:

    • 의미 있는 상태 변경당 하나의 어설션 — 통합하고, UI 레이블마다 주석을 달지 마세요.
    • 시작 상태를 설정하려면 "Precondition: ..." 어설션을 사용하세요.
    • 80자 미만, 높은 신호 유지(레코더가 더 긴 메시지를 거부합니다).
    • 테스트를 실행할 수 없는 경우(전제 조건 누락, 인증 창 만료), 이유와 함께 untested로 표시하세요. 절대 조용히 건너뛰지 마세요.
    • 타임스탬프는 어설션한 시점을 기록하며, 그것이 참인지 여부는 기록하지 않습니다. passed를 선택하기 전에 화면을 확인하세요.

4. 중지 및 검토

  • 최종 어설션 후 녹화를 중지하세요:

    python3 $EVIDENCE stop "$SESSION"
    

    이렇게 하면 캡처가 중단되고(우아하게, 레코더가 플러시되도록 하고, 요청을 무시하는 경우에만 에스컬레이션), 주석이 evidence.mp4에 구워지고, 결과를 프로브하며, 그 옆에 report.md와 manifest.json을 기록합니다. 성공 시 "verified": true를 출력합니다. 렌더링이 실패하면 세션은 finalization_failed로 표시됩니다. 보고된 원인을 수정하고 stop을 다시 실행하세요(재시도는 레코더에 두 번 신호를 보내지 않습니다). 레코더 프로세스에 더 이상 안전하게 신호를 보낼 수 없는 경우(죽었거나, PID가 이제 다른 프로세스에 속함), 세션은 recorder_lost로 표시됩니다. stop을 다시 실행하면 캡처된 모든 비디오가 최종 처리되지만, 해당 레코더 프로세스가 확실히 사라진 경우에만 가능합니다. 여전히 살아 있다면 먼저 중지하세요. 그렇지 않으면 비디오가 쓰여지는 동안 렌더링됩니다.

  • 공유 전에 녹화가 주요 순간을 캡처했는지 확인하세요: 각 어설션 타임스탬프에서 프레임을 추출하고(ffmpeg -ss <t> -i evidence.mp4 -frames:v 1 frame.png), 상태와 레이블이 보이는지 확인하세요.

  • report.md의 Caveats(주의사항) 섹션을 채우세요. 절대 플레이스홀더를 남기지 마세요.

5. 증거 게시

  • report.md가 보고서입니다: 테스트한 내용, 환경 + 정확한 커밋, 테스트별 통과/실패, 주의사항. 처음부터 다시 작성하지 말고 확장하세요.
  • 비디오 + 요약을 PR 댓글로 게시하세요(자신의 PR인 경우 PR 설명에 포함). gh pr comment는 로컬 비디오를 첨부할 수 없습니다. 인증된 브라우저에서 PR의 댓글 상자를 통해 evidence.mp4를 업로드하거나, 호스트에 업로드하여 링크하세요(예: before-and-after 업로드 어댑터). 댓글을 다시 열고 비디오가 재생되는지 확인한 후 게시했다고 주장하세요.
  • 동일한 비디오를 한 줄 결과와 함께 트래커 이슈(Linear/Jira)에 첨부하세요.
  • 보고서 + 녹화를 요청자에게 보내세요.

가드레일

  • 비디오는 실제 테스트 세션이 라이브로 진행되는 모습을 보여야 합니다. 스크립트 재생, 이어 붙인 클립 또는 합성 영상을 녹화로 제시하지 마세요. 컴퓨터 사용 도구가 없지만 GUI가 존재하는 경우 cua-driver를 통해 조작하세요. GUI가 전혀 없으면 대신 헤드리스 경로를 사용하세요.
  • 반만 덮이거나 타일링된 창을 녹화하지 마세요. 먼저 최대화하세요.
  • 비밀, 토큰, 고객 데이터 또는 결제 세부 정보가 표시된 화면을 녹화하지 마세요. 흐름에 필요하면 untested로 표시하고 이유를 말하세요.
  • 수정 사항을 확인할 때는 이전 실패와 새로운 성공을 함께 보여주거나 참조하세요.
  • 항상 테스트한 정확한 커밋/브랜치/배포를 명시하세요.

컴퓨터 사용 도구가 없나요? cua-driver로 조작하세요(GUI 사용 가능)

디스플레이는 있지만 에이전트에 내장된 컴퓨터 사용 기능이 없는 경우, cua-driver(macOS / Windows / Linux)를 액추에이터로 사용하세요. 여전히 앱을 라이브로 테스트하는 것입니다. 녹화 규칙은 변경되지 않습니다. 입력 메커니즘만 다릅니다.

  • 녹화 전에 cua-driver doctor로 설정을 확인하세요. cua-driver 스킬이 설치된 경우, 이를 읽고 프로토콜을 따르세요. 동작 전 스냅샷 불변 규칙은 필수입니다.
  • 상호작용당 루프: launch_app → get_window_state(접근성 트리 + 스크린샷) → element_token을 통한 동작(click, type_text, press_key) → 예상 사후 조건에 대한 verify_state. 각 verify_state 확인은 assertion 주석에 1:1로 매핑됩니다.
  • doctor가 capture_ready: yes를 보고하는 경우, 비디오 및 주석을 위해 위의 번들 레코더를 계속 사용하세요. cua-driver는 입력만 제공합니다.
  • 그렇지 않은 경우, cua-driver recording start <output-dir> / cua-driver recording stop이 레코더입니다(출력 디렉토리는 필수이며, 데몬이 실행 중이어야 합니다: cua-driver serve). 비디오 캡처는 기본적으로 켜져 있으며, 정지 시 <output-dir>/recording.mp4로 최종 처리됩니다. 그러나 Windows/Linux에서는 ffmpeg를 외부 호출하므로, ffmpeg가 없거나 디스플레이가 없으면 회차별 궤적 폴더(전후 스크린샷, action.json, click.png)만 생성되고 비디오는 없습니다. 중지 후 recording.mp4가 존재하는지 확인한 후 인용하세요. 없으면 레코더를 수정하거나 헤드리스 프로토콜에 따라 회차별 전후 스크린샷을 번호가 매겨진 캡처로 제시하세요.
  • 이 경로에서 주석 오버레이를 사용할 수 없는 경우, 파일로 프로토콜을 유지하세요. 각 test_start / assertion과 그 결과를 나열한 assertions.md 파일입니다. 헤드리스 경로와 정확히 같습니다.

헤드리스 경로(GUI 없음)

에이전트에 녹화할 데스크톱이 없는 경우, 동일한 어설션 규율을 유지하세요. 레코더를 스크립트 기반 캡처로 대체하세요:

  • 모든 것을 .artifacts/<task-name>/에 저장하세요(gitignore에 추가 — 증거는 업로드되며, 커밋되지 않습니다). 캡처 스크립트를 캡처 옆에 두어 실행을 재현 가능하게 만드세요.

  • 스크린샷: before-and-after CLI(@vercel/before-and-after)는 URL 또는 요소를 캡처하고, 그 페어는 PR 임베드에 직접 공급됩니다. "No usable sandbox"로 Chrome이 실패하는 컨테이너/VM에서는 AGENT_BROWSER_ARGS="--no-sandbox"를 설정하세요.

  • 비디오 / 다단계 흐름: 일회성 Playwright 스크립트. 프로젝트 종속성에 playwright를 추가하지 않고 실행:

    npx --yes --package=playwright node record.mjs
    

    (일반 npx playwright node record.mjs는 실패합니다. node는 Playwright CLI 명령이 아닙니다. --package=playwright가 모듈을 경로에 추가합니다.) 최소 record.mjs:

    import { chromium } from "playwright";
    const browser = await chromium.launch();
    const context = await browser.newContext({
      recordVideo: { dir: ".artifacts/<task-name>/" },
    });
    const page = await context.newPage();
    await page.goto("http://localhost:3000/path-under-test");
    // ...단계별로 하나의 의미 있는 상태 변경으로 흐름을 조작...
    await context.close(); // .webm 최종 처리
    await browser.close();
    

    파일이 크면 ffmpeg로 자르거나 압축하세요.

  • 주석 프로토콜은 파일이 됩니다: 테스트 순서대로 캡처에 번호를 매기고 어설션을 이름에 포함하세요. 01-precondition-signed-in.png, 02-it-saves-on-blur-passed.png와 같이, 아티팩트 폴더에 각 test_start / assertion과 그 결과(passed / failed / untested + 이유)를 나열한 assertions.md를 유지하세요.

UI가 아닌 변경에도 증거가 필요합니다

  • API / 성능: 측정된 숫자를 포함한 스크립트 프로브 — 단계별 요청 수, 전후 지연 시간 — probe-output.txt에 캡처.
  • 렌더링 / 캔버스 / 셰이더: 렌더링된 프레임과 픽셀 어설션(diff 값)을 육안으로 검토하고 PNG로 저장.
  • 에이전트 동작: 도구 호출 및 응답을 보여주는 관련 대화록 발췌.
  • 버그 수정: 수정 사항을 작성하기 전에 실패를 재현하고 캡처하세요. 그 캡처가 전후 페어의 "이전" 부분입니다.

캡처 위생

  • 특히 여러 에이전트가 머신을 공유할 때, 프로브 중인 서버가 당신의 코드를 실행하고 있는지 확인하세요(올바른 포트, 올바른 프로세스): lsof -i :<port> — 또는 lsof가 설치되지 않은 경우, ss -ltnp "sport = :<port>".
  • 캡처를 공유하기 전에 민감한 정보(비밀번호, 토큰, 고객 데이터)가 포함되어 있지 않은지 시각적으로 검토하세요.
  • 헤드리스 경로의 아티팩트 폴더가 .gitignore에 있는지 확인하세요. 증거는 업로드되며 커밋되지 않습니다.
  • 큰 파일의 경우 일정 시간이 지나면 호스트에서 제거하거나 수명이 제한된 업로드 링크를 사용하세요.

관련 스킬