jubakitiashvili/everything-react-native-expo/tdd-workflow

Claude Code and agent skill by jubakitiashvili/everything-react-native-expo

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

Test-driven development workflow for React Native — Jest, React Native Testing Library, and Detox

Install

npx vskill@latest install jubakitiashvili/everything-react-native-expo/tdd-workflow

SKILL.md

TDD Workflow

You are executing a test-driven development workflow for React Native. Follow the Red-Green-Refactor cycle strictly.

When to Use This Skill

Invoke this skill when:

  • Implementing a new feature or component
  • Fixing a bug (write test to reproduce first)
  • Refactoring existing code (ensure tests exist first)

Red-Green-Refactor Cycle

Phase 1: RED — Write a Failing Test

Before writing any implementation code, write a test that describes the expected behavior:

Component test (React Native Testing Library):

tsx
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), 'user@test.com');
fireEvent.changeText(screen.getByPlaceholderText(/password/i), 'secret123');
fireEvent.press(screen.getByRole('button', { name: /sign in/i }));
expect(onSubmit).toHaveBeenCalledWith({
email: 'user@test.com',
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), 'user@test.com');
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).

Phase 2: GREEN — Minimal Implementation

Write the minimum code to make the test pass. Do NOT add anything extra:

tsx
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).

Phase 3: REFACTOR — Clean Up

Now improve the code without changing behavior:

  • Extract hooks (useLoginForm)
  • Add NativeWind styling
  • Improve types
  • Add accessibility labels

Run tests after every change. They MUST stay green.

Testing Layers

LayerToolWhat to Test
UnitJestPure functions, hooks, utilities
ComponentRNTLComponent rendering, user interactions
IntegrationRNTLMultiple components working together
E2EDetoxFull user flows on real app

Test File Placement

Tests live next to their source:

src/features/auth/
LoginForm.tsx
__tests__/
LoginForm.test.tsx
hooks/
useLoginForm.ts
__tests__/
useLoginForm.test.ts

Rules

  1. Never write implementation before tests
  2. One behavior per test — test name should describe expected behavior
  3. Test behavior, not implementation — don't test internal state
  4. Use `screen` queries — prefer getByRole, getByText, getByPlaceholderText
  5. Mock at boundaries — mock API calls, not internal functions
  6. No snapshot tests — they break too easily, test specific assertions

Security

  • Security scanPassed, 95 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
33
Repository forks
3
Repository npm downloads, 7 days
31
7-day trend score
33

Stars and forks are for the whole GitHub repository, not this skill alone. Downloads are for the repository's npm package. Refreshed 28 Apr 2026, 6 months ago.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/jubakitiashvili/everything-react-native-expo/tdd-workflow/badge)](https://verified-skill.com/skills/jubakitiashvili/everything-react-native-expo/tdd-workflow)

Something wrong with this skill or its page? Tell us.