crucible은(는) 무엇을 하나요?
사용 시점
TypeScript 프로젝트에서 단위 테스트를 작성, 수정, 또는 감사하라는 요청을 받았을 때 사용합니다.
사용하지 말아야 할 경우
엔드 투 엔드(E2E), 통합, UI, 또는 시뮬레이션 테스트를 작성할 때는 사용하지 않습니다.
프로젝트별 옵트아웃
활성화하기 전에 프로젝트가 이 스킬을 옵트아웃했는지 확인합니다. 다음 중 하나라도 있는지 찾아보십시오:
- 프로젝트 루트에
.no-crucible파일이 있는 경우 AGENTS.md또는.claude/settings.json파일 내 어디든"crucible: false"가 있는 경우
옵트아웃 신호가 발견되면 자동으로 활성화하지 말고, 사용자가 이 대화에서 명시적으로 요청할 때만 이 스킬을 적용합니다.
규칙
- 예제 명령어는
pnpm을 사용하지만, 항상 프로젝트의 패키지 매니저를 사용합니다. - 특별히 요청받지 않는 한 애플리케이션 코드를 수정하지 않습니다.
- 테스트를 추가하라는 요청을 받으면 기존 테스트를 수정하지 않습니다.
- 테스트를 수정하라는 요청을 받으면 새 테스트를 추가하지 않습니다.
- 테스트를 감사하라는 요청을 받으면 기존 테스트를 수정한 후 테스트 기준을 충족하기 위해 필요에 따라 테스트를 추가합니다.
테스트 기준
단위 테스트는 다음을 충족해야 합니다:
- Vitest 기준 최대한 높은 분기 커버리지를 가져야 합니다.
- 죽일 수 있는 모든 돌연변이를 죽여, 프롬프트 범위 내 모든 코드(테스트가 커버하는 코드뿐만 아니라)에 대해 최대 돌연변이 점수를 달성해야 합니다. 죽일 수 없는 돌연변이는 100점을 막습니다.
- 가능하면 항상 속성 기반이어야 합니다. 단, 입력 케이스가 극소수인 경우는 예외입니다. 예를 들어, 단일 불리언 매개변수와 암시적 입력이 없는 함수는 입력 케이스가 두 개뿐이므로 속성 기반으로 만들 필요가 없습니다.
- (속성 기반인 경우) 모든 가능한 매개변수와 암시적 입력을 포함하는 arbitraries를 가져야 합니다. 프로덕션에서 발생할 수 있는 케이스가 배제되지 않는 것이 매우 중요합니다. 필요하거나 불확실한 경우, arbitraries를 너무 넓게 만드는 쪽으로 오류를 범합니다.
- 잘못된 코드를 테스트하거나 arbitraries가 의도적으로 너무 넓게 만들어진 경우 실패해야 합니다. 테스트를 요구사항으로 생각하십시오: 그에 따라 이름을 지정해야 하며, 사용자가 나중에 함수 및/또는 arbitraries를 수정한 후 버그를 수정하면 테스트가 자동으로 통과해야 합니다.
test.fails/.skip을 사용하지 마십시오. 이렇게 하면 사용자가 주의가 필요하다는 것을 덜 인지하게 되므로, 통과해서는 안 될 테스트가 통과하는 것이 가장 우선순위가 높은 방지해야 할 오류입니다.
분기 커버리지를 확인하고 테스트를 실행합니다: pnpm exec vitest run src/foo.test.ts --coverage
테스트 대상 코드에서 살아남은 돌연변이를 확인합니다: pnpm exec stryker run --mutate "src/foo.ts"
테스트 설정 확인
- 프로젝트에 다음 패키지가 모두 설치되어 있는지 확인합니다:
vitest fast-check @stryker-mutator/core @stryker-mutator/vitest-runner @stryker-mutator/typescript-checker - Vitest 및 Stryker 설정이 파일을 올바르게 포함/제외하는지 확인합니다. Stryker는 테스트 데이터만 포함하는 파일을 검사하지 않아야 합니다.
- Stryker 설정을 확인합니다:
clear-text리포터를 사용하는지 확인합니다(다른 리포터는 선택 사항).- TypeScript 체커를 사용하고 TS 설정 파일을 올바르게 가리키는지 확인합니다.
- 테스트 작성 워크플로우에 문제를 일으킬 수 있는 다른 설정 문제가 있는지 찾습니다.
- 결과를 사용자에게 보고합니다.
테스트 작성
새 테스트를 작성하라는 요청을 받으면 애플리케이션 코드나 기존 테스트를 수정하지 않습니다.
먼저, 모듈 평가하기에 따라 기존 테스트를 평가합니다. 템플릿을 사용하여 새 데브리프 파일을 만들고 초기 커버리지 및 돌연변이 점수를 기록합니다.
두 번째로, 다음 프로세스를 정확히 따라 테스트를 작성합니다:
모듈 인터페이스의 각 함수/메서드에 대해 다음을 수행하며, 한 함수를 끝낸 후 다음 함수를 시작합니다:
- 주석, 이름, 타입 시그니처 및 사용 방식을 검토하여 함수의 목적을 파악합니다. 확실하지 않은 경우 데브리프에 그 내용을 기록하고, 테스트 작성을 건너뛰고 다음 함수로 넘어갑니다.
- 함수 구현에서 잠재적인 버그를 기록합니다.
- 목적에 따라 함수가 매개변수 및 암시적 입력에 대해 가지고 있는 잘못된 가정을 식별하고, 잘못된 함수 동작으로 이어질 가능성이 있는 입력 케이스를 기록합니다. 예를 들어, 양의 정수를 받지만 입력을 검증하지 않는 함수는 입력에 대해 잘못된 가정을 합니다.
- 기존 테스트를 절대 수정하지 않습니다. 기존 테스트에서 문제를 발견하면 사용자에게 알립니다.
- 다음을 수행하여 새 테스트를 작성합니다:
a.
fast-check를 사용하여, 함수의 모든 가능한 매개변수와 암시적 입력을 포함하는 arbitraries로 속성 기반 테스트 스텁을 만듭니다. 테스트 대상 함수가 비동기인 경우fc.asyncProperty+await fc.assert(...)를 사용합니다. 확실하지 않은 경우 arbitraries를 너무 넓게 만드는 쪽으로 오류를 범하고 이 사실을 데브리프에 기록하여 사용자가 수정할 수 있도록 합니다. 테스트 이름은 원하는 동작을 설명하는 방식으로 지정합니다. b.vitest를 사용하여, 반환 값과 부작용(예외 발생, 입력 변이, 외부 스코프 변수 변이/재할당 등)을 포함하는 스텁 내에 단언문을 작성합니다. 테스트가 원하는 동작을 단언하고, 앞서 식별된 잘못된 가정/버그를 포착하여 그에 따라 실패하는지 확인합니다. - 커버리지를 다시 확인합니다:
pnpm exec vitest run src/foo.test.ts --coverage - 현재 함수만 돌연변이 테스트합니다:
pnpm exec stryker run --mutate "src/foo.ts:<시작줄>-<끝줄>" - 새로 작성된 테스트를 수정하고 함수에 대한 테스트 기준(위에 나열됨)이 충족될 때까지 5a 및 5b 단계를 반복합니다.
- 이 함수에 대한 섹션을 데브리프에 업데이트합니다.
모든 함수에 대한 테스트를 작성한 후, 각 함수에 대한 섹션을 데브리프에 추가했는지 다시 확인하고 요약 섹션 작성을 마칩니다.
테스트 감사
프로젝트 전체를 감사하라는 요청을 받으면 프로젝트 전체의 코드 커버리지와 돌연변이 점수를 확인하고, 더 상세한 감사 또는 테스트 추가/업데이트가 필요한 영역을 추천합니다. 핵심 비즈니스 로직, 이벤트 기반 코드, 복잡한 함수 등 코드베이스에서 가장 중요하고 버그가 발생하기 쉬운 영역을 추천합니다.
프로젝트의 일부를 감사하라는 요청을 받으면 (프롬프트 범위 내에서) 테스트가 없는 모듈이나 함수를 찾아 감사 후 데브리프에서 사용자에게 보고합니다.
프롬프트 범위 내에서 테스트가 있는 각 모듈에 대해 모듈 평가하기를 따릅니다. 그런 다음, 평가 수정 후에도 테스트 기준이 여전히 충족되지 않으면 테스트 작성에 따라 나머지 차이를 채웁니다.
모듈 평가하기
이 프로세스는 새 테스트를 작성하기 전이나 감사할 때, 기존 테스트 파일을 테스트 기준에 대해 평가해야 할 때마다 사용합니다.
- Vitest를 사용하여 코드 커버리지를 확인합니다:
pnpm exec vitest run src/foo.test.ts --coverage. - Stryker Mutator를 사용하여 살아남은 돌연변이를 확인합니다:
pnpm exec stryker run --mutate "src/foo.ts". - 테스트가 존재하는 모듈의 각 함수에 대해:
- 속성 기반 테스트의 경우:
- 함수가 예외를 던지거나 오류 값을 반환하지 않고 받아들이지만 arbitraries로 생성할 수 없는 입력을 찾습니다. 필요에 따라 arbitraries를 넓혀 이러한 입력을 포함시킵니다.
- arbitraries로 커버되지 않는 입력, 특히 클래스 필드, 전역 변수, 날짜/시간, 무작위 생성 숫자와 같은 암시적 입력을 찾습니다. 이에 대한 arbitraries를 추가합니다.
- 목 구현의 오류를 수정합니다.
- 성능 병목 현상을 찾습니다.
- 속성 기반 테스트의 경우:
- 커버리지 및 돌연변이 점수와 모든 발견 사항을 데브리프에 기록합니다.
테스트 데브리프
아래 템플릿에 따라 데브리프를 작성합니다. 함수 하위 섹션에 보고할 내용이 없으면 간단히 "n/a"라고 작성합니다. 데브리프를 debriefs/ 디렉토리에 Markdown 파일로 출력합니다.
데브리프: {모듈이름/파일이름} {yyyy-mm-dd}
요약
커버리지 (분기) 이전: X% → 이후: Y% 커버할 수 없었던 줄: {줄 범위}
돌연변이 점수 (전체) 이전: X% → 이후: Y%
이슈
{잘못된 가정, 발견된 버그, 테스트에서 발견된 문제, 실패하는 테스트의 불릿 목록. 각 목록 항목은 문제가 발견된 파일의 프로젝트 루트 기준 상대 경로와 줄 번호로 시작해야 합니다}
{함수이름}
함수 목적 {함수가 수행해야 하는 작업을 한 문장으로 설명} (신뢰도: 높음 | 불확실) {불확실한 경우: 무엇이 불분명하고 그 이유}
발견된 잘못된 가정
- (줄 {줄 번호/범위}): {함수가 검증하지 않는 입력 타입/범위/형태에 대한 가정}
구현에서 발견된 버그
- (줄 {줄 번호/범위}): {설명 + 줄 번호}
기존 테스트에서 발견된 문제
- (줄 {줄 번호/범위}): {문제 설명 + 테스트 이름}
작성된 테스트 케이스
- {테스트된 각 속성/불변 조건에 대한 간략한 설명}
실패하는 테스트
- (줄 {줄 번호/범위}): {테스트 이름 + 이유}
죽일 수 없는 돌연변이
- (줄 {줄 번호/범위}): {간략한 설명}