Configuração de testes avançados

As páginas Testar no Android Studio e Testar na linha de comando explicam como definir e executar configurações básicas de teste. No entanto, quando o aplicativo e os requisitos de teste forem mais avançados, talvez seja necessário adaptar ainda mais as configurações. Por exemplo, talvez você precise configurar um teste avançado quando quiser:

  • executar testes instrumentados somente para uma variante de build específica ou substituir as configurações do manifesto;
  • mudar o tipo de build em que os testes são executados ou configurar as opções do Gradle;
  • extrair seus testes instrumentados no próprio módulo de teste.

Esta página descreve várias maneiras de configurar testes quando as configurações padrão não se encaixarem no caso de uso em questão.

Criar um teste instrumentado para uma variante de build

Se o projeto incluir variantes de build com conjuntos de origem únicos, convém incluir testes instrumentados correspondentes. Fazer isso mantém o código de teste organizado e permite executar apenas testes que se apliquem a variantes de build específicas.

Você pode vincular testes instrumentados a uma variante de build os colocando no próprio conjunto de origem, localizado em src/androidTestVariantName.

Os testes instrumentados no conjunto de origem src/androidTest/ são compartilhados por todas as variantes de build. Ao criar um APK de teste para a variante "MyFlavor" do app, o Gradle combina os conjuntos de origem src/androidTest/ e src/androidTestMyFlavor/.

Para adicionar um conjunto de origem de teste à sua variante de build no Android Studio, siga estas etapas:

  1. Na janela Project à esquerda, clique no menu suspenso e selecione a visualização Project.
  2. Na pasta do módulo adequado, clique com o botão direito do mouse na pasta src e depois em New > Directory.
  3. Como nome do diretório, digite "androidTestNomeDaVariante". Por exemplo, se você tiver uma variante de build denominada "MyFlavor", o nome do diretório vai ser "androidTestMyFlavor". Clique em OK.
  4. Clique com o botão direito no novo diretório e depois em New > Directory.
  5. Nomeie o diretório como "java" e clique em OK.

Agora você pode adicionar testes a esse novo conjunto de origem seguindo as etapas para adicionar um novo teste. Ao ver a caixa de diálogo Choose Destination Directory, selecione o novo conjunto de origem de teste da variante.

Na tabela abaixo, mostramos um exemplo de como os arquivos de teste de instrumentação podem ficar nos conjuntos de origem correspondentes aos do código do app.

Tabela 1. O código-fonte do app e os arquivos de teste de instrumentação correspondentes.

Caminho para a classe do app Caminho para a classe de teste de instrumentação correspondente
src/main/java/Foo.java src/androidTest/java/AndroidFooTest.java
src/myFlavor/java/Foo.java src/androidTestMyFlavor/java/AndroidFooTest.java

Da mesma forma que nos conjuntos de origem do app, o build do Gradle mescla e substitui arquivos de diferentes conjuntos de origem de teste. Nesse caso, o arquivo AndroidFooTest.java no conjunto de origem androidTestMyFlavor substitui a versão no conjunto de origem androidTest. Isso acontece porque o conjunto de origem da variação de produto tem prioridade sobre o conjunto de origem principal. Para ver mais informações sobre como os conjuntos de origem são mesclados, consulte Configurar o build.

Definir configurações do manifesto de instrumentação

Testes instrumentados são criados em um APK separado, com o próprio arquivo AndroidManifest.xml. Quando o Gradle cria seu APK de teste, ele gera automaticamente o arquivo AndroidManifest.xml e o configura com o nó <instrumentation>. Um dos motivos para o Gradle configurar esse nó é garantir que a propriedade targetPackage especifique o nome de pacote correto do app em teste. Você pode mudar algumas das configurações desse nó criando outro arquivo de manifesto no conjunto de origem do teste ou configurando o arquivo build.gradle de nível de módulo, conforme mostrado no exemplo de código abaixo. A lista completa de opções pode ser encontrada na referência da API BaseFlavor.

android {

    ...

    // Each product flavor you configure can override properties in the
    // defaultConfig {} block. To learn more, go to Configure product flavors.

    defaultConfig {

        ...

        // Specifies the application ID for the test APK.
        testApplicationId = "com.test.foo"

        // Specifies the fully-qualified class name of the test instrumentation
        // runner.
        testInstrumentationRunner = "android.test.InstrumentationTestRunner"

        // If set to true, enables the instrumentation class to start and stop profiling.
        // If set to false (default), profiling occurs the entire time the instrumentation
        // class is running.
        testHandleProfiling = true

        // If set to true, indicates that the Android system should run the instrumentation
        // class as a functional test. The default value is false.
        testFunctionalTest = true

    }
}

Mudar o tipo de build de teste

Por padrão, todos os testes de instrumentação são executados no tipo de build debug. A fim de mudar para outro tipo de build, use a propriedade testBuildType no arquivo build.gradle de nível de módulo. Por exemplo, se você quiser executar os testes no tipo de build staging, edite o arquivo conforme mostrado no snippet abaixo.

android {

    ...

    testBuildType "staging"

}

Configurar opções de teste do Gradle

