new-test
jest-expo + RNTL 기반 테스트를 팀 컨벤션대로 스캐폴드한다. Use when writing a test, or starting the TDD red step before implementation. unit·integration 만 (E2E 제외).
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
jest-expo + RNTL 기반 테스트를 팀 컨벤션대로 스캐폴드한다. Use when writing a test, or starting the TDD red step before implementation. unit·integration 만 (E2E 제외).
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
TanStack Query 쿼리 정의·훅을 팀 컨벤션대로 스캐폴드한다. Use when connecting an API or creating useQuery/useMutation hooks (예:"API 연동해줘", "쿼리 훅 만들어줘", "서버 데이터 불러와줘"). 폼 상태는 /new-form, 로컬 UI 상태(useState)·익스텐션 코드에는 사용하지 않는다.
react-hook-form + zod 폼을 팀 컨벤션대로 스캐폴드한다. Use when creating a form or adding input validation (예:"폼 만들어줘", "입력 검증 추가해줘", "로그인 폼 구현", "검색 입력 구현"). 검색어 같은 단일 입력도 폼 상태(RHF)로 구성한다. 서버 상태 조회는 /new-query, 익스텐션 코드에는 사용하지 않는다.
이 프로젝트 고유의 Expo·NativeWind·RN 함정과 패키지 도입 기준 (자동 트리거). Use when writing/modifying app-web UI code, when a style works on web but not native (or vice versa), when adding a new package, or when upgrading expo/nativewind/react-native-css. 일반 Expo API 사용법은 expo 공식 플러그인 skill 을 쓴다. 익스텐션 코드에는 해당 없다.
NativeWind 기반 React Native 컴포넌트를 팀 컨벤션대로 스캐폴드한다. Use when creating a new UI component for the app/web. 익스텐션 UI 에는 사용하지 않는다.
expo-router 화면(라우트)을 팀 컨벤션대로 추가한다. Use when adding a new screen/route to the app/web. app/ 은 라우팅 껍데기로 두고 로직은 features 로 분리한다.
Creates a GitHub Pull Request by analyzing branch changes and filling in the project PR template. TRIGGER when: user invokes /pr directly, or says 'PR 만들어줘', 'PR 작성해줘'.
| name | new-test |
| description | jest-expo + RNTL 기반 테스트를 팀 컨벤션대로 스캐폴드한다. Use when writing a test, or starting the TDD red step before implementation. unit·integration 만 (E2E 제외). |
/check-dup 을 먼저(이미 했으면 생략).LinkCard.tsx → LinkCard.test.tsx, normalizeUrl.ts → normalizeUrl.test.ts.@/, @shared/).shared/ 또는 src/utils 순수 함수 → 단위 테스트src/features/* 컴포넌트 → 컴포넌트 통합 테스트src/features/*/api react-query 훅 → 훅 통합 테스트render / rerender / unmount 는 async → 반드시 await render(...). (빠뜨리면 screen 이 비어 실패)@testing-library/react-native 에서 import 만 하면 자동 적용.getByRole → getByText/getByLabelText → getByTestId(최후).import { normalizeUrl } from '@shared/domain/normalizeUrl';
describe('normalizeUrl', () => {
test('쿼리스트링 추적 파라미터를 제거한다', () => {
expect(normalizeUrl('https://a.com/x?utm_source=y')).toBe('https://a.com/x');
});
});
import { render, screen, userEvent } from '@testing-library/react-native';
import { LinkCard } from './LinkCard';
test('제목을 보여주고, 누르면 onPress 를 호출한다', async () => {
const onPress = jest.fn();
await render(<LinkCard title="제목" onPress={onPress} />);
expect(screen.getByText('제목')).toBeOnTheScreen();
const user = userEvent.setup();
await user.press(screen.getByText('제목'));
expect(onPress).toHaveBeenCalledTimes(1);
});
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { renderHook, waitFor } from '@testing-library/react-native';
import { useLinks } from './useLinks';
function createWrapper() {
const client = new QueryClient({ defaultOptions: { queries: { retry: false } } });
return ({ children }: { children: React.ReactNode }) => (
<QueryClientProvider client={client}>{children}</QueryClientProvider>
);
}
test('링크 목록을 불러온다', async () => {
// shared/api 의 fetch 는 mock 한다 (실제 호출 금지)
const { result } = renderHook(() => useLinks(), { wrapper: createWrapper() });
await waitFor(() => expect(result.current.isSuccess).toBe(true));
expect(result.current.data).toHaveLength(2);
});
pnpm test (또는 pnpm test:watch) → 실패(red) 확인. 실패해야 정상.