Marketplace mobile-testing
Write and run tests for React Native apps using Jest and React Native Testing Library. Use when creating tests, debugging failures, or setting up test infrastructure.
install
source · Clone the upstream repo
git clone https://github.com/aiskillstore/marketplace
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/aiskillstore/marketplace "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/babakbar/mobile-testing" ~/.claude/skills/aiskillstore-marketplace-mobile-testing && rm -rf "$T"
manifest:
skills/babakbar/mobile-testing/SKILL.mdsource content
Mobile Testing
Testing guide for React Native applications.
When to Use
- Writing unit tests for components or utilities
- Creating integration tests for features
- Setting up test infrastructure
- Debugging test failures
- Improving test coverage
Test Setup
# Install testing dependencies npm install --save-dev jest @testing-library/react-native # Add to package.json { "scripts": { "test": "jest", "test:watch": "jest --watch", "test:coverage": "jest --coverage" } }
Component Test Template
import { render, fireEvent } from '@testing-library/react-native'; import { MyButton } from './MyButton'; describe('MyButton', () => { it('renders correctly', () => { const { getByText } = render(<MyButton title="Click me" />); expect(getByText('Click me')).toBeTruthy(); }); it('calls onPress when pressed', () => { const onPress = jest.fn(); const { getByText } = render( <MyButton title="Click me" onPress={onPress} /> ); fireEvent.press(getByText('Click me')); expect(onPress).toHaveBeenCalledTimes(1); }); });
Hook Test Template
import { renderHook, act } from '@testing-library/react-native'; import { useCounter } from './useCounter'; describe('useCounter', () => { it('increments count', () => { const { result } = renderHook(() => useCounter()); act(() => { result.current.increment(); }); expect(result.current.count).toBe(1); }); });
Utility Test Template
import { formatDate } from './formatDate'; describe('formatDate', () => { it('formats date correctly', () => { const date = new Date('2025-01-15'); expect(formatDate(date)).toBe('2025-01-15'); }); it('handles invalid input', () => { expect(() => formatDate(null)).toThrow(); }); });
Mocking Patterns
Mock External Module
jest.mock('expo-notifications', () => ({ scheduleNotificationAsync: jest.fn(), }));
Mock Database
jest.mock('@/db/client', () => ({ db: { select: jest.fn(), insert: jest.fn(), }, }));
Mock Navigation
jest.mock('expo-router', () => ({ useRouter: () => ({ push: jest.fn(), back: jest.fn(), }), }));
Running Tests
# Run all tests npm test # Watch mode (auto-rerun on changes) npm run test:watch # With coverage report npm run test:coverage # Run specific test file npm test -- MyComponent.test.tsx # Update snapshots npm test -- -u
Best Practices
- Test Behavior, Not Implementation: Test what users see and do
- Use
for Selection: More reliable than text matchingtestID - Mock External Dependencies: Keep tests isolated and fast
- Test Edge Cases: Empty states, errors, loading states
- Keep Tests Simple: One assertion per test when possible
- Clean Up: Use
/beforeEach
for setup/teardownafterEach
Common Patterns
Async Testing
it('loads data', async () => { const { findByText } = render(<DataComponent />); expect(await findByText('Loaded')).toBeTruthy(); });
Testing Forms
it('validates input', () => { const { getByTestId, getByText } = render(<LoginForm />); fireEvent.changeText(getByTestId('email-input'), 'invalid'); fireEvent.press(getByTestId('submit-button')); expect(getByText('Invalid email')).toBeTruthy(); });
Testing Lists
it('renders list items', () => { const items = [{ id: '1', name: 'Item 1' }]; const { getAllByTestId } = render(<ItemList items={items} />); expect(getAllByTestId('list-item')).toHaveLength(1); });
Troubleshooting
- Tests timing out: Increase timeout or check for unresolved promises
- Can't find element: Use
to see rendered outputscreen.debug() - Mock not working: Ensure mock is before import
- Async issues: Use
orwaitFor
queriesfindBy