@fix-my/test-runner
v0.3.0
Published
Jest/React Testing Library (RTL) 호환 API를 제공하는 경량 테스트 러너 패키지입니다.
Readme
@fix-my/test-runner
Jest/React Testing Library (RTL) 호환 API를 제공하는 경량 테스트 러너 패키지입니다.
특징
- Jest 호환 API:
describe,it,expect등 익숙한 인터페이스 - RTL 스타일 쿼리:
screen.getByText(),screen.getByRole()등 - 풍부한 DOM 매처:
toBeInTheDocument(),toBeVisible(),toHaveTextContent()등 - 듀얼 환경 지원: Node.js VM과 브라우저 모두에서 실행 가능
- TypeScript 지원: 완전한 타입 정의 포함
설치
npm install @fix-my/test-runner기본 사용법
import { render, screen, expect, describe, it, cleanup } from '@fix-my/test-runner';
describe('Button Component', () => {
afterEach(() => {
cleanup();
});
it('renders with correct text', () => {
render(<Button>Click me</Button>);
const button = screen.getByText('Click me');
expect(button).toBeInTheDocument();
expect(button).toBeVisible();
});
it('displays loading state', async () => {
render(<Button loading>Submit</Button>);
const spinner = await screen.findByRole('img', { timeout: 1000 });
expect(spinner).toBeInTheDocument();
});
});API Reference
Test Structure
describe(name, fn)
테스트 그룹을 정의합니다.
describe('User Form', () => {
// 테스트들...
});it(name, fn) / test(name, fn)
개별 테스트 케이스를 정의합니다.
it('validates email format', () => {
// 테스트 로직...
});Rendering
render(element)
React 엘리먼트를 DOM에 렌더링합니다.
const { container, unmount, rerender } = render(<App />);반환값:
container: 렌더링된 컨테이너 엘리먼트unmount(): 컴포넌트를 DOM에서 제거rerender(newElement): 새 props로 리렌더링
cleanup()
모든 렌더링된 컴포넌트를 정리합니다.
afterEach(() => {
cleanup();
});Screen Queries
Query Types
| Query | Returns | Throws | Use Case |
|-------|---------|--------|----------|
| getBy* | Element | Yes | 엘리먼트가 있어야 할 때 |
| queryBy* | Element | null | No | 엘리먼트가 없을 수 있을 때 |
| findBy* | Promise<Element> | Yes | 비동기 엘리먼트 |
Available Queries
// 텍스트로 찾기
screen.getByText('Hello');
screen.getByText(/hello/i);
screen.queryByText('Optional');
await screen.findByText('Loading...');
// ARIA role로 찾기
screen.getByRole('button');
screen.getByRole('heading');
// data-testid로 찾기
screen.getByTestId('submit-button');
// 라벨로 찾기 (aria-label 포함)
screen.getByLabelText('Username');
screen.getByLabelText('Close dialog'); // aria-label
// placeholder로 찾기
screen.getByPlaceholderText('Enter email');Options
// 부분 매칭
screen.getByText('Hello', { exact: false });
// 타임아웃 (findBy*)
await screen.findByText('Loaded', { timeout: 5000 });Matchers
DOM Presence
expect(element).toBeInTheDocument();
expect(element).toBeVisible();
expect(element).toBeEmpty();Attributes & Content
expect(element).toHaveTextContent('Hello');
expect(element).toHaveTextContent(/hello/i);
expect(element).toHaveClass('active');
expect(element).toHaveClass('btn', 'primary');
expect(element).toHaveAttribute('disabled');
expect(element).toHaveAttribute('href', '/home');Form Elements
expect(input).toHaveValue('[email protected]');
expect(checkbox).toBeChecked();
expect(button).toBeDisabled();
expect(input).toHaveFocus();Styles
expect(element).toHaveStyle({ display: 'flex' });
expect(element).toHaveStyle({ color: 'red', fontSize: '16px' });Hierarchy
expect(parent).toContainElement(child);
expect(element).toContainHTML('<span>text</span>');Negation
expect(element).not.toBeInTheDocument();
expect(element).not.toBeVisible();
expect(button).not.toBeDisabled();Async Utilities
waitFor(callback, options?)
조건이 충족될 때까지 대기합니다.
await waitFor(() => {
expect(screen.getByText('Loaded')).toBeInTheDocument();
}, { timeout: 5000, interval: 100 });act(callback)
React 상태 업데이트를 동기화합니다.
await act(async () => {
button.click();
});Basic Matchers
expect(value).toBe(expected);
expect(value).toBeTruthy();
expect(value).toBeFalsy();
expect(array).toContain(item);
expect(number).toBeGreaterThan(other);
expect(number).toBeLessThan(other);Migration Guide
Legacy Mode (호환성)
기존 테스트에서 자동 렌더링을 사용했다면:
import { setCompatMode, registerApp, render } from '@fix-my/test-runner';
// 레거시 모드 활성화
setCompatMode('auto');
registerApp(App);
// 인자 없이 render 호출
render();권장 방식 (Manual Mode)
import { render, screen } from '@fix-my/test-runner';
// RTL 스타일
render(<App />);
const button = screen.getByText('Click');Node.js VM 환경에서 사용
import { runTestsInVM } from '@fix-my/test-runner';
const bundledCode = '...'; // 번들된 테스트 코드
const result = await runTestsInVM(bundledCode);
console.log(result.passed); // true/false
console.log(result.results); // 개별 테스트 결과에러 메시지
쿼리 실패 시 유용한 에러 메시지를 제공합니다:
Unable to find element with text: "Missing Text"
<body>
<div class="container">
<button>Click me</button>
</div>
</body>
Tip: Use findByText for async elements브라우저 지원
- Chrome (최신)
- Firefox (최신)
- Safari (최신)
- Edge (최신)
참고: IE11은 지원하지 않습니다. React 18+ 필요.
License
MIT
