Testing: Paparazzi Screenshot Testing Framework for Compose - devrath/RunTracer GitHub Wiki

paparazzi-background-75krg7qfw2h20u6g

References

Commands

Description Module Command
Generating Screenshots core:presentation:designsystem ./gradlew core:presentation:designsystem:recordPaparazziDebug
Validating Screenshots core:presentation:designsystem ./gradlew core:presentation:designsystem:verifyPaparazziDebug

How to integrate the library

Step-1- Add the dependencies in config

paparazzi-version = "1.3.4"
paparazzi = { id = "app.cash.paparazzi", version.ref = "paparazzi-version" }

Step-2- Add the plugin in project level gradle

plugins {
     alias(libs.plugins.paparazzi) apply false
}

Step-3- Add the plugin in module level gradle where we are writing tests

plugins {
    alias(libs.plugins.paparazzi)
}

Step-4- Add the test file in the unit test folder

Step-5- Add the tests

class Pixel6ProTest {

    @get:Rule
    val pixel6pro = Paparazzi(deviceConfig = DeviceConfig.PIXEL_6_PRO)

    @Test
    fun `Test in Pixel6Pro for the widget RunTracerActionButton`() { pixel6pro.snapshot {
        RunTracerActionButton(
            text = "Sign up",
            isLoading = false,
            enabled = false,
            onClick = {}
        )
    } }

    @Test
    fun `Test in Pixel6Pro for the widget RunTracerOutlinedActionButton`() { pixel6pro.snapshot {
        RunTracerOutlinedActionButton(
            text = "Sign In",
            isLoading = false,
            onClick = {}
        )
    } }

    @Test
    fun `Test in Pixel6Pro for the widget RunTracerPasswordRequirement`() { pixel6pro.snapshot {
        RunTracerPasswordRequirement(
            text = "Length of the password",
            isValid = true
        )
    } }

    @Test
    fun `Test in Pixel6Pro for the widget RunTracerPasswordTextField`() { pixel6pro.snapshot {
        RunTracerPasswordTextField(
            state = rememberTextFieldState(),
            hint = "[email protected]",
            title = "Email",
            modifier = Modifier.fillMaxWidth(),
            isPasswordVisible = true,
            onTogglePasswordVisibility = {}
        )
    } }
}

Where the snapshots are generated

Where the Output are generated

> Task :core:presentation:designsystem:testDebugUnitTest
See the Paparazzi report at: file:///Users/devrathad/Documents/Personal/github/RunTracer/Code/core/presentation/designsystem/build/reports/paparazzi/debug/index.html

Advantages of Using Paparazzi in Android Kotlin Snapshot Testing

  1. Fast Feedback Loop:

    • Advantage: Paparazzi runs on the JVM, so tests are faster than running on a physical device or emulator.
    • Benefit: Developers get immediate feedback on UI changes without the overhead of launching emulators or connecting devices.
  2. Integration with CI/CD:

    • Advantage: Easy to integrate with continuous integration and continuous deployment pipelines.
    • Benefit: Ensures UI consistency across different stages of development and deployment.
  3. Detailed UI Comparisons:

    • Advantage: Provides pixel-perfect comparisons between different versions of the UI.
    • Benefit: Helps catch subtle UI regressions that might be missed during manual testing.
  4. Customizability:

    • Advantage: Allows customization of themes, configurations, and device parameters for testing.
    • Benefit: Ensures that UI components are tested under various conditions and configurations.
  5. No Need for Physical Devices:

    • Advantage: Since it runs on the JVM, there's no need for physical devices or emulators.
    • Benefit: Reduces dependency on hardware and minimizes setup complexity.
  6. Consistency:

    • Advantage: Ensures consistent test results as it runs in a controlled environment.
    • Benefit: Avoids flakiness often seen with device or emulator-based tests.

Disadvantages of Using Paparazzi in Android Kotlin Snapshot Testing

  1. Limited Real-World Testing:

    • Disadvantage: Doesn't test the UI on real devices or emulators.
    • Impact: May miss issues related to device-specific behaviors or performance.
  2. Initial Setup Complexity:

    • Disadvantage: Setting up and configuring Paparazzi can be complex initially.
    • Impact: Requires additional time and effort to get started, especially for teams unfamiliar with the tool.
  3. Dependency on JVM:

    • Disadvantage: Since it runs on the JVM, it may not fully replicate the behavior of the app running on an actual device.
    • Impact: Potential differences in UI rendering between JVM and real devices.
  4. Maintenance Overhead:

    • Disadvantage: Requires maintaining snapshot images and updating them when intentional UI changes are made.
    • Impact: Increases the maintenance burden for developers.
  5. Handling of Dynamic Content:

    • Disadvantage: Dynamic content (e.g., animations, time-sensitive UI) can be challenging to test accurately.
    • Impact: May need additional configuration or handling to stabilize tests involving dynamic UI elements.
  6. Learning Curve:

    • Disadvantage: Teams need to learn how to effectively use Paparazzi and interpret its results.
    • Impact: Can slow down the adoption process, especially for teams new to snapshot testing.

Conclusion

Using Paparazzi for snapshot testing in Android Kotlin projects offers significant benefits in terms of speed, integration, and detailed UI comparisons. However, it also comes with challenges, particularly around setup complexity, maintenance, and real-world accuracy. Balancing these advantages and disadvantages is crucial for effectively incorporating Paparazzi into your testing strategy.