Skip to content

Latest commit

 

History

History
219 lines (171 loc) · 6.71 KB

File metadata and controls

219 lines (171 loc) · 6.71 KB

Test Fixture Infrastructure

Overview

This document describes the test fixture infrastructure for calendar monitoring tests. The fixtures provide a modular, extensible, and maintainable test infrastructure that reduces duplication and makes writing new tests easier.

Components

1. BaseCalendarTestFixture

The BaseCalendarTestFixture in testutils/BaseCalendarTestFixture.kt provides:

  • Core test infrastructure including context, timer, and permissions setup
  • Configurable mock components that can be selectively included
  • Helper methods for common testing operations
  • Resource management and cleanup

2. MockContextProvider

The MockContextProvider handles:

  • Creating and configuring the mock context
  • Setting up SharedPreferences with persistent storage
  • Managing system services like AlarmManager
  • Simulating context operations like startService() and startActivity()

3. MockTimeProvider

The MockTimeProvider offers:

  • Test clock implementation that extends CNPlusTestClock
  • Methods to advance time and trigger scheduled tasks
  • Utilities for setting specific time points and verifying timing behavior
  • Integration with MockTimer for scheduling operations

4. MockCalendarProvider

The MockCalendarProvider includes:

  • Methods to create test calendars and events
  • Configurable event attributes (title, start time, etc.)
  • Support for different event types (regular, all-day, recurring)
  • Delegation to real CalendarProvider where possible

5. MockApplicationComponents

The MockApplicationComponents provides:

  • Mock ApplicationController with configurable behavior
  • Mock notification handling
  • Mock alarm scheduling
  • Mock event formatting

Implementation Phases

Phase 1: Foundation

Created the base structure:

  1. Core interfaces and abstract classes
  2. Mock context provider with SharedPreferences support
  3. Test clock and timer management via CNPlusTestClock
  4. Resource cleanup in @After methods

Phase 2: Calendar and Event Support

Extracted calendar functionality:

  1. Calendar creation and management utilities
  2. Event creation with configurable attributes
  3. Real CalendarProvider delegation (not pure mocks)
  4. Storage verification utilities

Phase 3: Application Components

Extracted application-level mocking:

  1. ApplicationController mocking with provider injection
  2. Notification management mocks
  3. Alarm scheduling mocks
  4. Event formatting utilities

Phase 4: Builder Pattern

Implemented flexible configuration:

  1. Builder interface for fixture setup
  2. Specialized builders for common test scenarios
  3. Documentation and examples
  4. Cleanup mechanisms

Phase 5: Test Migration

Migrated existing tests to use fixtures:

  1. Refactored one test class at a time
  2. Verified tests continued to pass throughout
  3. Removed duplicate code
  4. Added additional test helpers as needed

Resulting Specialized Fixtures

  • CalendarProviderTestFixture - For calendar/event tests
  • CalendarMonitorTestFixture - For monitoring flow tests
  • DirectReminderTestFixture - For reminder broadcast tests
  • UITestFixture - For UI/Activity tests with Espresso

Usage Patterns

Basic Test Setup

@Test
fun testBasicEventProcessing() {
    // Configure and build the test fixture
    val fixture = BaseCalendarTestFixture.Builder()
        .withTestCalendar("Test Calendar")
        .withTestEvent(title = "Test Event")
        .build()
        
    // Simulate calendar monitoring
    fixture.triggerCalendarMonitoring()
    
    // Advance time and verify results
    fixture.advanceTime(1000)
    fixture.verifyEventProcessed(fixture.testEventId)
}

Specialized Test Scenarios

@Test
fun testDirectReminderProcessing() {
    // Use specialized fixture for direct reminders
    val fixture = DirectReminderTestFixture()
        .withTestEvent(title = "Direct Reminder Test")
        .build()
        
    // Simulate direct reminder broadcast
    fixture.simulateReminderBroadcast(fixture.reminderTime)
    
    // Verify processing
    fixture.verifyDirectReminderProcessed(fixture.testEventId)
}

Benefits

  1. Reduced Duplication: Common setup and verification code maintained in one place
  2. Improved Readability: Tests focus on behavior under test, not setup mechanics
  3. Easier Maintenance: Changes to mocking approach only need to be made in one place
  4. Faster Test Writing: New tests can be created quickly using the fixture
  5. Better Isolation: Each test can precisely configure only what it needs
  6. Consistent Verification: Standard verification methods ensure consistent checks
  7. Flexible Configuration: Builder pattern allows precise control over mock behavior
  8. Resource Management: Centralized cleanup of mocks and resources

Development History

The fixture system was developed incrementally:

  1. Foundation components were created without changing existing tests
  2. Simple utility methods allowed existing tests to adopt fixtures gradually
  3. Test classes were refactored one at a time, starting with simpler tests
  4. Specialized fixtures emerged as patterns became clear during migration
  5. Tests were run after each step to ensure functionality was preserved
flowchart TD
    A[Foundation Components] --> B[Context & Time Providers]
    B --> C[Calendar Provider]
    C --> D[Application Components]
    D --> E[Specialized Fixtures]
    E --> F[Direct Reminder Tests]
    F --> G[Calendar Monitor Tests]
    G --> H[UI Tests]
    H --> I[Documentation]
Loading

Component Relationships

classDiagram
    class BaseCalendarTestFixture {
        +MockContextProvider contextProvider
        +MockTimeProvider timeProvider
        +MockCalendarProvider calendarProvider
        +MockApplicationComponents appComponents
        +setup()
        +cleanup()
        +advanceTime()
        +verifyEventProcessed()
    }
    
    class MockContextProvider {
        +createMockContext()
        +setupSharedPreferences()
        +getMockService()
    }
    
    class MockTimeProvider {
        +CNPlusTestClock testClock
        +advanceTime()
        +executeScheduledTasks()
        +setSpecificTime()
    }
    
    class MockCalendarProvider {
        +createTestCalendar()
        +createTestEvent()
        +mockEventDetails()
        +mockEventReminders()
    }
    
    class MockApplicationComponents {
        +mockApplicationController()
        +mockNotifications()
        +mockAlarmScheduler()
        +mockFormatter()
    }
    
    BaseCalendarTestFixture --> MockContextProvider
    BaseCalendarTestFixture --> MockTimeProvider
    BaseCalendarTestFixture --> MockCalendarProvider
    BaseCalendarTestFixture --> MockApplicationComponents
    MockTimeProvider --> "uses" CNPlusTestClock
    MockContextProvider --> "creates" MockService
Loading