Aggiungere test di Espresso e UiAutomator a un'app Surface DuoAdd Espresso and UiAutomator tests to your Surface Duo app

Espresso e UiAutomator sono entrambi framework di test forniti dalle librerie AndroidX.Espresso and UiAutomator are both testing frameworks provided by AndroidX libraries. Espresso viene usato per trovare elementi di interfaccia utente all'interno di un'app e interagire con tali elementi, mentre UiAutomator offre funzionalità di test tra app e l'accesso ai sensori dei dispositivi.Espresso is used to find and interact with UI elements within an app, while UiAutomator provides cross-app testing functionality and access to device sensors.

Per altre informazioni su questi framework di test, vedere le risorse seguenti:To learn more about these testing frameworks, check out these resources:

Nel progetto di Android Studio questi test dell'interfaccia utente verranno scritti nella sezione androidTest, dove il file di test predefinito è denominato ExampleInstrumentedTest.In your Android Studio Project, you'll be writing these UI tests in the androidTest section, where the default test file is named ExampleInstrumentedTest. Prima di eseguire i test dell'interfaccia utente, ricordarsi di disabilitare le animazioni nel dispositivo.And remember, disable animations on your device before running your UI tests.

DipendenzeDependencies

Aggiungere le dipendenze seguenti al file build.gradle dell'app:Add the following dependencies to your app's build.gradle file:

android {
    defaultConfig {
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
}

dependencies {
    testImplementation "junit:junit:4.13"
    androidTestImplementation "androidx.test.ext:junit:1.1.1"
    androidTestImplementation "androidx.test.espresso:espresso-core:3.2.0"
    androidTestImplementation "androidx.test:runner:1.2.0"
    androidTestImplementation "androidx.test:rules:1.2.0"
    androidTestImplementation "androidx.test.uiautomator:uiautomator:2.2.0"
}

Se si esegue il test con una WebView, alla sezione dependecies è necessario aggiungere anche androidTestImplementation "androidx.test.espresso:espresso-web:3.2.0".If testing with a WebView, androidTestImplementation "androidx.test.espresso:espresso-web:3.2.0" should also be added to the dependencies section.

Nota

Se si usa un file dependencies.gradle separato, vedere il repository degli esempi app per visualizzare esempi di come aggiungere le dipendenze necessarie.If using a separate dependencies.gradle file, see the app samples repo for examples of how the add the necessary dependencies.

Creare regole per i testCreate rules for tests

Ai test è possibile aggiungere regole JUnit per specificare informazioni aggiuntive sui test successivi.JUnit rules can be added to your tests to specify additional information about subsequent tests. Una delle regole più comuni è quella di definire un'attività principale a cui applicare i test, come illustrato di seguito:One of the most common rules used is to define a main activity for the tests to be applied to, as shown below:

@RunWith(AndroidJUnit4::class)
class PhotoEditorUITest {
    @get:Rule
    val activityRule = ActivityTestRule(MainActivity::class.java)
}

Scrivere test a doppio schermoWrite dual-screen tests

Informazioni di baseBasics

Usare la classe UiDevice fornita da UiAutomator per trovare il dispositivo e modificare le relative configurazioni di spanning/rotazione. Usare quindi Espresso per verificare che gli elementi dell'interfaccia utente si comportino come previsto.Use the UiDevice class provided by UiAutomator to find your device and change its spanning/rotation configurations, and then use Espresso to check that UI elements behave as expected.

Come illustrato nell'esempio seguente, è possibile usare il metodo swipe per simulare spanning e unspanning.As shown in the example below, the swipe method can be used to simulate spanning and unspanning. Per migliorare più possibile l'affidabilità dei test, provare a raggruppare i test per i quali è necessaria la stessa configurazione in modo da non dover eseguire più richieste di spanning e unspanning.To make your tests are as reliable as possible, try to group tests together that need the same configuration so you don’t have to make multiple spanning and unspanning requests.

@Test
fun testSpan() {
    val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())

    // Span the app (from the left side)
    device.swipe(675, 1780, 1350, 900, 400)

    // Test that UI element appears
    onView(withId(R.id.yourElement)).check(matches(isDisplayed()))

    // Unspan the app (to the left side)
    // device.swipe(2109, 1780, 675, 900, 200)

    // Test that UI element has disappeared
    // onView(withId(R.id.yourElement)).check(matches(not(isDisplayed())))
}

Altre funzioni utili di UiAutomator includono setOrientationNatural, unfreezeRotation e pressHome.Other useful UiAutomator functions include setOrientationNatural, unfreezeRotation, and pressHome. Se si vuole testare la funzionalità tra app, è possibile usare UiAutomator anche per avviare altre app.If you want to test cross-app functionality, you can also use UiAutomator to launch other apps.

Funzioni helperHelper functions

È possibile usare queste funzioni helper di base per simulare il comportamento di spanning:These basic helper functions can be used for simulating spanning behavior:

