Testing Guide
Overview
This document describes the testing strategy for the Minuta application.
Test Structure
minuta/
+-- Shared/Tests/MinutaSharedTests/
+-- MinutaSharedTests.swift # Model tests
+-- Mocks/
| +-- MockFileStorageService.swift # Storage mock
| +-- MockTimeTrackingService.swift # Service mock (actor)
+-- Services/
+-- ExportServiceTests.swift # CSV export tests
+-- ImportServiceTests.swift # HEY CSV import tests
+-- LocalFileStorageServiceTests.swift # File I/O tests
+-- ReportServiceTests.swift # Report data + SVG renderer tests
+-- TimeTrackingServiceTests.swift # Unit tests
+-- TimeTrackingServiceIntegrationTests.swift # Integration tests Running Tests
# Run all tests
cd Shared && swift test
# Run specific test file (by name)
cd Shared && swift test --filter TimeTrackingServiceTests
# Run with verbose output
cd Shared && swift test --verbose Test Categories
Unit Tests
Unit tests verify individual functions and methods in isolation.
MinutaSharedTests.swift- Tag and TimeRecord model testsTimeTrackingServiceTests.swift- Service method tests with mocksExportServiceTests.swift- CSV export formattingImportServiceTests.swift- HEY CSV parsingReportServiceTests.swift- ReportData.build() and SVGReportRenderer
Integration Tests
Integration tests verify complete workflows and data flow.
TimeTrackingServiceIntegrationTests.swift:
- Complete timer workflow (tag -> start -> stop -> verify)
- Multiple concurrent timers
- Tag update/delete with existing records
- Error propagation from storage layer
- Manual record creation workflows
Mock Objects
MockFileStorageService:
- In-memory storage for testing
- Tracks method calls (loadTagsCalled, saveRecordCalled, etc.)
- Configurable error simulation
// Example: Simulate storage error
await mockStorage.setShouldThrowOnSave(true) MockTimeTrackingService:
- Actor-based mock for thread safety
- Configurable return values and error injection
Report Generation Testing
Reports use pure Swift SVG generation (SVGReportRenderer) with WKWebView for PDF/PNG conversion.
Unit Tests (SVGReportRenderer)
11 tests covering:
- Basic SVG structure and dimensions
- Header, chart, records, footer sections
- Text truncation and escaping
- Empty data handling
Manual Testing (WebKitReportService)
For PDF/PNG output, manual verification is recommended:
- Build and run the app in Simulator
- Create time records
- Navigate to History > Export
- Select PDF/PNG format
- Verify output file opens correctly
Verification Checklist
| Test Case | Steps | Expected Result |
|---|---|---|
| Empty report | Generate with no records | Shows empty chart, empty records |
| Single record | Generate with 1 record | Chart with one bar, one row |
| Multiple tags | Generate with 3+ tags | Chart sorted by hours, top 5 shown |
| Long comments | Record with 100+ char comment | Comment truncated with ”…” |
| Untagged records | Records without tags | Shown as ”-” in tag column |
| PDF generation | Export as PDF | Valid PDF opens in Preview |
| PNG generation | Export as PNG | Valid image at 2x resolution |
| A4 landscape | Check dimensions | 842 x 595 points |
Test Coverage Summary
| Area | Tests | Coverage |
|---|---|---|
| Models (Tag, TimeRecord) | 18 | 100% |
| LocalFileStorageService | 55 | 90% |
| TimeTrackingService | 23+31 | 95% |
| ExportService | 11 | 100% |
| ImportService | 21 | 100% |
| ReportService + SVGRenderer | 56 | 100% |
| TagColorGenerator | 14 | 100% |
| OKLCH | 9 | 100% |
| Integration Tests | 15 | - |
| Total Unit | 253 | - |
| UI Tests | 17 | - |
| Grand Total | 270 | - |
Related Documentation
- 306-report - Report Service architecture
- 302-export - Export Service
- 303-time-tracking - Time Tracking Service