Iniciando com Detox framework — 3/4
Utilize detox para saúde dos seus testes
Seguindo com a série de artigos para ajudar na configuração e execucação do detox, apresentamos a segunda parte onde iremos configurar as execuções para o Android.
Configurando um Ambiente de Desenvolvimento e Teste para Android
Este tutorial fornece algumas práticas fundamentais na configuração de um ambiente estável e confiável para operar testes automatizados de UI, usando os emuladores Android (Detox, em particular) — seja em um computador pessoal, local ou uma máquina poderosa de Integração Contínua (CI).
Note que operar testes UI automatizados está longe de ser como desenvolver apps para Android. Consequentemente, é possível não estar 100% de acordo com as recomendações aqui, mas, ainda assim, deveria considerá-las.
Instalação de Java
Esta é a etapa mais básica do processo, pois sem um SDK Java adequado instalado, nada derivado do Android funciona, pelo menos, não a partir da linha de comando, que é obrigatória para executar o Detox
.
É pressuposto que Android precisa do Java 1.8 instalado.
Para verificar a versão do seu executável java, no console de linha de comando, execute:
java --version
O que precisa ser verificado é se o java
está na pasta de instalação e que a saída contém algo como:
java version "1.8.0_121"
Ou seja, a versão é 1.8.x_abc
➢ Nota: Não confunda a versão Java potencialmente usada por seus navegadores etc. Para o
Detox
, o que a linha de comando vê é o que importa.
No MacOS, em particular, o java vem de OS e possivelmente de outros instaladores como homebrew
, então é provável que algumas coisas não estejam corretas: veja esta publicação no stackoverflow.
Se o java
não pode ser localizado ou nem sequer está instalado (ou seja, o comando falhou por completo), confira este tutorial.
Do contrário, se a versão simplesmente estiver errada, oriente-se por estas referências para Macs; considere aplicar a variável JAVA_HOME
para fazer com que as coisas funcionem:
- https://java.com/en/download/faq/java_mac.xml#version
- https://www.java.com/en/download/help/version_manual.xml
- https://medium.com/notes-for-geeks/java-home-and-java-home-on- macos-f246cab643bd
Android SDK
Caso tenha o Android Studio instalado, o SDK deve estar disponível em algum lugar na sua máquina*. No entanto, para os usuários de CI, possivelmente executando sem GUI, ou se simplesmente quiser esse software complexo em seu computador, é possível baixar o SDK e o conjunto de ferramentas separadamente. Ambos os casos são abordados no tutorial android do Google sobre o Android Studio. Para a opção das ferramentas puras, consulte a seção Command line tools online
no fim da página.
Para mais ajuda na configuração o SDK, este tutorial pode ser útil.
Seja qual for a opção e plataforma escolhida (Mac, Linux ou Windows), a preferência é que, eventualmente, 2 coisas sejam configuradas:
- O trajeto ao diretório raiz do SDK deve estar situado na variável ambiente do
ANDROID_SDK_ROOT
. - O trajeto ao diretório raiz do SDK deve estar localizado no
PATH
global em seu computador.
* Verifique o conteúdo das seguintes variáveis de ambiente: ANDROID_SDK_ROOT
e ANDROID_HOME
.
Emuladores (AOSP) Android
A automatização de aplicativos Mobile necessita de um dispositivo Android para execução. Caso ainda não possua um, é necessário configurar um emulador. Mas calma, não instale o modelo padrão ainda: primeiro leia com atenção.
Foi provado por muito tempo que para a automatização, a qual requer um ambiente estável e determinado, os emuladores do Google que funcionam com Google API simplesmente não fornecem o que é necessário. Seja com o Google Play Services já instalado — que tende a exigir bastante da CPU, ou mesmo do teclado gboard
do Google — que é completo, mas abundante. Esse tipo de aplicativo incentiva a imprevisibilidade nos testes, que somos desesperados para evitar na automatização.
Felizmente, a equipe Android do Google oferece uma boa alternativa: Emuladores de AOSP (Projeto Open-Source do Android). Mesmo que possivelmente falte alguns dos serviços extensos do Google, e seja menos excessivo, nós recomendamos usar apenas esta variedade de emuladores para executar testes de automação/Detox. Estes podem ser instalados ao lado dos emuladores regulares.
Abaixo temos uma comparação visual entre os dois — um emulador de SDK 28 (Android 9) AOSP (esquerdo) vs. um emulador com as APIs do Google instalado (direito):
Aqui é mostrado como instalá-los usando a linha de comando:
Enquanto for possível fazê-lo usando o Android Studio, mudaremos o foco para a linha de comando, já que ela também é boa para máquinas CI sem cabeça.
- Encontre sua pasta “home” no Android — situada normalmente no
ANDROID_HOME
, a variável de ambiente, ou em sua sucessoraANDROID_SDK_ROOT
. Se aANDROID_HOME
não está configurada, ajuste por conta própria ou execute os seguintes comandos após aplicar ocd
na pasta home. - Primeiramente: Atualize seu
emulator
executável para a versão mais recente.
Nota: Não tem problema se a versão do emulador não estiver emparelhada com a versão do SDK, ou de ferramentas de plataforma que tenha instalado atualmente (por exemplo: 30.x.x vs. SDK 29).
$ANDROID_HOME/tools/bin/sdkmanager --install emulator
3. Instale a imagem do emulador sem as APIs do Google:
$ANDROID_HOME/tools/bin/sdkmanager "system-images;android-28;default;x86_64" $ANDROID_HOME/tools/bin/sdkmanager --licenses
- Com o
;android-28;
, declaramos SDK 28 aqui, mas outros APIs são suportados da mesma forma. - A parte do
;default;
substitui o;google-apis;
, o padrão, que importa aqui.
4. Crie um emulador (isto é, AVD — Dispositivo Virtual Android):
$ANDROID_HOME/tools/bin/avdmanager create avd -n Pixel_API_28_AOSP -d pixel - -package "system-images;android-28;default;x86_64"
• PIXEL_API_28_AOSP
é só uma sugestão para um nome. Qualquer nome funciona, até mesmo Pixel_API_28
— mas, pode ser necessário ter que apagar um emulador existente que não seja do AOSP. De qualquer forma, o nome usado na configuração do Detox (tipicamente no package.json
) deve ser idêntico a este.
d-pixel
instalará um emulador com as specs de um dispositivo Pixel-1. Outras specs podem ser usadas.— package
é o pretexto mais importante: tenha certeza de usar o mesmo valor que foi usado na parte 2 acima, junto de;default;
.
➢ Execute o
avdmanager create — help
para a lista completa das opções.
5. Inicie o emulador:
Isto não é obrigatório, certamente, mas é sempre bom iniciar o emulador ao menos uma vez antes de executar testes automatizados. A seção abaixo discutirá sobre otimização do bootstraping nos emuladores.
A esse ponto, deve ser possível iniciar o emulador do Android Studio, mas isso também pode ser feito a partir de uma linha de comando em um console, como explicado nas orientações abaixo.
➢ Acompanhe este tutorial para detalhes sobre o
emulador
executável.
Instalando o Android Studio
Todos os detalhes não serão explorados, mas uma vez que a imagem apropriada está instalada usando o sdkmanager
, a opção se torna disponível no diálogo de criação do AVD (veja a coluna Target
da tela de Configuração do Dispositivo Virtual abaixo):
Certifique-se de atualizar seu emulador executável para a versão mais atual: Caso não esteja atualizado, uma mensagem é enviada dizendo: “Atualização Disponível” sob a coluna status, em vez de “Instalado”:
Nota: Não tem problema se a versão do emulador não estiver emparelhada com a versão do SDK ou das ferramentas de plataforma instaladas atualmente (por exemplo: 30.x.x vs. SDK 29).
Início Rápido do Emulador
Se o sistema permite um ponto de recuperação (por exemplo, em computador pessoal ou em sistema CI, onde é possível iniciar a partir de imagens pré- configuradas, que podem ser ajustadas), é extremamente recomendado configurar snapshots de início rápido para qualquer emulador que for usado em testes de automação.
O início rápido poupa uma quantidade considerável de tempo que seria desperdiçado quando o emulador inicia normalmente. O conceito se destaca em ambientes que conseguem uma execução paralela de testes em múltiplos emuladores sendo executados simultaneamente (como quando o Detox opera com múltiplos operadores de Jest).
Isso é algo que realmente recomendamos usar no próprio emulador do que na linha de comando, mas usaremos as duas opções.
Em todo o caso, o princípio geral que indicamos é:
- Habilite o auto-save no emulador instalado/funcionando.
- Inicie e quando estiver estável encerre — um snapshot é salvo como resultado.
- Desative o auto-save, de modo que, futuros snapshots testados não serão salvos.
Configurando um snapshot de início rápido do Emulador
Comece iniciando um emulador recém configurado. Espere até estabilizar. Ao executar, vá em configurações (3 pontos na barra lateral) > Snapshots
>Settings
. Caso ainda não esteja configurado selecione Yes
na opção auto_save
. Com isso provavelmente uma janela será aberta pedindo para reiniciar — escolha Yes
. O emulador irá reiniciar e salvar um snapshot.
Repita esse processo depois que o emulador estiver de volta, mas defina No
na opção de auto_save
. Permita que ele reinicie mais uma vez: ele irá inicializar imediatamente no estado salvo como um snapshot anteriormente.
Também é possível tentar por estas fontes alternativas para esse processo:
- Snapshots na página de desenvolvedores da Google para detalhes completos sobre snapshots.
- Blog altamente detalhado.
Configurando um snapshot de início rápido pela linha de comando
É um pouco mais difícil, mas também é aplicável mesmo em máquinas sem UI.
- Localize a
config.ini
do AVD - Usando um editor de texto à escolha, mude ou adicione estes conjuntos de valores chave:
fastboot.chosenSnapshotFile=
fastboot.forceChosenSnapshotBoot=no
fastboot.forceColdBoot=no
fastboot.forceFastBoot=yes
➢ Na prática,
forceFastBoot=yes
eforceColdBoot=no
devem ser suficientes.
3. No diretório inicial do AVD, crie ou edite outro arquivo ini
chamado quickbootChoice.ini
com o seguinte conteúdo:
saveOnExit = true
4. Agora que tudo está no lugar, inicie o emulador uma vez (no modo verbose) e espere que ele carregue totalmente. Em seguida, desligue-o e certifique-se que o estado foi salvo.
5. Por último, mas não menos importante, volte ao ckbootChoice.ini
e mude para:
saveOnExit = false
Aviso
Depois de atualizar o binário do emulador para uma versão mais recente, ele geralmente considera todos os snapshots existentes inválidos.
Isso pode ser resolvido excluindo e recriando os snapshots conforme explicado ou recriando os AVDs completamente.
Orientações
Localizando o diretório home do AVD
Cada AVD gerado pelas ferramentas Android possui o próprio diretório, onde o conteúdo associado é armazenado:
• Arquivo de configuração (isto é, config.ini
)
- Imagens do snapshot
- índice do cartão SD
Para nomear alguns.
Em máquinas Mac, o diretório de AVD é normalmente traçado para:
$HOME/.android/avd/<AVD Name>.avd/
(por exemplo: User/root/.android/avd/Pixel_API_28_AOSP.avd/
)
O trajeto deve ser similar em máquinas de Linux, mesmo que $HOME
não seja /Users/root
mas tipicamente /home/root.
(por exemplo: home/root/.android/avd/Pixel_API_28_AOSP.avd/
)
Iniciando emulador através da linha de comando
- Os seguintes exemplos aplicam-se para ambos Mac e Linux, e devem ser similares no Windows.
- É suposto que o nome do emulador seja
Pixel_API_28_AOSP
. Se não for, ajuste os nomes de acordo:
Atalho para inicializar um emulador visível e em verbose em um sistema com suporte de GUI
$ANDROID_HOME/emulator/emulator -verbose @Pixel_API_28_AOSP &
Atalho para iniciar um emulador em verbose e sem cabeça em um sistema sem UI no Linux
$ANDROID_HOME/emulator/emulator -verbose -no-window -no-audio -gpu swiftshader_indirect @Pixel_API_28_AOSP &
Verificando se o snapshot de início rápido do emulador foi salvo
Se ao executar seu emulador no modo verbose a partir de um shell, é fácil verificar o estado em que foi salvo seguindo os registros. Particularmente, ao encerrar o emulador, este registro declara o estado em que foi salvo:
emulador: Saving state on exit with session uptime 9423 ms
➢ Como referência, quando o estado não for salvo, a saída típica é:
emulador: WARNING: Not saving state: RAM not mapped as shared
➢ Pode ser o resultado de uma configuração inadequada ou da inicialização de um emulador em que o argument
-read-only
foi fornecido.
Detox para Android
Alterações Inesperadas⚠️
Caso esteja instalando Detox para o Android pela primeira vez, é possível pular até a seção de configuração.
➢ Siga o Tutorial de Migração para instruções de como atualizar versões antigas.
- Na versão 11 é alterado para o Android Espresso das novas bibliotecas de suporte do androidx.* do Android. Isso é feito a fim de permanecermos atualizados com os recursos e reparos mais recentes do Google, na esperança de usá-las para melhorar nosso próprio suporte do Android (que melhora a cada dia!).
- Na versão 10, Kotlin é indispensável para integrar o Detox em seu projeto Android. No mínimo, inclua o plugin do gradle do Kotlin em seu projeto, como será visto posteriormente. Entretanto, é bom levar em conta ao atualizar que essa é uma alteração inesperada. De qualquer forma, não se preocupe com o impacto em seu aplicativo, pois, a menos que use efetivamente o Kotlin em seu próprio código nativo, não haverá impacto no APK final, em termos de tamanho e contagem de métodos.
- A partir da versão 7 é requisitado o plugin gradle do Android 3.0.0 ou mais recente. Com essa alteração não é possível suportar versões anteriores do Plugin do Android para o Gradle
https://developer.android.com/studio/build/gradle-plugin-3-0-0-migration.html
Para suporte de versões mais antigas do Plugin do Android para o Gradle use detox@6.x.x
como alternativa (tutorial da versão anterior aqui).
Nota: De forma geral, todas as antigas versões principais são consideradas interrompidas; somente a versão principal mais recente do Detox é suportada.
Configuração ⚙
- Introdução
Siga os passos básicos do Ponto de Partida, assim como a configuração do ambiente e das ferramentas.
2. Para aplicar a Configuração Detox
Caso escolha aplicar a configuração em um .detoxrc.json
ou inseri-la em um package.json
no projeto (sob a seção detox
), isto é como a configuração deve aparentar para o Android:
{
"configurations": {
"android.emu.debug": {
"binaryPath": "android/app/build/outputs/apk/debug/app-debug.apk",
"build":
"cd android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug && cd ..",
"type": "android.emulator",
"device": {
"avdName": "Pixel_API_28"
}
},
"android.emu.release": {
"binaryPath": "android/app/build/outputs/apk/release/app-release.apk",
"build": "cd android && ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release && cd ..",
"type": "android.emulator",
"device": {
"avdName": "Pixel_API_28"
}
}
}
}
➢ Para uma explicação abrangente das configurações do Detox, consulte o tutorial exclusivo de referência API.
Preste atenção no -DtestBuildType
, escolha entre debug
ou release
de acordo com o tipo do apk principal.
Os seguintes tipos de dispositivos podem ser usados para controlar aparelhos Android:
android.emulator
. Inicialização em lote do emulador Android SDK (AVD) com oname
fornecido, por exemploPixel_API_28
.android.attached
. Conecte-se a um dispositivo Android já vinculado. O dispositivo deve estar listado na saída de comando doadb devices
peloname
fornecido. Use esse padrão para conectar ao emulador do Genymotion. A propriedadeadbName
aceita um padrão de expressão normal que permite especificar o arranjo de candidatos que deseja conectar. Use essa propriedade para executar testes paralelos em múltiplos aparelhos conectados.
Para obter um exemplo completo, consulte o aplicativo de exemplo do Detox.
2a. Para usar variações do produto
Caso esteja usando um productFlavors, a configuração precisa ser aplicada de forma diferente. Esse exemplo mostra como uma variação de produto beta
deve aparentar para ambos debug e versões de tipos de estruturas:
"detox" : {
"configurations": {
"android.emu.beta.debug": {
"binaryPath": "android/app/build/outputs/apk/beta/debug/app-beta-debug.apk",
"build": "cd android && ./gradlew assembleBetaDebug assembleBetaDebugAndroidTest -DtestBuildType=debug && cd ..",
"type": "android.emulator",
"device": {
"avdName": "Pixel_API_28"
}
},
"android.emu.beta.release": {
"binaryPath": "android/app/build/outputs/apk/beta/release/app-beta-release.apk",
"build": "cd android && ./gradlew assembleBetaRelease assembleBetaReleaseAndroidTest -DtestBuildType=release && cd ..",
"type": "android.emulator",
"device": {
"avdName": "Pixel_API_28"
}
}
}
}
3. Para adicionar dependências Nativas do Detox
➢ Ao iniciar o Detox 12.5.0, ele é enviado como um
.aar
pré-compilado. Para configurar o Detox como uma dependência de compilação, contudo — confira a sessão Configurando o Detox como uma dependência de compilação no fim da página.
No script de estrutura raiz (isto é, build.gradle
), registre ambos google()
e pontos de referência em todo o projeto:
// Note: add the 'allproject' section if it doesn't exist
allprojects {
repositories {
// ...
google()
maven {
// All of Detox' artifacts are provided via the npm module
url "$rootDir/../node_modules/detox/Detox-android"
}
}
}
Em seu script de estrutura do aplicativo (isto é, app/build.gradle
) adicione isso na seção dependencies
:
dependencies {
// ...
androidTestImplementation('com.wix:detox:+')
}
… e adicione isso à subseção defaultConfig
:
android {
// ...
defaultConfig {
// ...
testBuildType System.getProperty('testBuildType', 'debug') // This will later be used to control the test apk build type
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
}
}
Esteja ciente de que mindSdkVersion
precisa ser, no mínimo, 18.
4. Adicione o Kotlin
Se o projeto ainda não suporta Kotlin, adicione o plugin Gradle do Kotlin para o classpath no script de estrutura raiz (isto é, android/build-gradle
):
buildscript {
// ...
ext.kotlinVersion = '1.3.0' // (check what the latest version is!)
dependencies {
// ...
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
}
}
Nota: A maioria dos tutoriais aconselham definir uma constante de KotlinVersion
, como no exemplo, mas isso não é obrigatório.
Repare que Detox foi testado para versão 1.1.0 do Kotlin ou mais recente!
5. Crie uma Classe de Teste do Detox
Adicione o arquivo android/app/src/androidTest/java/com/[your.package]/DetoxTest.java
e preencha assim como no aplicativo de exemplo do detox para RN. Não esqueça de mudar o nome da pasta para o do seu projeto.
6. Disponibilize o tráfego da limpeza de texto (não criptografado) para o Detox
Iniciar o Android SDK v28; o Google desabilitou todo o tráfego em rede de limpeza de texto por padrão. A menos que explicitamente configurado, todo o tráfego de saída das aplicações não encriptadas (isto é, sem TLS usando HTTP ao invés de HTTPS) é bloqueado pelo aparelho.
Para que o Detox funcione, seu código de teste que está sendo executado no aparelho deve conectar-se no host executor de testes pela interface(*) virtual do localhost usando um tráfego simples de HTTP. Portanto, a seguinte configuração de isenção da rede de segurança deve ser aplicada:
Em um arquivo de recurso xml, por exemplo android/app/src/main/res/xml/network_security_config.xml
:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">10.0.2.2</domain>
<domain includeSubdomains="true">localhost</domain>
</domain-config>
</network-security-config>
No AndroidManifest.xml
do aplicativo
<manifest>
<application
...
android:networkSecurityConfig="@xml/network_security_config">
</application>
</manifest>
➢ Consulte o aplicativo de exemplos Detox para um modelo de como implementar de forma efetiva.
Nota: se configurado corretamente, de modo algum comprometerá as configurações de segurança do aplicativo.
Para detalhes completos, confira o tutorial do Android para configurar a segurança, e o artigo dedicado no blog de desenvolvedores Android.
➢ (*) 10.0.2.2 para emuladores Google, 10.0.3.2 para emuladores Genymotion.
7. Proguard (Minificação)
Para aplicativos em processo de minificação usando Proguard, de forma que o Detox funcione em novas versões, disponibilize algumas regras de configuração proguard do Detox aplicando o arquivo de configuração padrão acima do seu. Normalmente, isso é definido usando a declaração proguardFiles
no tipo de estrutura que disponibiliza minificação em seu app/build.gradle
:
buildTypes {
// 'release' is typically the default proguard-enabled build-type
release {
minifyEnabled true
// Typical pro-guard definitions
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
// Detox-specific additions to pro-guard
proguardFile "${rootProject.projectDir}/../node_modules/detox/android/detox/proguard-rules-app.pro"
}
}
8. Suporte do Test Butler (Opcional)
Se, quando estiver configurando o ambiente de trabalho, ocorrer a seleção dos emuladores do Google com uma imagem de AOSP como o alvo de teste, como foi recomendado, nós incentivamos fortemente a integração de um Test Butler: pelo menos, a fim de evitar crashs e erros de ANR. Eles são um ponto fraco nos testes de UI em todo o Android, como, quando mostrado, tornam a UI completamente inacessível (dessa forma causando falhas em massa nos testes).
Configurar o Test Butler para trabalhar com Detox é um pouco diferente de como foi explicado em seus tutoriais. O processo, como um todo, tem duas etapas:
1. Instalar o APK do aplicativo do Test Butler no dispositivo de teste.
2. Integrar as bibliotecas do Test Butler em seu próprio APK de teste, e inicializá-lo em um executor de testes personalizado (como explicado).
A parte da biblioteca pode ser facilmente alcançada como explicado (isto é, usando o androidTestImplementation
do Gradle). O mesmo vai para a iniciação. Quanto ao APK, o uso sugerido do androidTestUtil
do Gradle é escasso ao ser executado com Detox (testes não nativos à instrumentação). Nesse caso temos estas alternativas.
1° Solução: Imagens Pré-Configuradas
Caso tenha controle sobre os snapshots do emulador, simplesmente baixe (veja o tutorial do Test Butler) e instale o APK do Test Butler uma vez (por exemplo use o adbinstall -r -t path/to/test-butler-app.apkx
), e salve uma versão atualizada do snapshot. Esta é a melhor solução.
➢ Nota: será necessário repetir este processo caso a versão do Test Butler seja atualizada futuramente.
2° Solução: Instalação Dinâmica
Supondo que o APK esteja disponível no sistema, é possível fazer com que o Detox o instale em todos os emuladores-alvo em execução, utilizando utilBinaryPaths
na sua configuração de Detox. Exemplo:
{
"configuration": {
"android.emu.release": {
"binaryPath": "android/app/build/outputs/apk/fromBin/release/app-fromBin-release.apk",
"utilBinaryPaths": ["relative/path/to/test-butler-app-2.1.0.apk"],
"build": "...",
"type": "android.emulator",
...
}
}
}
➢ Consulte o nosso tutorial de configuração para mais detalhes sobre
utilBinaryPaths
.
Em relação a tornar o APK disponível ainda não temos nenhuma solução efetiva, por enquanto (mas está no processo). Porém há algumas soluções:
a). Em um script personalizado, baixe o APK diretamente do Bintray com antecedência, como sugerido na guia do Test Butler. Por exemplo (em um Mac/Linux):
curl -f -o ./temp/test-butler-app.apk https://linkedin.bintray.com/maven/com/linkedin/testbutler/test-butler-app/2.1.0/test-butler-app-2.1.0.apk`
A instalação global do Jest é um lugar recomendado para esse tipo de coisa.
➢ Se for decidido seguir este trajeto, é recomendado adicionar
./temp/test-butler-app.apk
ao.gitignore
de maior relevância.
b). (Não recomendado) Adicione-o ao código fonte (por exemplo o git), como parte do repositório.
Para configurar o Detox como dependência de compilação
Isto é uma alternativa ao processo de instalação descrito na seção anterior, para adicionar Detox como uma dependência.
No settings.gradle
do seu projeto, adicione:
include ':detox'
project(':detox').projectDir = new File(rootProject.projectDir, '../node_modules/detox/android/detox')
No seu script raiz (isto é, build.gradle
), registre google()
como um ponto de referência repositório em todos os projetos:
// Note: add the 'allproject' section if it doesn't exist
allprojects {
repositories {
// ...
google()
}
}
No script do seu aplicativo (isto é, app/build.gradle
) adicione isto na seção dependencies
:
dependencies {
// ...
androidTestImplementation(project(path: ":detox"))
}
No script do seu aplicativo (isto é, app/build.gradle
) adicione esta chave à subseção do defaultConfig
:
android {
// ...
defaultConfig {
// ...
testBuildType System.getProperty('testBuildType', 'debug') // This will later be used to control the test apk build type
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
}
}
Esteja ciente que minSdkVersion
necessita estar pelo menos na versão 18.
Correção de erros
Problema: Duplicate files copied in...
Se surgir um erro como esse:
Execution failed for task ':app:transformResourcesWithMergeJavaResForDebug'.
> com.android.build.api.transform.TransformException: com.android.builder.packaging.DuplicateFileException: Duplicate files copied in APK META-INF/LICENSE
É preciso adicionar isso à seção android
do seu android/app/build.gradle
:
packagingOptions {
exclude 'META-INF/LICENSE'
}
Problema: Conflitos da versão do stdlib de Kotlin
Os problemas e as definições aqui são diferentes se você estiver usando Detox como um artefato dependente de pré-compilação (isto é, .aar ) — que é o padrão, ou compilando você mesmo.
Resolução para uma dependência de pré-compilação ( .aar )
De todos as variações de implementações do Kotlin, o Detox atribui o mais recente, isto é: kotlin-stdlib-jdk8
. Se sua configuração do Android falhar devido aos conflitos com as implementações vindas de outras dependências ou mesmo de seu próprio aplicativo, considere adicionar uma exclusão às “outras” dependências ou ao próprio detox, por exemplo:
dependencies {
- androidTestImplementation('com.wix:detox:+')
+ androidTestImplementation('com.wix:detox:+') {
+ exclude group: 'org.jetbrains.kotlin', module: 'kotlin-stdlib-jdk8'
+ }
}
Detox deve funcionar bem com kotlin-stdlib-jdk7.
Uma saída de erro típica formada pelo Gradle neste caso é a fornecida, por exemplo, em #1380:
Could not determine the dependencies of task ':detox:compileDebugAidl'.
> Could not resolve all task dependencies for configuration ':detox:debugCompileClasspath'.
> Could not resolve org.jetbrains.kotlin:kotlin-stdlib:1.3.0.
Required by:
project :detox
> Cannot find a version of 'org.jetbrains.kotlin:kotlin-stdlib' that satisfies the version constraints:
Dependency path 'OurApp:detox:unspecified' --> 'com.squareup.okhttp3:okhttp:4.0.0-alpha01' --> 'org.jetbrains.kotlin:kotlin-stdlib:1.3.30'
Dependency path 'OurApp:detox:unspecified' --> 'com.squareup.okio:okio:2.2.2' --> 'org.jetbrains.kotlin:kotlin-stdlib:1.2.60'
Dependency path 'OurApp:detox:unspecified' --> 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.0' --> 'org.jetbrains.kotlin:kotlin-stdlib:1.3.0'
Dependency path 'OurApp:detox:unspecified' --> 'com.facebook.react:react-native:0.59.5' --> 'com.squareup.okhttp3:okhttp:4.0.0-alpha01' --> 'org.jetbrains.kotlin:kotlin-stdlib:1.3.30'
Dependency path 'OurApp:detox:unspecified' --> 'com.facebook.react:react-native:0.59.5' --> 'com.squareup.okio:okio:2.2.2' --> 'org.jetbrains.kotlin:kotlin-stdlib:1.2.60'
Dependency path 'OurApp:detox:unspecified' --> 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.0' --> 'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.0' --> 'org.jetbrains.kotlin:kotlin-stdlib:1.3.0'
Constraint path 'OurApp:detox:unspecified' --> 'org.jetbrains.kotlin:kotlin-stdlib' strictly '1.3.0' because of the following reason: debugRuntimeClasspath uses version 1.3.0
Constraint path 'OurApp:detox:unspecified' --> 'org.jetbrains.kotlin:kotlin-stdlib' strictly '1.3.0' because of the following reason: debugRuntimeClasspath uses version 1.3.0
> Could not resolve org.jetbrains.kotlin:kotlin-stdlib-common:1.3.0.
Required by:
project :detox
> Cannot find a version of 'org.jetbrains.kotlin:kotlin-stdlib-common' that satisfies the version constraints:
Dependency path 'OurApp:detox:unspecified' --> 'com.squareup.okhttp3:okhttp:4.0.0-alpha01' --> 'org.jetbrains.kotlin:kotlin-stdlib:1.3.30' --> 'org.jetbrains.kotlin:kotlin-stdlib-common:1.3.30'
Constraint path 'OurApp:detox:unspecified' --> 'org.jetbrains.kotlin:kotlin-stdlib-common' strictly '1.3.0' because of the following reason: debugRuntimeClasspath uses version 1.3.0
(O projeto depende indiretamente de versões diferentes do kotlin-stdlib
, assim como a 1.3.0, 1.3.30, 1.2.60
).
Resolução para um subprojeto de compilação
O Detox requer a biblioteca padrão do Kotlin como sua própria dependência. Devido aos vários conjuntos que o Kotlin está lançando, múltiplas dependências frequentemente criam conflitos.
Por isso, o Detox permite a especificação exata da biblioteca padrão usar dois globais do Gradle: detoxKotlinVersion
e detoxKotlinStdlib
. É possível definir ambos no arquivo script estrutural raiz ( android/build.gradle
):
buildscript {
// ...
ext.detoxKotlinVersion = '1.3.0' // Detox' default is 1.2.0
ext.detoxKotlinStdlib = 'kotlin-stdlib-jdk7' // Detox' default is kotlin-stdlib-jdk8
}
Problema: O aplicativo carrega, mas os testes não executam no SDK >= 28
Como relatado na edição #1450, algumas vezes o aplicativo que está sendo testado iniciaria em um emulador/dispositivo quando o Detox é executado, mas o executor de testes suspenderá e não irá iniciar a execução dos testes.
Mais especificamente, quando isto acontecer:
- O Detox e o executor de testes iniciam com sucesso, juntamente com o aplicativo que está sendo executado (a menos que
launchApp:false
for passado paradetox.init()
), mas o primeiro teste simplesmente fica paralisado para sempre (como explicado). - Eventualmente, o executor de testes seria interrompido.
3. Os últimos registros de Detox, relatados antes da interrupção, indicariam que o dispositivo não se conectava ao executor de testes no host. Por exemplo:
detox[12345] DEBUG: [DetoxServer.js/CANNOT_FORWARD] role=testee not connected, cannot fw action (sessionId=11111111-2222-3333-4444-555555555555)
- O passo principal para reparar esse problema é voltar para a etapa 6 neste tutorial, que discute a rede de segurança.
- De outra forma, o atributo
android:usesCleartextTraffic="true"
pode ser configurado na tag<application>
doAndroidManifest.xml
do aplicativo, porém isso é fortemente desencorajado.
Problema: Detox não pôde encontrar o APK de teste
Pode ser gerada uma mensagem de erro como essa: detox[53027] ERROR: Error:'android/app/build/outputs/androidTest/x86_64/debug/app-x86_64-debug-androidTest.apk' could not be found, did you run ‘./gradlew assembleAndroidtest'
?
Nesse caso o testBinaryPath
pode ser usado na configuração para substituir o binaryPath
e apontar diretamente para o APK de teste.