AndroidTesting

Android UI Tests with launch arguments

User interface (UI) testing lets you ensure that your app meets its functional requirements and achieves a high standard of quality. Common scenarios for UI testing consists of a set of steps which have to be fulfilled in order for a test to succeed. This steps usually can be easily recorded with Espresso Test Recorder and later adjusted with some code cleanup.

However, UI testing has some other usage. For example, it can be used for automated screenshots generation with Fastlane. When we run an automated screenshots generation, it’s pretty common that we want our App to display some predefined data (e.g. texts or pictures) which will look stunning on a final screenshot. Maintaining an App with such state of data in the simulator can be difficult and error prone. Much easier solution would be to start an application with some set of arguments. Such arguments can be later used to display a placeholder images or populate a database.

One way to implement such a solution is to use Intents mechanism combined with ActivityTestRules.

@Rule
var activityRule = ActivityTestRule(MainActivity::class.java)

By default ActivityTestRule starts an Activity before each test. However, this behaviour can be adjusted and we can prevent the activity from being started by passing false as third argument (launchActivity) to ActivityTestRuleConstructor.

@Rule
var activityRule = ActivityTestRule(MainActivity::class.java, false, false)

We can then create an Intent, put extra arguments into it and start the activity.

val i = Intent()
i.putExtra("testArg", "testValue")
activityRule.launchActivity(i)

This code should result in starting an Activity with our intent. The data which we passed to our intent with putExtra method can be accessed inside our Activity in onCreate() or onResume() methods.

override fun onResume() {
   super.onResume()
   val testValue = intent.extras?.getString("testArg")
   // do something with testValue
}

We can go one step further and create a helper method extension for ActivityTestRule which will start the Activity with a hashMap of arguments. Such function can be easily reused later.

fun ActivityTestRule<out Activity>.launchActivityWith(arguments: HashMap<String, String>) {
    val i = Intent()
    for ((key, value) in arguments) {
        i.putExtra(key, value)
    }

    this.launchActivity(i)
}

A full sample code will look like this.

class UITestsWithArguments {

    @Rule
    var activityRule = ActivityTestRule(MainActivity::class.java, false, false)

    @Test
    fun testArguments() {
        activityRule.launchActivityWith(hashMapOf(
                "user" to "testUser",
                "imagePlaceholder" to "image-placeholder1.png"
        ))
    }
}

fun ActivityTestRule<out Activity>.launchActivityWith(arguments: HashMap<String, String>) {
    val i = Intent()
    for ((key, value) in arguments) {
        i.putExtra(key, value)
    }

    this.launchActivity(i)
}

This way we can easily pass some extra data to the tested application.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.