Criar testes de unidade de instrumentação

Testes de unidade de instrumentação são testes executados em dispositivos físicos e emuladores. Eles podem usar as APIs do framework do Android e as de suporte, como a AndroidX Test. Os testes de instrumentação proporcionam um nível de fidelidade maior do que os testes de unidade locais, mas são executados muito mais lentamente. Portanto, recomendamos o uso de testes de unidade de instrumentação apenas nos casos em que você precisa testar o comportamento de um dispositivo real. A AndroidX Test oferece várias bibliotecas que facilitam a programação de testes de unidade de instrumentação quando necessário. Por exemplo, as classes do Builder Android facilitam a criação de objetos de dados Android.

Observação: se os testes se baseiam nas suas dependências, disponibilize as próprias falsificações ou imite as dependências usando um framework fictício, como o Mockito (em inglês).

Configurar seu ambiente de teste

No projeto do Android Studio, é preciso armazenar os arquivos de origem para testes de instrumentação em module-name/src/androidTest/java/. Esse diretório já existe quando você cria um novo projeto e contém um exemplo de teste de instrumentação.

Antes de começar, adicione APIs do AndroidX Test, que permitem criar e executar rapidamente um código de teste de instrumentação para seus apps. O AndroidX Test inclui um executor de testes JUnit 4 (AndroidJUnitRunner) e APIs para testes funcionais de IU (Espresso e UI Automator).

Você também precisa configurar as dependências de teste do Android para que seu projeto use o executor e as APIs de regras disponibilizados pelo AndroidX Test. Para simplificar o desenvolvimento do teste, inclua também a biblioteca Hamcrest, que permite criar asserções mais flexíveis usando as APIs de matchers do Hamcrest.

No arquivo build.gradle de nível superior do app, é necessário especificar estas bibliotecas como dependências:

    dependencies {
        androidTestImplementation 'androidx.test:runner:1.1.0'
        androidTestImplementation 'androidx.test:rules:1.1.0'
        // Optional -- Hamcrest library
        androidTestImplementation 'org.hamcrest:hamcrest-library:1.3'
        // Optional -- UI testing with Espresso
        androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'
        // Optional -- UI testing with UI Automator
        androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0'
    }
    

Para usar as classes de teste do JUnit 4, especifique AndroidJUnitRunner como o executor de instrumentação de teste padrão no projeto incluindo a seguinte configuração no arquivo build.gradle do módulo do app:

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

Criar uma classe de teste de unidade de instrumentação

Sua classe de teste de unidade de instrumentação deve ser uma classe de teste do JUnit 4 àquela descrita na seção sobre como Criar uma classe de teste de unidade local.

Para criar uma classe de teste de instrumentação do JUnit 4, especifique AndroidJUnit4 como o executor de teste padrão.

Observação: se seu conjunto de testes depende de uma combinação de bibliotecas JUnit3 e JUnit4, adicione a anotação @RunWith(AndroidJUnit4::class) no início da definição da sua classe de teste.

O exemplo a seguir mostra como é possível programar um teste de unidade de instrumentação para verificar se a interface Parcelable foi implementada corretamente para a classe LogHistory:

Kotlin

    import android.os.Parcel
    import android.text.TextUtils.writeToParcel
    import androidx.test.filters.SmallTest
    import androidx.test.runner.AndroidJUnit4
    import com.google.common.truth.Truth.assertThat
    import org.junit.Before
    import org.junit.Test
    import org.junit.runner.RunWith

    const val TEST_STRING = "This is a string"
    const val TEST_LONG = 12345678L

    // @RunWith is required only if you use a mix of JUnit3 and JUnit4.
    @RunWith(AndroidJUnit4::class)
    @SmallTest
    class LogHistoryAndroidUnitTest {
        private lateinit var logHistory: LogHistory

        @Before
        fun createLogHistory() {
            logHistory = LogHistory()
        }

        @Test
        fun logHistory_ParcelableWriteRead() {
            val parcel = Parcel.obtain()
            logHistory.apply {
                // Set up the Parcelable object to send and receive.
                addEntry(TEST_STRING, TEST_LONG)

                // Write the data.
                writeToParcel(parcel, describeContents())
            }

            // After you're done with writing, you need to reset the parcel for reading.
            parcel.setDataPosition(0)

            // Read the data.
            val createdFromParcel: LogHistory = LogHistory.CREATOR.createFromParcel(parcel)
            createdFromParcel.getData().also { createdFromParcelData: List<Pair<String, Long>> ->

                // Verify that the received data is correct.
                assertThat(createdFromParcelData.size).isEqualTo(1)
                assertThat(createdFromParcelData[0].first).isEqualTo(TEST_STRING)
                assertThat(createdFromParcelData[0].second).isEqualTo(TEST_LONG)
            }
        }
    }

    

