Roborazzi Help

Multiplatform support

Experimental feature: iOS support

Roborazzi supports Compose Multiplatform iOS. You can use Roborazzi with Compose iOS as follows:

Gradle settings

plugins { kotlin("multiplatform") id("org.jetbrains.compose") id("io.github.takahirom.roborazzi") } kotlin { sourceSets { ... val appleTest by getting { dependencies { implementation("io.github.takahirom.roborazzi:roborazzi-compose-ios:[version]") // Use 1.13.0 or higher implementation(kotlin("test")) } } ...

Test with Roborazzi

class IosTest { @OptIn(ExperimentalTestApi::class) @Test fun test() { runComposeUiTest { setContent { MaterialTheme { Column { Button(onClick = { }) { Text("Hello World") } Box( modifier = Modifier .background(Color.Red.copy(alpha = 0.5f), MaterialTheme.shapes.small) .size(100.dp), ) } } } // iOS uses the same RoborazziOptions as the other targets. For example, // allow up to 1% of pixels to differ before a comparison fails. val roborazziOptions = RoborazziOptions( compareOptions = RoborazziOptions.CompareOptions(changeThreshold = 0.01F), ) // Unlike the JVM, iOS has no automatic file-name generation, so filePath // is required for every capture. onRoot().captureRoboImage(this, filePath = "ios.png", roborazziOptions = roborazziOptions) onNodeWithText("Hello World").captureRoboImage( this, filePath = "ios_button.png", roborazziOptions = roborazziOptions, ) } } }

Then, you can run the Gradle tasks for iOS Support, just like you do for Android Support.

./gradlew recordRoborazzi[SourceSet]
./gradlew recordRoborazziIosSimulatorArm64 ./gradlew compareRoborazziIosSimulatorArm64 ./gradlew verifyRoborazziIosSimulatorArm64 ...

The currently implemented features for iOS support are as follows:

Feature

status

Record

supported

Compare

supported

Verify

supported

Report

supported

Dropbox/Differ comparison

supported

threshold / resultValidator

supported

diffPercentage

supported

resizing image (resizeScale)

supported

context data

supported (user-supplied only; the automatically-added default context data such as the test class name is JVM-only)

custom reporter

supported

ComparisonStyle

supported (Simple and Grid; Grid falls back to Simple when the density is unavailable)

RoborazziRecordFilePathStrategy

🆖 (filePath is required; a relative path always resolves against the output directory)

automatic file naming

🆖 (filePath is required)

image format

PNG only (WebP encoding is not supported on iOS)

pixelBitConfig

🆖 (Rgb565 falls back to Argb8888 with a warning; CoreGraphics has no 5-6-5 format)

dump

n/a (Robolectric-only concept)

applyDeviceCrop

n/a (Robolectric-only concept)

iOS runs on the same shared pipeline as the JVM and Compose Desktop targets (RoborazziOptionsprocessOutputImageAndReportRoboCanvas), so the image comparator, threshold / resultValidator, resizeScale, context data, custom reporters, and the reference | diff | new comparison output (including ComparisonStyle.Grid) all behave the same way. A few platform-specific features remain unsupported (see the table above); contributions are welcome.

Experimental feature: Compose Desktop support

Roborazzi supports Compose Desktop. You can use Roborazzi with Compose Desktop as follows:

Gradle settings

plugins { kotlin("multiplatform") id("org.jetbrains.compose") id("io.github.takahirom.roborazzi") } kotlin { // You can use your source set name jvm("desktop") sourceSets { ... val desktopTest by getting { dependencies { implementation("io.github.takahirom.roborazzi:roborazzi-compose-desktop:[version]") // Use 1.6.0-alpha-2 or higher implementation(kotlin("test")) } } ...

Test target Composable function

@Composable fun App() { var text by remember { mutableStateOf("Hello, World!") } MaterialTheme { Button( modifier = Modifier.testTag("button"), onClick = { text = "Hello, Desktop!" }) { Text( style = MaterialTheme.typography.h2, text = text ) } } }

Test with Roborazzi

class MainKmpTest { @OptIn(ExperimentalTestApi::class) @Test fun test() = runDesktopComposeUiTest { setContent { App() } val roborazziOptions = RoborazziOptions( recordOptions = RoborazziOptions.RecordOptions( resizeScale = 0.5 ), compareOptions = RoborazziOptions.CompareOptions( changeThreshold = 0F ) ) onRoot().captureRoboImage(roborazziOptions = roborazziOptions) onNodeWithTag("button").performClick() onRoot().captureRoboImage(roborazziOptions = roborazziOptions) } }

Then, you can run the Gradle tasks for Desktop Support, just like you do for Android Support.

./gradlew recordRoborazzi[SourceSet]
./gradlew recordRoborazziDesktop ./gradlew compareRoborazziDesktop ./gradlew verifyRoborazziDesktop ...

If you use the Kotlin JVM plugin, the task will be recordRoborazzi**Jvm**.

The sample image

MainJvmTest test MainJvmTest test_2

Last modified: 12 July 2026