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 tests
  • TimeTrackingServiceTests.swift - Service method tests with mocks
  • ExportServiceTests.swift - CSV export formatting
  • ImportServiceTests.swift - HEY CSV parsing
  • ReportServiceTests.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:

  1. Build and run the app in Simulator
  2. Create time records
  3. Navigate to History > Export
  4. Select PDF/PNG format
  5. Verify output file opens correctly

Verification Checklist

Test CaseStepsExpected Result
Empty reportGenerate with no recordsShows empty chart, empty records
Single recordGenerate with 1 recordChart with one bar, one row
Multiple tagsGenerate with 3+ tagsChart sorted by hours, top 5 shown
Long commentsRecord with 100+ char commentComment truncated with ”…”
Untagged recordsRecords without tagsShown as ”-” in tag column
PDF generationExport as PDFValid PDF opens in Preview
PNG generationExport as PNGValid image at 2x resolution
A4 landscapeCheck dimensions842 x 595 points

Test Coverage Summary

AreaTestsCoverage
Models (Tag, TimeRecord)18100%
LocalFileStorageService5590%
TimeTrackingService23+3195%
ExportService11100%
ImportService21100%
ReportService + SVGRenderer56100%
TagColorGenerator14100%
OKLCH9100%
Integration Tests15-
Total Unit253-
UI Tests17-
Grand Total270-

Related Documentation