VibeFast
Testing & Quality

Unit Testing Guide

Learn how to write effective unit tests for your components and functions using Jest and React Native Testing Library.

Unit testing is a critical part of maintaining a high-quality codebase. VibeFast is configured with Jest and React Native Testing Library to make testing your frontend components straightforward and effective.

The Secret Weapon: Your AI Test-Writing Prompt

VibeFast includes a powerful, expert-level prompt designed to guide an AI (like ChatGPT, Claude, or Cursor) to write comprehensive and accurate unit tests for your components.

  • Location: prompts/write-unit-tests.md
  • Purpose: This file contains a detailed set of rules and patterns for testing in the VibeFast environment. It instructs the AI on how to mock dependencies, structure tests, and handle common pitfalls.

How-To: Write a Test for a New Component

Step 1: Use the AI Prompt

When you have a new component to test, copy the entire contents of prompts/write-unit-tests.md. Paste this into your AI chat tool, followed by the source code of the component you want to test.

Example Prompt to your AI:

"Here are our comprehensive testing guidelines. Please follow them strictly. Now, write unit tests for the following component:"

[...paste the content of write-unit-tests.md here...]

[...paste your component's source code here...]

Step 2: Review the Generated Test

The AI will generate a complete test file (*.test.tsx) based on the expert rules it was given. Review the generated code to ensure it covers the key user interactions for your component.

Step 3: Run the Test

Place the generated test file alongside your component in a __tests__ directory and run the testing script.

pnpm test:frontend

Example Test File

Here is an example of a test file for the <Checkbox /> component, which was generated using this methodology. It demonstrates how to test rendering, user interaction, and state changes.

src/components/ui/form/__tests__/checkbox.test.tsx
import 'react-native';
import React from 'react';
import { cleanup, screen, setup } from '@/lib/test-utils';
import { Checkbox } from '../checkbox';

afterEach(cleanup);

describe('Checkbox component', () => {
  it('renders correctly and calls onChange on press', async () => {
    const mockOnChange = jest.fn();
    const { user } = setup(
      <Checkbox
        testID="checkbox"
        onChange={mockOnChange}
        accessibilityLabel="agree"
      />
    );

    // Initial state
    expect(screen.getByTestId('checkbox')).toBeOnTheScreen();
    expect(screen.getByTestId('checkbox')).not.toBeChecked();

    // User interaction
    await user.press(screen.getByTestId('checkbox'));

    // Assertions
    expect(mockOnChange).toHaveBeenCalledTimes(1);
    expect(mockOnChange).toHaveBeenCalledWith(true);
  });

  it("shouldn't change value while disabled", async () => {
    const mockOnChange = jest.fn();
    const { user } = setup(
      <Checkbox
        disabled={true}
        testID="checkbox"
        onChange={mockOnChange}
        accessibilityLabel="agree"
      />
    );

    // Check disabled state
    expect(screen.getByTestId('checkbox')).toBeDisabled();

    // Attempt interaction
    await user.press(screen.getByTestId('checkbox'));

    // Assert that no change occurred
    expect(mockOnChange).toHaveBeenCalledTimes(0);
  });
});