TheKnowhowTitan
TheKnowhowTitan

Reputation: 3

Is there a way to pass a Class variable to Espresso ActivityTestRule?

I am writing tests for Activities using Espresso. For each activity, the test looks something like this

@RunWith(AndroidJUnit4::class)
class TestSomeActivity {
    @get:Rule
    var activityTestRule = ActivityTestRule(SomeActivity::class.java, true, false)
    @Test
    fun testNullIntent() {
        val intent = Intent()
        activityTestRule.launchActivity(intent)
    }
}

What this does is whenever an Intent inside that Activity calls intent.getExtra, null is returned.

The problem is, if we are to check this for every activity the same code has to be written except for this line-

@get:Rule
var activityTestRule = ActivityTestRule(SomeActivity::class.java, true, false)

To solve this problem, I got the name of all the activities using PackageManager and converted them to Class. Then I tried passing this class to my activityTestRule.

val intent = Intent()
val activityInfoList = getAllActivities()
for(activityInfo in activityInfoList!!) {
    val className = activityInfo.applicationInfo.className
    val activityClass = Class.forName(className)
    val activityTestRule = ActivityTestRule(activityClass.javaClass, true, false)
    activityTestRule.launchActivity(intent)
}

Unfortunately, this resulted in compile time error-

None of the following functions can be called with the arguments supplied.
<init>(SingleActivityFactory<T!>!, Boolean, Boolean)   where T cannot be inferred for    constructor ActivityTestRule<T : Activity!>(activityFactory: SingleActivityFactory<T!>!, initialTouchMode: Boolean, launchActivity: Boolean) defined in androidx.test.rule.ActivityTestRule
<init>(Class<T!>!, Boolean, Boolean)   where T cannot be inferred for    constructor ActivityTestRule<T : Activity!>(activityClass: Class<T!>!, initialTouchMode: Boolean, launchActivity: Boolean) defined in androidx.test.rule.ActivityTestRule

To solve this we tried to convert activityClass to Activity using

val activityClass = Class.forName(className) as Activity
val activityTestRule = ActivityTestRule(activityUnderTest.javaClass, true, false)

which eliminated the compile time error but introduced java.lang.ClassCastException: java.lang.Class cannot be cast to android.app.Activity.

Is there a way to run the same Espresso script for all the activities in a class or pass a Class to ActivityTestRule?

Upvotes: 0

Views: 423

Answers (1)

Poorva Warghade
Poorva Warghade

Reputation: 26

Instead of this piece of code

val activityClass = Class.forName(className) as Activity

You can use the following

val activityClass = Class.forName(className) as Class<Activity>

This would ensure that you won't get the compile-time error, and the type-cast exception won't happen after you run your code.

Upvotes: 1

Related Questions