Claude
Skills
Sign in
Back

testing-framework-helper

Included with Lifetime
$97 forever

Generates comprehensive test suites with unit tests, integration tests, and E2E tests for various frameworks (Jest, Pytest, Vitest, etc.). Use when writing tests.

Writing & Docs

What this skill does


# Testing Framework Helper Skill

Expert at creating comprehensive test suites following testing best practices.

## When to Activate

- "write tests for [component/function]"
- "create test suite for [feature]"
- "generate unit/integration/E2E tests"

## Jest/Vitest (JavaScript/TypeScript)

```typescript
// UserService.test.ts
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
import { UserService } from './UserService';
import { mockDatabase } from '../test-utils/mockDatabase';

describe('UserService', () => {
  let userService: UserService;
  let db: ReturnType<typeof mockDatabase>;

  beforeEach(() => {
    db = mockDatabase();
    userService = new UserService(db);
  });

  afterEach(() => {
    vi.clearAllMocks();
  });

  describe('getById', () => {
    it('should return user when found', async () => {
      const mockUser = {
        id: 1,
        name: 'John Doe',
        email: '[email protected]',
      };

      db.user.findUnique.mockResolvedValue(mockUser);

      const result = await userService.getById(1);

      expect(result).toEqual(mockUser);
      expect(db.user.findUnique).toHaveBeenCalledWith({
        where: { id: 1 },
      });
    });

    it('should return null when user not found', async () => {
      db.user.findUnique.mockResolvedValue(null);

      const result = await userService.getById(999);

      expect(result).toBeNull();
    });

    it('should throw error on database failure', async () => {
      db.user.findUnique.mockRejectedValue(new Error('DB Error'));

      await expect(userService.getById(1)).rejects.toThrow('DB Error');
    });
  });

  describe('create', () => {
    it('should create user with valid data', async () => {
      const userData = {
        name: 'Jane Doe',
        email: '[email protected]',
        password: 'SecurePass123!',
      };

      const createdUser = {
        id: 2,
        ...userData,
        password: 'hashed_password',
      };

      db.user.create.mockResolvedValue(createdUser);

      const result = await userService.create(userData);

      expect(result).toEqual(createdUser);
      expect(db.user.create).toHaveBeenCalledWith({
        data: expect.objectContaining({
          name: userData.name,
          email: userData.email,
        }),
      });
    });

    it('should throw error when email exists', async () => {
      const userData = {
        name: 'John Doe',
        email: '[email protected]',
        password: 'pass123',
      };

      db.user.findUnique.mockResolvedValue({ id: 1 });

      await expect(userService.create(userData)).rejects.toThrow(
        'Email already exists'
      );
    });
  });
});
```

## React Testing Library

```typescript
// UserList.test.tsx
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { UserList } from './UserList';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';

const mockUsers = [
  { id: 1, name: 'Alice', email: '[email protected]' },
  { id: 2, name: 'Bob', email: '[email protected]' },
];

const createWrapper = () => {
  const queryClient = new QueryClient({
    defaultOptions: { queries: { retry: false } },
  });

  return ({ children }) => (
    <QueryClientProvider client={queryClient}>
      {children}
    </QueryClientProvider>
  );
};

describe('UserList', () => {
  beforeEach(() => {
    global.fetch = vi.fn();
  });

  it('renders loading state initially', () => {
    (global.fetch as any).mockImplementation(() => new Promise(() => {}));

    render(<UserList />, { wrapper: createWrapper() });

    expect(screen.getByText(/loading/i)).toBeInTheDocument();
  });

  it('renders user list after loading', async () => {
    (global.fetch as any).mockResolvedValueOnce({
      ok: true,
      json: async () => mockUsers,
    });

    render(<UserList />, { wrapper: createWrapper() });

    await waitFor(() => {
      expect(screen.getByText('Alice')).toBeInTheDocument();
      expect(screen.getByText('Bob')).toBeInTheDocument();
    });
  });

  it('handles search functionality', async () => {
    render(<UserList />, { wrapper: createWrapper() });

    const searchInput = screen.getByPlaceholderText(/search/i);
    fireEvent.change(searchInput, { target: { value: 'Alice' } });

    await waitFor(() => {
      expect(global.fetch).toHaveBeenCalledWith(
        expect.stringContaining('search=Alice')
      );
    });
  });

  it('handles error state', async () => {
    (global.fetch as any).mockRejectedValueOnce(new Error('API Error'));

    render(<UserList />, { wrapper: createWrapper() });

    await waitFor(() => {
      expect(screen.getByText(/error/i)).toBeInTheDocument();
    });
  });
});
```

## Pytest (Python)

```python
# test_user_service.py
import pytest
from unittest.mock import Mock, patch, AsyncMock
from app.services.user_service import UserService
from app.models.user import User
from app.exceptions import ValidationError, NotFoundError

@pytest.fixture
def user_service():
    """Fixture for UserService instance"""
    return UserService()

@pytest.fixture
def mock_user():
    """Fixture for mock user data"""
    return User(
        id=1,
        email="[email protected]",
        name="Test User",
        role="user"
    )

class TestUserService:
    @pytest.mark.asyncio
    async def test_get_by_id_success(self, user_service, mock_user):
        """Test getting user by ID successfully"""
        with patch.object(User, 'get', return_value=mock_user) as mock_get:
            result = await user_service.get_by_id(1)

            assert result == mock_user
            mock_get.assert_called_once_with(id=1)

    @pytest.mark.asyncio
    async def test_get_by_id_not_found(self, user_service):
        """Test getting non-existent user"""
        with patch.object(User, 'get', return_value=None):
            with pytest.raises(NotFoundError, match="User not found"):
                await user_service.get_by_id(999)

    @pytest.mark.asyncio
    async def test_create_success(self, user_service):
        """Test creating user successfully"""
        user_data = {
            "email": "[email protected]",
            "name": "New User",
            "password": "SecurePass123!"
        }

        with patch.object(User, 'create', return_value=Mock(id=2)) as mock_create:
            result = await user_service.create(user_data)

            assert result.id == 2
            mock_create.assert_called_once()

    @pytest.mark.asyncio
    async def test_create_duplicate_email(self, user_service, mock_user):
        """Test creating user with existing email"""
        user_data = {
            "email": "[email protected]",
            "name": "Test",
            "password": "pass123"
        }

        with patch.object(User, 'get_by_email', return_value=mock_user):
            with pytest.raises(ValidationError, match="Email already exists"):
                await user_service.create(user_data)

    @pytest.mark.parametrize("email,valid", [
        ("[email protected]", True),
        ("invalid-email", False),
        ("", False),
        ("test@test", False),
    ])
    def test_validate_email(self, user_service, email, valid):
        """Test email validation with various inputs"""
        if valid:
            user_service.validate_email(email)
        else:
            with pytest.raises(ValidationError):
                user_service.validate_email(email)
```

## Integration Tests

```typescript
// user.integration.test.ts
import request from 'supertest';
import { app } from '../app';
import { setupTestDB, cleanupTestDB, seedTestData } from '../test-utils';

describe('User API Integration Tests', () => {
  let authToken: string;

  beforeAll(async () => {
    await setupTestDB();
    const seedData = await seedTestData();
    authToken = seedData.adminToken;
  });

  afterAll(async () => {
    await cleanupTestDB();
  });

  describe('GET /api/users', () => {
    it('should return paginated users', async () => {
      const r

Related in Writing & Docs