companion object {
    // testing device
    val device: UiDevice = UiDevice.getInstance(getInstrumentation())

    // Swipe constants
    const val leftX: Int = 675          // middle of left screen
    const val rightX: Int = 2109        // middle of right screen
    const val middleX: Int = 1350       // hinge area
    const val bottomY: Int = 1780       // bottom of screen
    const val middleY: Int = 900        // middle of screen
    const val spanSteps: Int = 400      // spanning swipe
    const val unspanSteps: Int = 200    // unspanning swipe
    const val switchSteps: Int = 100    // swipe to switch from one screen to the other
    const val closeSteps: Int = 50      // swipe to close app
}

private fun spanFromLeft() {
    device.swipe(leftX, bottomY, middleX, middleY, spanSteps)
}

private fun unspanToLeft() {
    device.swipe(rightX, bottomY, leftX, middleY, unspanSteps)
}

private fun spanFromRight() {
    device.swipe(rightX, bottomY, middleX, middleY, spanSteps)
}

private fun unspanToRight() {
    device.swipe(leftX, bottomY, rightX, middleY, unspanSteps)
}

private fun switchToLeft() {
    device.swipe(rightX, bottomY, leftX, middleY, switchSteps)
}

private fun switchToRight() {
    device.swipe(leftX, bottomY, rightX, middleY, switchSteps)
}

private fun closeLeft() {
    device.swipe(leftX, bottomY, leftX, middleY, closeSteps)
}

private fun closeRight() {
    device.swipe(rightX, bottomY, rightX, middleY, closeSteps)
}

Per verificare se un'app è estesa, definire una regola che si colleghi all'attività principale e usarla per sostituire activityRule in questa funzione:To test if an app is spanned, define a rule that connects to the main activity and use it to replace activityRule in this function:

private fun isSpanned(): Boolean {
    onIdle() // wait until layout changes have been fully processed before checking
    return ScreenHelper.isDualMode(activityRule.activity)
}

Per accertarsi che tutte le funzioni helper funzionino come previsto, aggiungere import org.hamcrest.CoreMatchers.`is` as iz alle istruzioni di importazione e quindi eseguire il test seguente:To make sure all of the helper functions work as expected, add import org.hamcrest.CoreMatchers.`is` as iz to your import statements and then run the following test:

/**
 * Runs helper functions and checks that they work as expected
 *
 * @precondition device in portrait mode, no other applications are open
 * (so app by default opens on left screen)
 */
@Test
fun testSpanningHelperFunctions() {
    spanFromLeft()
    assertThat(isSpanned(), iz(true))

    unspanToRight()
    assertThat(isSpanned(), iz(false))

    spanFromRight()
    assertThat(isSpanned(), iz(true))

    unspanToLeft()
    assertThat(isSpanned(), iz(false))

    switchToRight()
    switchToLeft()
    closeLeft()
}

Suggerimenti per la risoluzione dei problemiTroubleshooting tips

Se il test testSpanningHelperFunctions ha esito negativo o si verificano altri problemi di test:If the testSpanningHelperFunctions test fails or you encounter other testing issues:

  • Modificare le costanti dei passaggi: è necessario che determinati movimenti siano sufficientemente lenti da poter essere elaborati correttamente.Adjust the step constants - certain gestures need to be slow enough to ensure they are processed correctly. 100 passaggi impiegano circa 0,5 secondi.100 steps take approximately 0.5 seconds.
  • Modificare le costanti x e y, che rappresentano valori di pixel sullo schermo.Change the x and y constants, which represent pixel values on the screen. Ogni schermo è 1350 x 1800 px e il gap della cerniera ha una larghezza di 84 px (Dimensioni di Surface Duo).Each screen is 1350 x 1800 px, and the hinge gap is 84 px wide (Surface Duo dimensions).
  • Aggiungere IdlingResources ai test che caricano dati o eseguono altre operazioni asincrone che possono influire sui test dell'interfaccia utente.Add IdlingResources to tests that load data or perform other asynchronous operations that may affect UI tests.

RiepilogoSummary

I test dell'interfaccia utente per le app di Surface Duo possono essere eseguiti usando una combinazione dei framework di test Espresso e UiAutomator.UI testing for Surface Duo apps can be accomplished by using a combination of the Espresso and UiAutomator testing frameworks. Nella maggior parte dei casi, il metodo swipe di UiAutomator è sufficiente per simulare eventi a doppio schermo. Può essere quindi usato normalmente Espresso per interagire con gli elementi dell'interfaccia utente nell'app di Surface Duo.In most cases, the swipe method from UiAutomator is all you need to simulate dual-screen events, and then Espresso can be used normally to interact with UI elements in your Surface Duo app.

Per alcuni esempi di test dell'interfaccia utente nelle app di Surface Duo, consultare le risorse seguenti:For examples of UI testing in Surface Duo apps, check out these resources: