Development
Command
/test
Complete test execution flow including backend and frontend tests, lint checks, and coverage reports.
How it fires
How this command gets triggered: by you, by Claude, or both.
- Fires itselfClaude auto-loads it when your prompt matches the work.
- You can call itInvoke it directly when you want it.
- Slash command
/test
Context preview
What this command does when you run it.
Complete test execution flow including backend and frontend tests, lint checks, and coverage reports.
Command definition
test.mdRun Tests
Complete test execution flow including backend and frontend tests, lint checks, and coverage reports.
Quick Test (daily development)
# Backend: run all tests
cd apps && python -m pytest -v
# Frontend: run all tests
cd ui && pnpm test
Full Test Flow
Step 1: Backend Tests
cd apps
# Run all tests (verbose)
python -m pytest -v
# Run single test file
python -m pytest tests/test_users.py -v
# Run tests matching name
python -m pytest -k "test_create_user" -v
# With coverage report
python -m pytest --cov=. --cov-report=html --cov-report=term-missing
# Only fast tests (skip slow-marked)
python -m pytest -m "not slow" -v
# Stop on first failure
python -m pytest -x -v
Step 2: Backend Lint & Format
cd apps
# Format check (no file changes)
black --check .
# Format (modify files)
black .
# Lint check
ruff check .
# Lint auto-fix
ruff check . --fix
# Full check
black --check . && ruff check .
Step 3: Frontend Tests
cd ui
# Run all package tests
pnpm test
# Run single package tests
pnpm --filter web test
pnpm --filter admin test
# Watch mode (during development)
pnpm --filter web test -- --watch
# With coverage
pnpm --filter web test -- --coverage
Step 4: Frontend Lint & Type Check
cd ui
# ESLint check
pnpm lint
# Type check
pnpm type-check
# Full check
pnpm lint && pnpm type-check
CI Full Check (must pass before commit)
# Backend
cd apps && black --check . && ruff check . && python -m pytest -v
# Frontend
cd ui && pnpm lint && pnpm type-check && pnpm test
Test Writing Conventions
Backend Tests (pytest)
# tests/test_users.py
import pytest
from httpx import AsyncClient
@pytest.mark.asyncio
async def test_create_user_with_valid_data_returns_201():
"""Create user - valid data should return 201"""
# Arrange
user_data = {
"username": "testuser",
"email": "test@example.com",
"password": "SecurePass123"
}
# Act
async with AsyncClient(app=app, base_url="http://test") as client:
response = await client.post("/api/v1/users", json=user_data)
# Assert
assert response.status_code == 201
data = response.json()
assert data["code"] == 200
assert data["data"]["username"] == "testuser"
@pytest.mark.asyncio
async def test_create_user_with_duplicate_email_returns_409():
"""Create user - duplicate email should return 409"""
# ...Frontend Tests (Vitest)
// src/__tests__/UserCard.test.ts
import { mount } from '@vue/test-utils'
import { describe, it, expect, vi } from 'vitest'
import UserCard from '../components/UserCard.vue'
describe('UserCard', () => {
it('should display username', () => {
const wrapper = mount(UserCard, {
props: {
user: { id: '1', username: 'test', email: 'test@example.com' }
}
})
expect(wrapper.text()).toContain('test')
})
it('should emit delete event on button click', async () => {
const wrapper = mount(UserCard, {
props: { user: { id: '1', username: 'test', email: 'test@example.com' } }
})
await wrapper.find('[data-testid="delete-btn"]').trigger('click')
expect(wrapper.emitted('delete')).toHaveLength(1)
expect(wrapper.emitted('delete')![0]).toEqual(['1'])
})
})Test Naming Conventions
- Backend: `test_<feature>_<scenario>_<expected_result>`
- `test_create_user_with_valid_data_returns_201`
- `test_login_with_wrong_password_returns_401`
- Frontend: `describe('ComponentName')` + `it('should behavior')`
- `it('should display username')`
- `it('should emit delete event on button click')`
Coverage Targets
| Module | Minimum Coverage | |--------|-----------------| | core/ | 90% | | services/ | 80% | | api/ | 75% | | Frontend components | 70% | | Frontend utilities | 90% |
Read more
Run Tests
Complete test execution flow including backend and frontend tests, lint checks, and coverage reports.
Quick Test (daily development)
# Backend: run all tests cd apps && python -m pytest -v # Frontend: run all tests cd ui && pnpm test
Full Test Flow
Step 1: Backend Tests
cd apps # Run all tests (verbose) python -m pytest -v # Run single test file python -m pytest tests/test_users.py -v # Run tests matching name python -m pytest -k "test_create_user" -v # With coverage report python -m pytest --cov=. --cov-report=html --cov-report=term-missing # Only fast tests (skip slow-marked) python -m pytest -m "not slow" -v # Stop on first failure python -m pytest -x -v
Step 2: Backend Lint & Format
cd apps # Format check (no file changes) black --check . # Format (modify files) black . # Lint check ruff check . # Lint auto-fix ruff check . --fix # Full check black --check . && ruff check .
Step 3: Frontend Tests
cd ui # Run all package tests pnpm test # Run single package tests pnpm --filter web test pnpm --filter admin test # Watch mode (during development) pnpm --filter web test -- --watch # With coverage pnpm --filter web test -- --coverage
Step 4: Frontend Lint & Type Check
cd ui # ESLint check pnpm lint # Type check pnpm type-check # Full check pnpm lint && pnpm type-check
CI Full Check (must pass before commit)
# Backend cd apps && black --check . && ruff check . && python -m pytest -v # Frontend cd ui && pnpm lint && pnpm type-check && pnpm test
Test Writing Conventions
Backend Tests (pytest)
# tests/test_users.py
import pytest
from httpx import AsyncClient
@pytest.mark.asyncio
async def test_create_user_with_valid_data_returns_201():
"""Create user - valid data should return 201"""
# Arrange
user_data = {
"username": "testuser",
"email": "test@example.com",
"password": "SecurePass123"
}
# Act
async with AsyncClient(app=app, base_url="http://test") as client:
response = await client.post("/api/v1/users", json=user_data)
# Assert
assert response.status_code == 201
data = response.json()
assert data["code"] == 200
assert data["data"]["username"] == "testuser"
@pytest.mark.asyncio
async def test_create_user_with_duplicate_email_returns_409():
"""Create user - duplicate email should return 409"""
# ...Frontend Tests (Vitest)
// src/__tests__/UserCard.test.ts
import { mount } from '@vue/test-utils'
import { describe, it, expect, vi } from 'vitest'
import UserCard from '../components/UserCard.vue'
describe('UserCard', () => {
it('should display username', () => {
const wrapper = mount(UserCard, {
props: {
user: { id: '1', username: 'test', email: 'test@example.com' }
}
})
expect(wrapper.text()).toContain('test')
})
it('should emit delete event on button click', async () => {
const wrapper = mount(UserCard, {
props: { user: { id: '1', username: 'test', email: 'test@example.com' } }
})
await wrapper.find('[data-testid="delete-btn"]').trigger('click')
expect(wrapper.emitted('delete')).toHaveLength(1)
expect(wrapper.emitted('delete')![0]).toEqual(['1'])
})
})Test Naming Conventions
- Backend: `test_<feature>_<scenario>_<expected_result>`
- `test_create_user_with_valid_data_returns_201`
- `test_login_with_wrong_password_returns_401`
- Frontend: `describe('ComponentName')` + `it('should behavior')`
- `it('should display username')`
- `it('should emit delete event on button click')`
Coverage Targets
| Module | Minimum Coverage | |--------|-----------------| | core/ | 90% | | services/ | 80% | | api/ | 75% | | Frontend components | 70% | | Frontend utilities | 90% |
Ships withaihelms
企业级 AI 资源纳管平台,提供统一 AI网关、Token调度能力,纳管 OpenAI、Azure、Claude、DeepSeek 等主流模型,并支持 MCP 工具与 Skill 的集中注册分发。具备内外双轨定价、成本归因、统一身份认证、安全审计与效能报表,帮助企业精准控制成本、量化 ROI,高效治理 AI 资产。
Get the whole plugin
Stats
934
Stars
94
Forks
Active
Maintenance
Python
Language
GPL-3.0
License
6d ago
Last commit
3mo ago
Created
Repo: beizhu-1209/AIHelms