Java

    import android.os.Parcel;
    import android.util.Pair;
    import androidx.test.filters.SmallTest;
    import androidx.test.runner.AndroidJUnit4;
    import com.google.common.truth.Truth.assertThat;
    import java.util.List;
    import org.junit.Before;
    import org.junit.Test;
    import org.junit.runner.RunWith;

    // @RunWith is required only if you use a mix of JUnit3 and JUnit4.
    @RunWith(AndroidJUnit4.class)
    @SmallTest
    public class LogHistoryAndroidUnitTest {

        public static final String TEST_STRING = "This is a string";
        public static final long TEST_LONG = 12345678L;
        private LogHistory mLogHistory;

        @Before
        public void createLogHistory() {
            mLogHistory = new LogHistory();
        }

        @Test
        public void logHistory_ParcelableWriteRead() {
            // Set up the Parcelable object to send and receive.
            mLogHistory.addEntry(TEST_STRING, TEST_LONG);

            // Write the data.
            Parcel parcel = Parcel.obtain();
            mLogHistory.writeToParcel(parcel, mLogHistory.describeContents());

            // After you're done with writing, you need to reset the parcel for reading.
            parcel.setDataPosition(0);

            // Read the data.
            LogHistory createdFromParcel = LogHistory.CREATOR.createFromParcel(parcel);
            List<Pair<String, Long>> createdFromParcelData
                    = createdFromParcel.getData();

            // Verify that the received data is correct.
            assertThat(createdFromParcelData.size()).isEqualTo(1);
            assertThat(createdFromParcelData.get(0).first).isEqualTo(TEST_STRING);
            assertThat(createdFromParcelData.get(0).second).isEqaulTo(TEST_LONG);
        }
    }
    

Criar um conjunto de testes

Para organizar a execução dos seus testes de unidade de instrumentação, agrupe uma coleção de classes de testes em uma classe de conjunto de testes e execute-os juntos. Os conjuntos de testes podem ser aninhados. Além disso, eles podem agrupar outros conjuntos de testes e executar todas as classes de teste de componente relacionadas.

Um conjunto de testes fica em um pacote semelhante ao pacote principal do aplicativo. Por convenção, o nome do pacote do conjunto de testes geralmente termina com o sufixo .suite (por exemplo, com.example.android.testing.mysample.suite).

Para criar um conjunto para seus testes de unidade, importe as classes RunWith e Suite. No seu conjunto de testes, adicione as anotações @RunWith(Suite.class) e @Suite.SuitClasses(). Na anotação @Suite.SuiteClasses(), liste as classes de teste individuais ou os conjuntos de testes como argumentos.

O exemplo a seguir mostra como implementar um conjunto de testes denominado UnitTestSuite, que agrupa e executa as classes de testes CalculatorInstrumentationTest e CalculatorAddParameterizedTest juntas.

Kotlin

    import com.example.android.testing.mysample.CalculatorAddParameterizedTest
    import com.example.android.testing.mysample.CalculatorInstrumentationTest
    import org.junit.runner.RunWith
    import org.junit.runners.Suite

    // Runs all unit tests.
    @RunWith(Suite::class)
    @Suite.SuiteClasses(CalculatorInstrumentationTest::class,
            CalculatorAddParameterizedTest::class)
    class UnitTestSuite
    

Java

    import com.example.android.testing.mysample.CalculatorAddParameterizedTest;
    import com.example.android.testing.mysample.CalculatorInstrumentationTest;
    import org.junit.runner.RunWith;
    import org.junit.runners.Suite;

    // Runs all unit tests.
    @RunWith(Suite.class)
    @Suite.SuiteClasses({CalculatorInstrumentationTest.class,
            CalculatorAddParameterizedTest.class})
    public class UnitTestSuite {}
    

