- StrictMode solo en DEBUG mode - ExecutorService con shutdown apropiado - DNSSetter NetworkCallback unregister - DiffUtil en ChannelAdapter y EventAdapter - minifyEnabled=true y shrinkResources=true para release - Validación en constructores (StreamChannel) - Strings externalizadas - ProGuard rules completas - Testing dependencies agregadas - Removed Firebase (uso personal) - JavaDoc documentación agregada - Android SDK configurado localmente Compilado exitosamente: StreamPlayer v9.4.2 debug APK (11MB)
6.0 KiB
Testing Guide - StreamPlayer
This document explains how to run and maintain tests for the StreamPlayer application.
Test Structure
The project has two types of tests:
-
Unit Tests (
app/src/test/)- Run on the JVM (no device/emulator needed)
- Test business logic in isolation
- Located in:
app/src/test/java/com/streamplayer/
-
Integration Tests (
app/src/androidTest/)- Run on Android device/emulator
- Test UI interactions and component integration
- Located in:
app/src/androidTest/java/com/streamplayer/
Running Tests
Unit Tests
Run all unit tests:
./gradlew test
Run specific test class:
./gradlew test --tests StreamUrlResolverTest
Run with coverage report:
./gradlew test jacocoTestReport
Integration Tests
Run all integration tests:
./gradlew connectedAndroidTest
Run specific test class:
./gradlew connectedAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=com.streamplayer.PlayerIntegrationTest
All Tests
Run both unit and integration tests:
./gradlew test connectedAndroidTest
Test Files
Unit Tests
-
StreamUrlResolverTest.java
- Tests for
parseVersionCode()andderiveGroupName()methods - Tests JSON parsing with Gson
- Tests various edge cases and error conditions
- Tests for
-
EventRepositoryTest.java
- Tests for EventItem model
- Tests Gson serialization/deserialization
- Tests filtering, sorting, and grouping operations
Integration Tests
-
PlayerIntegrationTest.java
- Tests channel playback flow
- Tests navigation between activities
- Tests error handling during playback
-
UpdateFlowIntegrationTest.java
- Tests update check flow
- Tests update download and installation
- Tests error handling during updates
Test Coverage
The tests aim to cover:
- ✅ All public methods in critical classes
- ✅ Happy path scenarios
- ✅ Error conditions and edge cases
- ✅ JSON serialization/deserialization
- ✅ UI navigation flows
- ✅ Integration between components
Dependencies
Testing Libraries
- JUnit 4: Unit testing framework
- Mockito: Mocking framework for unit tests
- Espresso: UI testing framework
- UiAutomator: Cross-app UI testing
- Robolectric: Android unit testing on JVM
Added Dependencies
The following dependencies have been added to build.gradle:
// Unit testing
testImplementation 'junit:junit:4.13.2'
testImplementation 'org.mockito:mockito-core:5.7.0'
testImplementation 'org.mockito:mockito-inline:5.2.0'
testImplementation 'androidx.arch.core:core-testing:2.2.0'
testImplementation 'org.robolectric:robolectric:4.11.1'
// Integration testing
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.5.1'
androidTestImplementation 'androidx.test.espresso:espresso-intents:3.5.1'
androidTestImplementation 'androidx.test:runner:1.5.2'
androidTestImplementation 'androidx.test:rules:1.5.0'
androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0'
Best Practices
-
Test Naming: Use descriptive names that explain what is being tested
- Good:
testParseVersionCode_withValidInput_returnsCorrectCode() - Bad:
test1()
- Good:
-
Test Structure: Follow AAA pattern (Arrange, Act, Assert)
- Arrange: Set up test data and conditions
- Act: Perform the action being tested
- Assert: Verify the expected results
-
Test Independence: Each test should be independent and not rely on other tests
-
Test Data: Use meaningful test data that covers edge cases
-
Mocking: Mock external dependencies (network, database, etc.)
-
Coverage: Aim for high code coverage but focus on testing behavior, not implementation
Continuous Integration
Tests should be run automatically on:
- Every pull request
- Before releases
- Nightly builds
Troubleshooting
Unit Tests
-
Mockito Issues: If you get "Mockito cannot mock this class", check:
- Add
@RunWith(MockitoJUnitRunner.class)to test class - Ensure
mockito-inlinedependency is included
- Add
-
Robolectric Issues: If tests fail with Robolectric:
- Check SDK version compatibility
- Add
@Configannotation with correct SDK version
Integration Tests
-
Emulator Issues:
- Ensure emulator is running or device is connected
- Check that developer options and USB debugging are enabled
-
Timing Issues: Add proper waits and delays:
Thread.sleep(1000); // Simple delay device.wait(Until.hasObject(By.pkg("com.streamplayer")), 5000); -
Permission Issues: Add necessary permissions to test manifest
Future Improvements
- Add more unit tests for other classes
- Implement test doubles for network layer
- Add performance tests
- Add screenshot tests for UI regression testing
- Implement mutation testing to verify test quality
- Add integration tests for error scenarios
- Implement automated test reporting
Firebase Configuration
To use Firebase services (Crashlytics, Analytics, Performance):
- Download
google-services.jsonfrom Firebase Console - Place it in
app/directory (replace the example file) - Firebase plugins are already configured in
build.gradle
LeakCanary
LeakCanary is included for debug builds to detect memory leaks:
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.12'
Check logcat for leak analysis results when testing on device/emulator.
ProGuard/R8
ProGuard rules have been updated to keep test-related classes:
- Keep ExoPlayer classes
- Keep OkHttp classes
- Keep Gson model classes
- Keep test classes and methods