O Plug-in do Android para Gradle permite especificar algumas opções para todos os testes ou apenas alguns deles. No arquivo build.gradle de nível de módulo, use o bloco testOptions{} para especificar opções que mudem a forma como o Gradle executa todos os testes.

Groovy

android {
    ...
    // Encapsulates options for running tests.
    testOptions {
        // Changes the directory where Gradle saves test reports. By default,
        // Gradle saves test reports in the
        // path_to_your_project/module_name/build/outputs/reports/ directory.
        // '$rootDir' sets the path relative to the root directory of the
        // current project.
        reportDir "$rootDir/test-reports"
        // Changes the directory where Gradle saves test results. By default,
        // Gradle saves test results in the
        // path_to_your_project/module_name/build/outputs/test-results/ directory.
        // '$rootDir' sets the path relative to the root directory of the
        // current project.
        resultsDir "$rootDir/test-results"
    }
}

Kotlin

android {
    ...
    // Encapsulates options for running tests.
    testOptions {
        // Changes the directory where Gradle saves test reports. By default,
        // Gradle saves test reports in the
        // path_to_your_project/module_name/build/outputs/reports/ directory.
        // '$rootDir' sets the path relative to the root directory of the
        // current project.
        reportDir "$rootDir/test-reports"
        // Changes the directory where Gradle saves test results. By default,
        // Gradle saves test results in the
        // path_to_your_project/module_name/build/outputs/test-results/ directory.
        // '$rootDir' sets the path relative to the root directory of the
        // current project.
        resultsDir = "$rootDir/test-results"
    }
}

Para especificar opções exclusivas de testes de unidades locais, configure o bloco unitTests{} em testOptions{}.

Groovy

android {
    ...
    testOptions {
        ...
        // Encapsulates options for local unit tests.
        unitTests {
            // By default, local unit tests throw an exception any time the code
            // you are testing tries to access Android platform APIs (unless you
            /// mock Android dependencies yourself or with a testing framework like Mockito).
            // However, you can enable the following property so that the test
            // returns either null or zero when accessing platform APIs, rather
            // than throwing an exception.
            returnDefaultValues true

            // Encapsulates options for controlling how Gradle executes local
            // unit tests. For a list of all the options you can specify, read
            // Gradle's reference documentation.
            all {
                // Sets JVM argument(s) for the test JVM(s).
                jvmArgs '-XX:MaxPermSize=256m'

                // You can also check the task name to apply options to only the
                // tests you specify.
                if (it.name == 'testDebugUnitTest') {
                    systemProperty 'debug', 'true'
                }
                ...
            }
        }
    }
}

Kotlin

android {
    ...
    testOptions {
        ...
        // Encapsulates options for local unit tests.
        unitTests {
            // By default, local unit tests throw an exception any time the code
            // you are testing tries to access Android platform APIs (unless you
            /// mock Android dependencies yourself or with a testing framework like Mockito).
            // However, you can enable the following property so that the test
            // returns either null or zero when accessing platform APIs, rather
            // than throwing an exception.
            returnDefaultValues = true

            // Encapsulates options for controlling how Gradle executes local
            // unit tests. For a list of all the options you can specify, read
            // Gradle's reference documentation.
            all {
                // Sets JVM argument(s) for the test JVM(s).
                jvmArgs = listOf("-XX:MaxPermSize=256m")

                // You can also check the task name to apply options to only the
                // tests you specify.
                if (it.name == "testDebugUnitTest") {
                    systemProperty = mapOf("debug" to "true")
                }
                ...
            }
        }
    }
}

Usar módulos de teste diferentes para testes instrumentados

Se você quer usar um módulo dedicado para testes instrumentados e isolar o restante do código dos testes, crie um módulo de teste separado e configure o build de maneira semelhante à de um módulo de biblioteca. Para criar um módulo de teste, siga estas etapas:

  1. Crie um módulo de biblioteca.
  2. No arquivo build.gradle de nível de módulo, aplique o plug-in com.android.test em vez de com.android.library.
  3. Clique em Sync Project para sincronizar o projeto.

Depois de criar o módulo de teste, você pode incluir o código de teste no conjunto de origem principal ou variante (por exemplo, src/main/java ou src/variant/java). Se o módulo do app definir diversas variações de produto, você pode as recriar no módulo de teste, e, usando o gerenciamento de dependências com reconhecimento de variantes, o módulo de teste vai tentar testar a variação correspondente no módulo de destino.

Por padrão, os módulos de teste contêm e testam apenas uma variante de depuração. No entanto, você pode criar novos tipos de build que correspondam ao projeto de app testado. Para fazer o módulo testar outro tipo de build que não o de depuração, use VariantFilter a fim de desativar a variante no projeto de teste, conforme mostrado abaixo:

Groovy

android {
    variantFilter { variant ->
        if (variant.buildType.name.equals('debug')) {
            variant.setIgnore(true);
        }
    }
}

Kotlin

android {
    variantFilter {
        if (buildType.name == "debug") {
            ignore = true
        }
    }
}

Caso queira que um módulo de teste seja direcionado apenas a determinadas variações ou tipos de build de um app, você pode usar a propriedade matchingFallbacks para selecionar apenas as variantes que quer testar. Isso também impede que o módulo de teste precise configurar essas variantes por conta própria.