Executar testes de unidade de instrumentação

Para executar testes de instrumentação, siga estas etapas:

  1. Verifique se o projeto está sincronizado com o Gradle clicando em Sync Project , na barra de ferramentas.
  2. Execute o teste de uma das seguintes formas:
    • Para executar um único teste, abra a janela Project, clique com o botão direito do mouse em um teste e depois em Run .
    • Para testar todos os métodos de uma classe, clique com o botão direito do mouse em uma classe ou método no arquivo de teste e depois em Run .
    • Para executar todos os testes em um diretório, clique com o botão direito do mouse no diretório e selecione Run tests .

O plug-in do Android para Gradle compila o código do teste de instrumentação localizado no diretório padrão (src/androidTest/java/), cria um APK de teste e um APK de produção, instala os dois APKs no dispositivo ou emulador conectado e executa os testes. O Android Studio exibe os resultados da execução do teste de instrumentação na janela Run.

Executar testes com o Firebase Test Lab

Com o Firebase Test Lab, você pode testar seu app simultaneamente em vários dispositivos e configurações Android conhecidos (localidade, orientação, tamanho da tela e versão da plataforma). Esses testes são executados em dispositivos físicos e virtuais em data centers remotos do Google. Você pode implantar apps no Test Lab diretamente do Android Studio ou da linha de comando. Os resultados do teste incluem registros e os detalhes de qualquer falha do app.

A menos que você já tenha uma Conta do Google e um projeto do Firebase, faça o seguinte antes de começar a usar o Firebase Test Lab:

  1. Crie uma Conta do Google, caso ainda não tenha uma.
  2. No console do Firebase, clique em Create New Project.

    Dentro da cota gratuita diária do plano Spark, nenhuma cobrança é realizada para testar seu app com o Test Lab.

Configurar uma matriz de teste e executar um teste

O Android Studio oferece ferramentas integradas que permitem configurar a implantação dos seus testes no Firebase Test Lab. Depois de criar um projeto do Firebase com o faturamento do plano Blaze, você pode criar uma configuração para executar seus testes:

  1. No menu principal, clique em Run > Edit Configurations.
  2. Clique em Add New Configuration e selecione Android Tests.
  3. Na caixa de diálogo de configuração do Android Test:
    1. Digite ou selecione os detalhes do seu teste, como, nome, tipo de módulo, tipo de teste e classe de testes.
    2. No menu suspenso Target, em Deployment Target Options, selecione Firebase Test Lab Device Matrix.
    3. Se você não fez login, clique em Connect to Google Cloud Platform e permita o acesso do Android Studio à sua conta.
    4. Ao lado de Cloud Project, clique no botão e selecione seu projeto do Firebase na lista.
  4. Crie e configure uma matriz de testes:
    1. Ao lado da lista suspensa Matrix Configuration, clique em Open Dialog .
    2. Clique em Add New Configuration (+).
    3. No campo Name, insira um nome para sua nova configuração.
    4. Selecione os dispositivos, as versões do Android, as localidades e as orientações da tela com que você quer testar seu app. Ao gerar os resultados dos testes, o Firebase Test Lab testa seu app em relação a todas as combinações das suas escolhas.
    5. Clique em OK para salvar sua configuração.
  5. Clique em OK na caixa de diálogo Run/Debug Configurations para sair.
  6. Para executar seus testes, clique em Run .

Figura 1. Criação de uma configuração de teste para o Firebase Test Lab.

Analisar resultados do teste

Quando o Firebase Test Lab conclui a execução dos testes, a janela Run é aberta para mostrar os resultados, conforme mostrado na figura 2. Pode ser necessário clicar em Show Passed para ver todos os testes executados.

Figura 2. Visualização dos resultados de testes de instrumentação usando o Firebase Test Lab.

Você também pode analisar seus testes na Web por meio do link exibido no início do registro de execução de testes da janela Run.

Leia mais

Para saber mais sobre como interpretar resultados na Web, consulte Análise de resultados no Firebase Test Lab.

Outros recursos

Para saber mais sobre o uso do Espresso em testes do Android, consulte os recursos a seguir.

Exemplos

Codelabs