testing-frameworks

SKILL.md

Testing Frameworks - Jest, Vitest, Pytest

Write maintainable, reliable tests with proper structure and mocking


When to Use This Skill

Use this skill when:

  • Writing unit, integration, or end-to-end tests
  • Setting up test frameworks
  • Implementing mocks and fixtures
  • Following TDD practices

Critical Patterns

Pattern 1: AAA Pattern

When: Structuring all tests

Good:

test('should apply 10% discount for orders over $100', () => {
  // Arrange
  const order = { items: [{ price: 120 }], discount: 0.1 };

  // Act
  const total = calculateTotal(order);

  // Assert
  expect(total).toBe(108);
});

Why: AAA (Arrange, Act, Assert) makes tests clear and maintainable.


Pattern 2: Mocking Dependencies

When: Isolating units under test

Good (Jest):

import { getUserById } from './userService';
import { fetchUser } from './api';

jest.mock('./api');

test('should fetch and return user', async () => {
  // Arrange
  const mockUser = { id: 1, name: 'Alice' };
  (fetchUser as jest.Mock).mockResolvedValue(mockUser);

  // Act
  const user = await getUserById(1);

  // Assert
  expect(fetchUser).toHaveBeenCalledWith(1);
  expect(user).toEqual(mockUser);
});

Good (Pytest):

def test_get_user(mocker):
    # Arrange
    mock_get = mocker.patch('requests.get')
    mock_get.return_value.json.return_value = {"id": 1, "name": "Alice"}

    # Act
    user = get_user(1)

    # Assert
    assert user["name"] == "Alice"

Why: Mocking isolates the unit under test and makes tests fast and reliable.


Pattern 3: Test Organization

When: Grouping related tests

Good:

describe('calculateTotal', () => {
  test('applies discount for orders over $100', () => {
    expect(calculateTotal({ price: 120, discount: 0.1 })).toBe(108);
  });

  test('handles zero discount', () => {
    expect(calculateTotal({ price: 50, discount: 0 })).toBe(50);
  });

  test('throws error for negative prices', () => {
    expect(() => calculateTotal({ price: -10 })).toThrow();
  });
});

Why: Grouping related tests improves organization and readability.


Pattern 4: Async Testing

When: Testing asynchronous code

Good:

// async/await
test('should fetch user data', async () => {
  const data = await fetchUser(1);
  expect(data.name).toBe('Alice');
});

// .resolves/.rejects
test('should fetch user data', () => {
  return expect(fetchUser(1)).resolves.toHaveProperty('name', 'Alice');
});

test('should handle errors', () => {
  return expect(fetchUser(999)).rejects.toThrow('User not found');
});

Why: Properly handling async ensures tests wait for operations to complete.


Pattern 5: Fixtures (Pytest)

When: Reusing test data

Good:

@pytest.fixture
def user():
    return {"id": 1, "name": "Alice"}

@pytest.fixture
def database():
    db = Database()
    db.connect()
    yield db
    db.disconnect()

def test_save_user(database, user):
    database.save(user)
    assert database.count() == 1

Why: Fixtures provide reusable setup and teardown logic.


Best Practices

One Assertion Per Test

// ✅ Good: Separate tests
test('user has correct name', () => {
  expect(user.name).toBe('Alice');
});

test('user email is valid', () => {
  expect(user.email).toContain('@');
});

// ❌ Bad: Multiple unrelated assertions
test('user validation', () => {
  expect(user.name).toBe('Alice');
  expect(user.email).toContain('@');
  expect(user.age).toBeGreaterThan(0);
});

Code Examples

Example 1: Unit Test with Mocking (Jest/Vitest)

import { getUserById, updateUser } from './userService';
import { db } from './db';

jest.mock('./db');

describe('userService', () => {
  test('should fetch user by id', async () => {
    // Arrange
    const mockUser = { id: 1, name: 'Alice', email: 'alice@example.com' };
    (db.user.findUnique as jest.Mock).mockResolvedValue(mockUser);

    // Act
    const user = await getUserById(1);

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

  test('should throw error when user not found', async () => {
    // Arrange
    (db.user.findUnique as jest.Mock).mockResolvedValue(null);

    // Act & Assert
    await expect(getUserById(999)).rejects.toThrow('User not found');
  });
});

Example 2: Component Test with User Interaction

import { render, screen, fireEvent } from '@testing-library/react';
import { LoginForm } from './LoginForm';

test('should display error on invalid email', async () => {
  // Arrange
  render(<LoginForm />);

  // Act
  const emailInput = screen.getByLabelText(/email/i);
  const submitButton = screen.getByRole('button', { name: /submit/i });

  fireEvent.change(emailInput, { target: { value: 'invalid-email' } });
  fireEvent.click(submitButton);

  // Assert
  expect(await screen.findByText(/invalid email/i)).toBeInTheDocument();
});

For comprehensive examples and detailed implementations, see the references/ folder.


Quick Reference

Jest/Vitest Commands

npm test                    # Run all tests
npm test -- --watch         # Watch mode
npm test -- --coverage      # Coverage report

Pytest Commands

pytest                      # Run all tests
pytest -v                   # Verbose
pytest --cov=myapp          # Coverage
pytest -k "user"            # Run tests matching "user"

Progressive Disclosure

For detailed implementations:


References


Maintained by dsmj-ai-toolkit

Weekly Installs
2
First Seen
Feb 25, 2026
Installed on
trae-cn2
codebuddy2
github-copilot2
codex2
kiro-cli2
kimi-cli2