Skip to content

Robolectric

The Robolectric integration brings Robolectric's fast, reliable and configurable Android testing to TestBalloon:

  • All TestBalloon capabilities are available in Robolectric test suites, including parameterized tests, nested test suites and test fixtures.
  • The Robolectric environment can be fully configured in plain Kotlin, using a DSL, without resorting to annotations.

Getting started🔗

  1. Add the integration's dependency for Android host-side tests:

    named("androidHostTest") { // (1)!
        dependencies {
            implementation("de.infix.testBalloon:testBalloon-integration-robolectric:$testBalloonVersion")
            implementation("junit:junit:$junit4Version")
        }
    }
    
    1. Using the com.android.kotlin.multiplatform.library plugin.
    dependencies {
        testImplementation("de.infix.testBalloon:testBalloon-integration-robolectric:$testBalloonVersion")
        testImplementation("junit:junit:$junit4Version")
    }
    
  2. Register a Robolectric test suite with robolectricTestSuite:

    robolectricTestSuite( // (1)!
        "API level $apiLevel",
        MyRobolectricTests::class, // (2)!
        testConfig = TestConfig.robolectric { // (3)!
            sdk = apiLevel
            qualifiers = "xlarge-port"
            applicationLifetime = ApplicationLifetime.RobolectricTestSuite
        }
    ) // (4)!
    
    1. Registers a Robolectric test suite. This must occur inside an existing test suite.
    2. Specifies the class which will contain the test suite's content.
    3. Configure Robolectric as desired. As usual, this can also be done higher up in TestBalloon's test element hierarchy.
    4. There is no trailing lambda because the test suite's content resides in a separate class.
  3. Add the Robolectric test suite contents to a separate class derived from RobolectricTestSuiteContent:

    internal class MyRobolectricTests : // (1)!
        RobolectricTestSuiteContent({ // (2)!
            test("Application exists") {
                val application = getApplicationContext<Application>()
                assertNotNull(application)
            }
    
            testSuite("Details") {
                test("Motion event sources are supported, but not present") {
                    // Added in API level 34
                    assertEquals(0, AccessibilityServiceInfo().motionEventSources)
                }
    
                test("Screen size is 'xlarge'") {
                    assertContains(RuntimeEnvironment.getQualifiers(), "xlarge")
                }
            }
        })
    
    1. This class will be dynamically loaded by Robolectric's sandbox class loader.
    2. The RobolectricTestSuiteContent base class handles all TestBalloon integration.

    Note

    Robolectric test suites do not nest. You cannot invoke robolectricTestSuite inside RobolectricTestSuiteContent.

Configuration🔗

TestConfig.robolectric { ... } configures all Robolectric settings via a DSL.

As with any other TestConfig configuration, Robolectric settings can be configured at any level of the test element hierarchy, including globally. Settings are inherited, but can be overridden at lower levels.

Note

Settings become effective wherever a robolectricTestSuite appears. Settings appearing inside a Robolectric test suite have no effect.

robolectricTestSuite has an arguments parameter which you can use to pass values to constructor parameters of the corresponding test suite content class.

Info

arguments is the boundary where types and values travel between the "normal" JVM world and the Robolectric environment. By default, Robolectric will re-load all classes it encounters with its own sandbox class loader, making them incompatible with the "same" classes in the JVM world.

To make a class MyType and all classes in com.example.mypackage portable between those worlds, add the following testConfig parameter to the robolectricTestSuite invocation (or anywhere above it in the test element hierarchy):

testConfig = TestConfig.robolectric {
    portableClasses += MyType::class
    portablePackages += "com.example.mypackage"
}

Robolectric Resources🔗