Unit Testing
Part of: MPAC SmartPOS Cloud Platform - Product RequirementsVersion: 2.0 Last Updated: 2026-01-28
Overview
This document defines unit testing standards, coverage targets, and execution procedures for the MPAC platform across all technology stacks. Unit tests focus on testing individual components in isolation with mocked dependencies, ensuring code quality and maintainability. The platform requires different testing approaches for Python (pytest), Go (go test), and frontend JavaScript/TypeScript (likely Jest/Vitest) codebases, with specific coverage targets for business logic and security-critical code.
Table of Contents
Backend Testing (Python - svc-portal)
Purpose: Validate individual Python modules, functions, and classes in the svc-portal service.
Test Execution
# Run unit tests with pytest
cd mpac-smartpos/svc-portal
uv run pytest tests/unit/ --cov=mpac --cov-report=html
# Run specific test file
uv run pytest tests/unit/test_auth.py -v
# Run with coverage report
uv run pytest tests/unit/ --cov=mpac --cov-report=html --cov-report=termCoverage Targets
| Code Type | Coverage Target | Rationale |
|---|---|---|
| Business logic | 80-90% | Ensure core functionality works correctly |
| Security code | 95-100% | Critical for authentication and authorization |
| Utility functions | 70-80% | Helper functions with lower risk |
| Configuration | 60-70% | Setup code with minimal logic |
Test Structure
# Example unit test for authentication
import pytest
from unittest.mock import Mock, patch
from mpac.auth.service import AuthService
@pytest.fixture
def auth_service():
return AuthService(db=Mock(), cache=Mock())
@pytest.mark.unit
async def test_user_login_success(auth_service):
# Arrange
user = Mock(id="user123", password_hash="$2b$12$...")
auth_service.db.get_user = Mock(return_value=user)
# Act
result = await auth_service.login("test@example.com", "password123")
# Assert
assert result.access_token is not None
assert result.user_id == "user123"Backend Testing (Go - svc-smarttab, mpac-pgw)
Purpose: Validate individual Go packages, functions, and structs in backend services.
Test Execution
# Run all unit tests
cd mpac-smartpos/svc-smarttab
go test ./... -cover -coverprofile=coverage.out
# Run tests for specific package
go test ./internal/order -v
# View HTML coverage report
go tool cover -html=coverage.out
# Run with race detector
go test ./... -race
# Run with verbose output
go test ./... -v -coverCoverage Analysis
# Generate coverage profile
go test ./... -coverprofile=coverage.out
# View coverage by function
go tool cover -func=coverage.out
# View HTML coverage report
go tool cover -html=coverage.out -o coverage.htmlTest Structure
// Example unit test for order service
package order_test
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"mpac/internal/order"
)
func TestCreateOrder_Success(t *testing.T) {
// Arrange
mockRepo := new(MockOrderRepository)
service := order.NewService(mockRepo)
mockRepo.On("Create", mock.Anything).Return(&order.Order{
ID: "order123",
StoreID: "store456",
}, nil)
// Act
result, err := service.CreateOrder(ctx, orderReq)
// Assert
assert.NoError(t, err)
assert.Equal(t, "order123", result.ID)
mockRepo.AssertExpectations(t)
}Frontend Testing
Purpose: Validate React components, hooks, and utility functions in isolation.
Test Execution
cd mpac-frontend
# Run all unit tests
pnpm test
# Run tests with coverage report
pnpm test:coverage
# Run tests in watch mode
pnpm test:watch
# Run tests for specific app
pnpm test --filter=portal
# Run tests for specific file
pnpm test --filter=portal -- LoginForm.test.tsxTesting Framework
The frontend monorepo likely uses Vitest (given Vite usage) or Jest for unit testing, along with:
- React Testing Library for component testing
- @testing-library/user-event for user interaction simulation
- MSW (Mock Service Worker) for API mocking
Test Structure
// Example component test
import { render, screen, waitFor } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { LoginForm } from './LoginForm'
describe('LoginForm', () => {
it('should submit login credentials', async () => {
// Arrange
const onSubmit = vi.fn()
render(<LoginForm onSubmit={onSubmit} />)
// Act
await userEvent.type(screen.getByLabelText('Email'), 'test@example.com')
await userEvent.type(screen.getByLabelText('Password'), 'password123')
await userEvent.click(screen.getByRole('button', { name: 'Login' }))
// Assert
await waitFor(() => {
expect(onSubmit).toHaveBeenCalledWith({
email: 'test@example.com',
password: 'password123'
})
})
})
})Related Documentation
- Integration Testing - API and service integration tests
- Load Testing - Performance and scalability testing
- Security Testing - Security validation and compliance
- CI/CD Configuration - Automated testing in pipelines
Navigation
- Previous: Integration Requirements
- Next: Integration Testing
- Up: Testing Strategy
- Home: PRD Home