I am trying to write some UI tests with UIAutomator on Android. I need to use UIAutomator to perform the following actions:
Could anyone please give me an example ? Thanks!
UiDevice
& UiObject2
tests classes offer arbitrary timeout wait period associated to the matching condition before proceeding in tests.
Notice that the timeout value is the maximum amount of time to wait in milliseconds before declaring that the condition is not met; so it doesn't sleep your test until the timeout period expires; instead it tries to match the condition (finding a matched component for instance) and once the condition is met, the test continues without waiting the expiration of the timeout value.
So, you can assign an arbitrary value that can make sure that the test succeeds. So, it's safe if you want to set it to Long.MAX_VALUE
; but make sure that should succeed to avoid ANR. In the below example, I am using 500 milliseconds.
For instance to launch an app, and wait for it to appear as per documentation:
var device: UiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
....
// Wait for the app to appear
device.wait(
Until.hasObject(By.pkg(BASIC_SAMPLE_PACKAGE).depth(0)), // condition
LAUNCH_TIMEOUT // timeout
)
}
Similarly, you can wait/timeout until you can find the target component at the second activity, before proceeding in the test; something like:
val someView = mDevice.wait(
Until.findObject(
By.res( // find object by resource id
BASIC_SAMPLE_PACKAGE, // application package name
"myViewId" // id of the view in the second activity
)
),
500) /* wait 500ms */
So, in your test that you are trying to do, you need to:
Use the @Before test method (that precedes any test) to make sure the app is launched and its main actvivity is shown:
private lateinit var mDevice: UiDevice
private val BASIC_SAMPLE_PACKAGE = "com.example.android......" // change this to your app's package name
private val LAUNCH_TIMEOUT = 5000L
@Before
fun startMainActivityFromHomeScreen() {
// Initialize UiDevice instance
mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
// Start from the home screen
mDevice.pressHome()
// Wait for launcher
val launcherPackage = getLauncherPackageName()
assertThat(launcherPackage, CoreMatchers.notNullValue())
mDevice.wait(
Until.hasObject(By.pkg(launcherPackage).depth(0)),
LAUNCH_TIMEOUT
)
// Launch the blueprint app
val context = ApplicationProvider.getApplicationContext<Context>()
val intent = context.packageManager
.getLaunchIntentForPackage(BASIC_SAMPLE_PACKAGE)
intent!!.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK) // Clear out any previous instances
context.startActivity(intent)
// Wait for the app to appear
mDevice.wait(
Until.hasObject(
By.pkg(BASIC_SAMPLE_PACKAGE)
.depth(0)
),
LAUNCH_TIMEOUT
)
}
Then to press on a button to launch the second activity:
// searching for a UI component with a resource Id btn_goto_second
val secondActivityButton = mDevice.wait(
Until.findObject(
By.res(
BASIC_SAMPLE_PACKAGE,
"btn_goto_second" // change to your button id
)
),
500 /* wait 500ms */
)
// Perform a click on the button to load the second activity.
secondActivityButton.click()
Then to enter some text to an EditText
at the second activity; you can just wait until you find this view; and then type some text:
// searching for the EditText component with a resource Id edit_text
val editText = mDevice.wait(
Until.findObject(
By.res(
BASIC_SAMPLE_PACKAGE,
"edit_text" // change this to yoru editText id
)
),
500 /* wait 500ms */
)
// Set the text to the EditText
editText.text = "some text"
And to verify the text result, use one of the assertion methods:
assertThat(
editText.text,
CoreMatchers.`is`(equalTo("some text"))
)
You can check the documentation for further help; or refer to their sample app. Also this is a nice repo that would help.