• After 15+ years, we've made a big change: Android Forums is now Early Bird Club. Learn more here.

How to run/invoke Instrumented Tests from within Android App code (MainActivity)

drnbg

Lurker
In the current arrangement, on Android, Instrumented Tests can be invoked by following approaches:

  1. From within Android Studio -> Right click on the class saved under "androidTest"
  2. Fire command adb shell am instrument -w com.example.testing/androidx.test.runner.AndroidJUnitRunner on CMD prompt.
But mine is unique requirement. As per my requirement, I would like to Run/Invoke these test cases (written inside classes saved under androidTest) from UI of the App code itself i.e. when user clicks on a button presented on the UI, the respective test case(s) get executed.

Following is the code written in "ExampleInstrumentedTest" saved under "androidTest" Folder:

Code:
package com.example.myapplication

import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.uiautomator.UiDevice

import org.junit.Test
import org.junit.runner.RunWith

import org.junit.Assert.*

/**
 * Instrumented test, which will execute on an Android device.
 *
 * See [testing documentation](http://d.android.com/tools/testing).
 */
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
    @Test
    fun testCaseForButton1() {
        val appContext = InstrumentationRegistry.getInstrumentation().targetContext
        //Filler step
        assertEquals("com.example.myapplication", appContext.packageName)
    }

    @Test
    fun testCaseForButton2() {
        val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
        //Filler step
        assertEquals("com.sec.android.app.launcher", device.launcherPackageName)
    }
}


Code in MainActivity():

Code:
override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        findViewById<Button>(R.id.buttonRunTest1)
            .setOnClickListener {
                //Invoke testCaseForButton1
            }

        findViewById<Button>(R.id.buttonRunTest2)
            .setOnClickListener {
                //Invoke testCaseForButton2
            }
    }


I read somewhere that "instrumented" tests can not be called/triggered from within App code. Also tried but failed with error "No instrumentation registered! Must run under a registering instrumentation"

Request help with code to be written inside the "OnClickListener".

Tried couple of approaches:

Code:
// Code to execute when the button is clicked
fun startTest(){
   val packageName = "com.example.myapplication"
   val testRunnerClass = "androidx.test.runner.AndroidJUnitRunner"
   val command = "am instrument -w $packageName/$testRunnerClass"
   Runtime.getRuntime().exec(command)
}


Code:
// Code to execute when the button is clicked
fun startTest(){
   val instrumentation = InstrumentationRegistry.getInstrumentation()
   val paramTypes = arrayOf(ComponentName::class.java, Bundle::class.java)
   val method = instrumentation.javaClass.getDeclaredMethod("startInstrumentation", *paramTypes)
}


My build.gradle:

Code:
    {
        ....
        defaultConfig {
            applicationId "com.example.myapplication"
            minSdk 28
            targetSdk 32
            versionCode 1
            versionName "1.0"

            testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
            ....
    }

Dependencies in build.gradle:

Code:
dependencies {
    ...
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.5'
    implementation 'androidx.test.uiautomator:uiautomator:2.2.0'
    implementation 'androidx.test:runner:1.4.0'
    androidTestImplementation 'androidx.test:runner:1.4.0'
    androidTestImplementation 'androidx.test:rules:1.5.0'
    ...
}


But nothing works. Ideally, it should invoke respective instrumented test cases.
 
Back
Top Bottom