From erne-universal
Guides test-driven development workflow for React Native using Jest, React Native Testing Library, and Detox in Red-Green-Refactor cycle. For new features, bug fixes, refactoring.
How this skill is triggered — by the user, by Claude, or both
Slash command
/erne-universal:tdd-workflowThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
You are executing a test-driven development workflow for React Native. Follow the Red-Green-Refactor cycle strictly.
You are executing a test-driven development workflow for React Native. Follow the Red-Green-Refactor cycle strictly.
Invoke this skill when:
Before writing any implementation code, write a test that describes the expected behavior:
Component test (React Native Testing Library):
import { render, screen, fireEvent } from '@testing-library/react-native';
import { LoginForm } from '../LoginForm';
describe('LoginForm', () => {
it('disables submit when fields are empty', () => {
render(<LoginForm onSubmit={jest.fn()} />);
const submitButton = screen.getByRole('button', { name: /sign in/i });
expect(submitButton).toBeDisabled();
});
it('calls onSubmit with email and password', () => {
const onSubmit = jest.fn();
render(<LoginForm onSubmit={onSubmit} />);
fireEvent.changeText(screen.getByPlaceholderText(/email/i), '[email protected]');
fireEvent.changeText(screen.getByPlaceholderText(/password/i), 'secret123');
fireEvent.press(screen.getByRole('button', { name: /sign in/i }));
expect(onSubmit).toHaveBeenCalledWith({
email: '[email protected]',
password: 'secret123',
});
});
it('shows error message on failed login', async () => {
const onSubmit = jest.fn().mockRejectedValue(new Error('Invalid credentials'));
render(<LoginForm onSubmit={onSubmit} />);
fireEvent.changeText(screen.getByPlaceholderText(/email/i), '[email protected]');
fireEvent.changeText(screen.getByPlaceholderText(/password/i), 'wrong');
fireEvent.press(screen.getByRole('button', { name: /sign in/i }));
expect(await screen.findByText(/invalid credentials/i)).toBeTruthy();
});
});
Run the test. It MUST fail (red).
Write the minimum code to make the test pass. Do NOT add anything extra:
export function LoginForm({ onSubmit }: LoginFormProps) {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [error, setError] = useState<string | null>(null);
const handleSubmit = async () => {
try {
await onSubmit({ email, password });
} catch (e) {
setError(e instanceof Error ? e.message : 'Unknown error');
}
};
return (
<View>
<TextInput placeholder="Email" value={email} onChangeText={setEmail} />
<TextInput placeholder="Password" value={password} onChangeText={setPassword} secureTextEntry />
<Pressable
onPress={handleSubmit}
disabled={!email || !password}
accessibilityRole="button"
accessibilityLabel="Sign in"
>
<Text>Sign In</Text>
</Pressable>
{error && <Text>{error}</Text>}
</View>
);
}
Run tests again. All MUST pass (green).
Now improve the code without changing behavior:
useLoginForm)Run tests after every change. They MUST stay green.
| Layer | Tool | What to Test |
|---|---|---|
| Unit | Jest | Pure functions, hooks, utilities |
| Component | RNTL | Component rendering, user interactions |
| Integration | RNTL | Multiple components working together |
| E2E | Detox | Full user flows on real app |
Tests live next to their source:
src/features/auth/
LoginForm.tsx
__tests__/
LoginForm.test.tsx
hooks/
useLoginForm.ts
__tests__/
useLoginForm.test.ts
screen queries — prefer getByRole, getByText, getByPlaceholderTextnpx claudepluginhub jubakitiashvili/everything-react-native-expoGuides Test-Driven Development for React Native using Jest (jest-expo) and @testing-library/react-native. Use before implementing features, bugfixes, or refactors.
Test-driven development with red-green-refactor loop, including planning via coverage gaps, tracer bullets, async leak detection, deep module design, and condition-based waiting. Activates on test files.
Provides Jest testing patterns including factory functions, mocking strategies, custom renders, and TDD workflow for React Native unit tests.