skills/testing-patterns/SKILL.md
TDD/BDD workflows for FastAPI + React stack with pytest, vitest, and integration testing. Use when writing tests, configuring test runners, or implementing test-driven development.
npx skillsauth add ainative-studio/ainativestudio-ide testing-patternsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
4 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
This skill provides comprehensive testing patterns and workflows for test-driven development (TDD) and behavior-driven development (BDD) in FastAPI + React applications.
Activate this skill when you need to:
1. RED - Write a failing test
2. GREEN - Write minimal code to make it pass
3. REFACTOR - Improve code while keeping tests green
def test_example():
# ARRANGE - Set up test data and conditions
user = User(email="[email protected]")
# ACT - Execute the behavior being tested
result = user.validate_email()
# ASSERT - Verify the expected outcome
assert result is True
def test_user_authentication():
# GIVEN a registered user
user = create_user(email="[email protected]", password="password123")
# WHEN the user attempts to login with correct credentials
result = authenticate(email="[email protected]", password="password123")
# THEN authentication succeeds
assert result.success is True
assert result.user_id == user.id
from fastapi.testclient import TestClient
from main import app
client = TestClient(app)
def test_create_item():
# ARRANGE
item_data = {"name": "Test Item", "price": 29.99}
# ACT
response = client.post("/api/items", json=item_data)
# ASSERT
assert response.status_code == 201
assert response.json()["name"] == "Test Item"
assert response.json()["price"] == 29.99
import pytest
@pytest.fixture
def auth_headers(client):
"""Fixture providing authenticated headers"""
response = client.post("/api/auth/login", json={
"email": "[email protected]",
"password": "password123"
})
token = response.json()["access_token"]
return {"Authorization": f"Bearer {token}"}
def test_protected_endpoint(client, auth_headers):
# ACT
response = client.get("/api/profile", headers=auth_headers)
# ASSERT
assert response.status_code == 200
assert "email" in response.json()
import pytest
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from database import Base
@pytest.fixture(scope="function")
def test_db():
"""Create a fresh test database for each test"""
engine = create_engine('sqlite:///./test.db')
Base.metadata.create_all(bind=engine)
TestingSessionLocal = sessionmaker(bind=engine)
db = TestingSessionLocal()
yield db
db.close()
Base.metadata.drop_all(bind=engine)
def test_create_user(test_db):
# ARRANGE
from models import User
user = User(email="[email protected]", name="Test User")
# ACT
test_db.add(user)
test_db.commit()
test_db.refresh(user)
# ASSERT
assert user.id is not None
assert user.email == "[email protected]"
import { describe, it, expect } from 'vitest'
import { render, screen } from '@testing-library/react'
import { Button } from './Button'
describe('Button Component', () => {
it('renders with correct text', () => {
// ARRANGE & ACT
render(<Button>Click Me</Button>)
// ASSERT
expect(screen.getByText('Click Me')).toBeInTheDocument()
})
it('calls onClick handler when clicked', () => {
// ARRANGE
const handleClick = vi.fn()
render(<Button onClick={handleClick}>Click Me</Button>)
// ACT
screen.getByText('Click Me').click()
// ASSERT
expect(handleClick).toHaveBeenCalledOnce()
})
})
import { renderHook, act } from '@testing-library/react'
import { useCounter } from './useCounter'
describe('useCounter', () => {
it('increments counter', () => {
// ARRANGE
const { result } = renderHook(() => useCounter(0))
// ACT
act(() => {
result.current.increment()
})
// ASSERT
expect(result.current.count).toBe(1)
})
})
from unittest.mock import Mock, patch
@pytest.fixture
def mock_openai():
with patch('openai.ChatCompletion.create') as mock:
mock.return_value = {
'choices': [{'message': {'content': 'AI response'}}]
}
yield mock
def test_ai_chat(mock_openai):
# ACT
response = get_ai_response("Hello")
# ASSERT
assert response == "AI response"
mock_openai.assert_called_once()
@pytest.fixture
def mock_db_session():
"""Mock database session for unit tests"""
mock_session = Mock()
mock_session.query.return_value.filter.return_value.first.return_value = Mock(
id=1,
email="[email protected]"
)
return mock_session
def test_get_user_by_email(mock_db_session):
# ACT
user = get_user_by_email(mock_db_session, "[email protected]")
# ASSERT
assert user.email == "[email protected]"
mock_db_session.query.assert_called_once()
@pytest.mark.integration
def test_user_registration_flow(client, test_db):
# GIVEN no existing user
assert test_db.query(User).count() == 0
# WHEN user registers
response = client.post("/api/auth/register", json={
"email": "[email protected]",
"password": "securepass123"
})
# THEN user is created and can login
assert response.status_code == 201
assert test_db.query(User).count() == 1
login_response = client.post("/api/auth/login", json={
"email": "[email protected]",
"password": "securepass123"
})
assert login_response.status_code == 200
assert "access_token" in login_response.json()
@pytest.fixture
def mock_zerodb_client():
with patch('services.zerodb.ZeroDBClient') as mock:
mock_instance = Mock()
mock_instance.vector_search.return_value = [
{'id': '1', 'score': 0.95, 'content': 'Relevant document'}
]
mock.return_value = mock_instance
yield mock_instance
@pytest.mark.integration
def test_semantic_search(client, mock_zerodb_client, auth_headers):
# ACT
response = client.post("/api/search",
headers=auth_headers,
json={"query": "machine learning"}
)
# ASSERT
assert response.status_code == 200
assert len(response.json()["results"]) > 0
mock_zerodb_client.vector_search.assert_called_once()
All tests must achieve ≥80% code coverage:
# Run with coverage
pytest --cov=src --cov-report=html --cov-report=term-missing --cov-fail-under=80
# View HTML coverage report
open htmlcov/index.html
project/
├── src/
│ ├── api/
│ ├── services/
│ └── models/
├── tests/
│ ├── unit/
│ │ ├── test_api.py
│ │ ├── test_services.py
│ │ └── test_models.py
│ ├── integration/
│ │ ├── test_api_integration.py
│ │ └── test_db_integration.py
│ ├── conftest.py
│ └── pytest.ini
└── frontend/
├── src/
└── tests/
├── components/
├── hooks/
└── utils/
# pytest.ini
[pytest]
markers =
unit: Unit tests (fast, isolated)
integration: Integration tests (slower, with dependencies)
slow: Slow tests (skip in CI with -m "not slow")
smoke: Critical smoke tests
# Run only unit tests
pytest -m unit
# Run all except slow tests
pytest -m "not slow"
# Run specific test file
pytest tests/unit/test_api.py
# Run tests matching pattern
pytest -k "test_user"
Tests run automatically in GitHub Actions:
- name: Run tests with coverage
run: |
cd backend
pytest --cov=src --cov-report=xml --cov-fail-under=80
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
with:
files: ./backend/coverage.xml
test_user_cannot_access_other_users_dataThis skill includes detailed reference documentation:
references/pytest-config.md - pytest configuration and setupreferences/vitest-config.md - vitest configuration for Reactreferences/mock-patterns.md - Mocking strategies for external servicesreferences/integration-tests.md - End-to-end testing patternsreferences/ci-integration.md - GitHub Actions test configurationreferences/test-examples.md - Real-world test examplesWorks seamlessly with:
pytest # Run all tests
pytest -v # Verbose output
pytest -x # Stop on first failure
pytest --lf # Run last failed tests
pytest --cov=src # Run with coverage
pytest -m unit # Run unit tests only
pytest -k "test_user" # Run tests matching pattern
npm run test # Run all tests
npm run test:watch # Watch mode
npm run test:ui # UI mode
npm run test:coverage # Generate coverage
Remember: Tests are not just verification - they are documentation, design tools, and safety nets. Write tests that clarify intent and catch regressions.
development
ZeroDB vector database best practices, semantic search patterns, RLHF workflows, and memory management. Use when working with ZeroDB APIs, vector search, or AI memory systems.
devops
Railway deployment workflows, nixpacks configuration, environment management, and production troubleshooting
tools
MCP server development patterns extending Anthropic's mcp-builder with AINative-specific conventions. Use when creating MCP servers, integrating ZeroDB, or building tool-based AI systems.
development
# API Design Skill You are an expert FastAPI backend architect specializing in RESTful API design, Pydantic data validation, and scalable backend systems. ## When to Use This Skill Use this skill when: - Designing new REST APIs or endpoints - Creating Pydantic models and schemas - Implementing authentication (JWT, OAuth) - Setting up error handling and validation - Structuring FastAPI applications - Working with OpenAPI/Swagger documentation ## Core Principles ### 1. RESTful Design - Use HT