Testing Guide
How to run and write tests for FiestaBoard.
Running Tests
Python Backend Tests
# Run all Python tests
pytest tests/
# Run with coverage report
pytest tests/ --cov=src --cov=plugins --cov-report=term-missing
# Run specific test file
pytest tests/test_api_server.py
# Run specific test
pytest tests/test_api_server.py::test_health_endpoint
Web UI Tests
# Run all web tests
npm run test:web
# Run with coverage
cd web && npx vitest --coverage
# Run specific test file
cd web && npx vitest src/components/__tests__/PageEditor.test.tsx
Linting
# Lint web code (ESLint)
npm run lint:web
# Lint Python code (Pylint)
pylint src/ plugins/
Writing Tests
Python Plugin Tests
Plugins require a minimum of 80% test coverage. Use the provided test utilities:
import pytest
from unittest.mock import patch, MagicMock
class TestMyPlugin:
"""Tests for MyPlugin."""
def test_fetch_data_success(self):
"""Test successful data fetching."""
plugin = MyPlugin(config={"api_key": "test"})
with patch("requests.get") as mock_get:
mock_get.return_value = MagicMock(
status_code=200,
json=lambda: {"temp": 72}
)
result = plugin.fetch_data()
assert result.available is True
assert result.data["temp"] == 72
def test_fetch_data_api_error(self):
"""Test handling of API errors."""
plugin = MyPlugin(config={"api_key": "test"})
with patch("requests.get") as mock_get:
mock_get.side_effect = Exception("API Error")
result = plugin.fetch_data()
assert result.available is False
assert result.error is not None
def test_validate_config(self):
"""Test configuration validation."""
# Missing required key
plugin = MyPlugin(config={})
assert plugin.validate_config() is False
# Valid config
plugin = MyPlugin(config={"api_key": "test"})
assert plugin.validate_config() is True
Web UI Component Tests
Use Vitest with React Testing Library:
import { render, screen } from '@testing-library/react';
import { describe, it, expect } from 'vitest';
import MyComponent from './MyComponent';
describe('MyComponent', () => {
it('renders correctly', () => {
render(<MyComponent title="Test" />);
expect(screen.getByText('Test')).toBeDefined();
});
it('handles click events', async () => {
const onClick = vi.fn();
render(<MyComponent onClick={onClick} />);
await screen.getByRole('button').click();
expect(onClick).toHaveBeenCalled();
});
});
Test Best Practices
- Mock external APIs — Never make real API calls in tests
- Test happy path and error cases — Cover both success and failure scenarios
- Test edge cases — Empty data, missing config, rate limits
- Keep tests focused — One assertion per test when possible
- Use descriptive names — Test names should explain what's being tested
CI/CD Integration
Tests run automatically on every pull request via GitHub Actions. The CI pipeline:
- Runs Python tests with coverage
- Runs web UI tests with coverage
- Runs linting checks
- Reports coverage to the PR
info
All tests must pass before a PR can be merged. Coverage must meet the minimum threshold for plugins (80%).
Next Steps
- Contributing — How to contribute
- Plugin Development Guide — Creating plugins with tests