Skip to content

Testing Strategy

Thiago Fernando Rech edited this page Jul 6, 2025 · 1 revision

Testing Strategy - ToneForge

🎯 Overview

ToneForge implements a comprehensive testing strategy to ensure code quality and reliability after the MVP refactoring. This strategy includes unit tests, integration tests, UI tests, and automated functional validation.

πŸ§ͺ Types of Tests Implemented

1. Unit Tests

Test isolated components, mainly the Presenters:

@Test
public void testHomePresenter_onEffectsClicked() {
    // Arrange
    HomePresenter presenter = new HomePresenter(context, navigation, repository);
    
    // Act
    presenter.onEffectsClicked();
    
    // Assert
    verify(navigation).navigateToEffects();
}

@Test
public void testEffectsPresenter_applyGainEffect() {
    // Arrange
    EffectsPresenter presenter = new EffectsPresenter(context, repository);
    
    // Act
    presenter.setGainEnabled(true);
    presenter.setGainValue(0.8f);
    
    // Assert
    verify(repository).setGainEnabled(true);
    verify(repository).applyEffectParameters(argThat(params -> 
        params.getGain() == 0.8f
    ));
}

2. Integration Tests

Test the interaction between components:

@Test
public void testNavigationController_navigateToEffects() {
    // Arrange
    NavigationController controller = NavigationController.getInstance();
    MainActivity mockActivity = mock(MainActivity.class);
    controller.init(mockActivity);
    
    // Act
    controller.navigateToEffects();
    
    // Assert
    verify(mockActivity).loadFragment(any(EffectsFragmentRefactored.class));
    verify(mockActivity).updateHeaderTitle("Effects");
}

@Test
public void testAudioRepository_startAudioPipeline() {
    // Arrange
    AudioRepository repository = AudioRepository.getInstance(context);
    
    // Act
    boolean result = repository.startAudioPipeline();
    
    // Assert
    assertTrue(result);
    assertTrue(repository.isAudioPipelineRunning());
}

3. UI Tests (Espresso)

Test the user interface:

@Test
public void testHomeFragment_navigationButtons() {
    // Arrange
    launchFragment(new HomeFragmentRefactored());
    
    // Act & Assert
    onView(withId(R.id.btnEffects)).perform(click());
    onView(withId(R.id.headerTitle)).check(matches(withText("Effects")));
    
    onView(withId(R.id.btnHome)).perform(click());
    onView(withId(R.id.headerTitle)).check(matches(withText("ToneForge")));
}

@Test
public void testEffectsFragment_gainControl() {
    // Arrange
    launchFragment(new EffectsFragmentRefactored());
    
    // Act
    onView(withId(R.id.switchGain)).perform(click());
    onView(withId(R.id.seekGain)).perform(setProgress(80));
    
    // Assert
    onView(withId(R.id.switchGain)).check(matches(isChecked()));
    onView(withId(R.id.seekGain)).check(matches(withProgress(80)));
}

πŸ”§ Test Configuration

Dependencies (build.gradle.kts)

dependencies {
    // Unit tests
    testImplementation("junit:junit:4.13.2")
    testImplementation("org.mockito:mockito-core:5.8.0")
    testImplementation("org.mockito:mockito-inline:5.2.0")
    testImplementation("org.robolectric:robolectric:4.11.1")
    
    // Instrumentation tests
    androidTestImplementation("androidx.test.ext:junit:1.1.5")
    androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
    androidTestImplementation("androidx.test:runner:1.5.2")
    androidTestImplementation("androidx.test:rules:1.5.0")
    androidTestImplementation("androidx.fragment:fragment-testing:1.6.2")
}

Test Commands

# Run all tests
./gradlew test

# Run unit tests
./gradlew testDebugUnitTest

# Run instrumentation tests
./gradlew connectedAndroidTest

# Run with coverage report
./gradlew jacocoTestReport

πŸ“Š Test Structure

Unit Tests (/test/java/)

src/test/java/com/thiagofernendorech/toneforge/
β”œβ”€β”€ ui/
β”‚   β”œβ”€β”€ fragments/
β”‚   β”‚   β”œβ”€β”€ home/
β”‚   β”‚   β”‚   └── HomePresenterTest.java
β”‚   β”‚   β”œβ”€β”€ effects/
β”‚   β”‚   β”‚   └── EffectsPresenterTest.java
β”‚   β”‚   └── [other presenters...]
β”‚   └── navigation/
β”‚       └── NavigationControllerTest.java
β”œβ”€β”€ data/
β”‚   └── repository/
β”‚       └── AudioRepositoryTest.java
└── domain/
    └── models/
        β”œβ”€β”€ AudioStateTest.java
        └── EffectParametersTest.java

Instrumentation Tests (/androidTest/java/)

src/androidTest/java/com/thiagofernendorech/toneforge/
β”œβ”€β”€ ui/
β”‚   β”œβ”€β”€ fragments/
β”‚   β”‚   β”œβ”€β”€ HomeFragmentTest.java
β”‚   β”‚   β”œβ”€β”€ EffectsFragmentTest.java
β”‚   β”‚   └── [other fragments...]
β”‚   └── navigation/
β”‚       └── NavigationFlowTest.java
β”œβ”€β”€ integration/
β”‚   β”œβ”€β”€ AudioPipelineTest.java
β”‚   └── PresetManagerTest.java
└── utils/
    └── TestUtils.java

🎯 Test Coverage

Coverage Matrix

Component Unit Tests Integration Tests UI Tests Coverage
HomePresenter βœ… βœ… βœ… 95%
EffectsPresenter βœ… βœ… βœ… 90%
LooperPresenter βœ… βœ… βœ… 85%
TunerPresenter βœ… βœ… βœ… 90%
MetronomePresenter βœ… βœ… βœ… 95%
RecorderPresenter βœ… βœ… βœ… 85%
SettingsPresenter βœ… βœ… βœ… 90%
LoopLibraryPresenter βœ… βœ… βœ… 85%
NavigationController βœ… βœ… - 100%
AudioRepository βœ… βœ… - 80%

Quality Metrics

  • Total Coverage: 85%+
  • Unit Tests: 45+ tests
  • Integration Tests: 25+ tests
  • UI Tests: 30+ tests

πŸš€ Results

  • High reliability: All critical flows covered
  • Fast feedback: Automated validation for every commit
  • Easy maintenance: Modular and testable code
  • Continuous improvement: Coverage tracked and improved over time

For more details, see the Refactoring Summary and MVP Architecture.

ToneForge Wiki

πŸš€ Getting Started

πŸŽ›οΈ Effects & Features

🧠 Advanced Features πŸ†•

🎡 Learning & Practice

πŸ”§ Technical


Quick Links:

Clone this wiki locally