Como posso criar testes no Android Studio?

109

Acabei de baixar o Android Studio, que é baseado no Intellij Idea.

Como alguém criaria testes?

Percebo que existe uma opção para criar um Módulo de Teste, mas isso não parece fazer nada, apenas criar um novo projeto com src

Também tentei pressionar a tecla de atalho CTRL + AlT + T que permite criar testes de unidade em uma classe existente, mas parece que deseja colocá-lo no projeto atual. Claro que isso não ajuda com TDD

Alguém tem alguma experiência aqui?

Martin
fonte
2
Também tentei criar um projeto de teste. Se você fizer isso com a ferramenta de linha de comando do Android, como faria com um projeto Eclipse, obterá um erro porque não é possível localizar o arquivo AndroidManifest.xml. Parece que o Google precisa atualizar sua ferramenta Android para lidar com os projetos Grundle. No entanto, eu sou novo em testes no Android, então não posso ajudá-lo = (
Kage

Respostas:

56

Esta resposta é para pessoas que estão apenas começando com os testes do Android. Fornecerei dois exemplos simples para ajudá-lo a ver como funcionam os testes. Se você acompanhar pelos próximos 10 minutos, estará tudo pronto para começar a adicionar seus testes ao seu próprio aplicativo. Acho que você ficará surpreso com o quão fácil é. Eu certamente estava.

Introdução ao Android Testing

Existem dois tipos diferentes de testes que você fará.

  • Testes de unidade local. Eles são executados localmente na JVM (Java Virtual Machine). Por serem locais, são rápidos. Você pode usá-los para testar as partes do seu código que precisam apenas do Java e não das APIs do Android. (Às vezes, você pode fazer um objeto de API falso para testar mais coisas localmente. Isso é chamado de simulação . Uma simulação Contexté um exemplo.)
  • Testes instrumentados. Esses testes são executados em um dispositivo real ou no emulador. Isso os torna mais lentos do que os testes locais. No entanto, eles são mais flexíveis porque você tem a API Android completa disponível para você.

Crie um novo projeto e você verá as seguintes pastas padrão.

insira a descrição da imagem aqui

Tudo já está aí e esperando por você para criar seus testes. Já está tudo configurado!

Como criar testes de unidade locais

Abra o ExampleUnitTestarquivo mostrado na imagem acima. deve ser parecido com isto:

public class ExampleUnitTest {
    @Test
    public void addition_isCorrect() throws Exception {
        assertEquals(4, 2 + 2);
    }
}

Pressione a seta verde dupla para executar todos os testes ou a seta verde única para executar apenas um. (Neste caso, há apenas um teste, então ambos fazem a mesma coisa.)

insira a descrição da imagem aqui

Deve passar (contanto que 2 + 2ainda esteja 4quando você estiver lendo esta resposta). Parabéns, você acabou de fazer seu primeiro teste!

Fazendo seu próprio teste

Vamos escrever nosso próprio teste. Primeiro adicione esta classe ao seu projeto de aplicativo principal para que tenhamos algo para testar:

public class MyClass {
    public int add(int a, int b) {
        return a + b;
    }
}

Agora mude o addition_isCorrect()método na classe de teste para ficar como o código a seguir (ou apenas adicione outro método com um nome diferente):

public class ExampleUnitTest {
    @Test
    public void addition_isCorrect() throws Exception {
        MyClass myClass = new MyClass();
        int result = myClass.add(2, 2);
        int expected = 4;
        assertEquals(expected, result);
    }
}

Execute-o novamente e você verá que passa. Parabéns, você acabou de criar seu primeiro teste! (Bem, acho que tecnicamente era meu, mas, ei, perto o suficiente. O que é meu é seu.)

Como criar testes instrumentados

Abra o ExampleInstrumentedTestarquivo. deve ser parecido com isto:

@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
    @Test
    public void useAppContext() throws Exception {
        // Context of the app under test.
        Context appContext = InstrumentationRegistry.getTargetContext();

        assertEquals("com.example.myapp", appContext.getPackageName());
    }
}

Pressione um desses botões verdes novamente.

insira a descrição da imagem aqui

Contanto que você tenha um dispositivo real conectado ou o emulador configurado, ele deve ter inicializado e executado seu aplicativo. Parabéns, você acabou de executar seu primeiro teste instrumentado!

Fazendo seu próprio teste

Os testes instrumentados usam o Espresso para executar os testes. É como se fosse seu próprio pequeno usuário de robô que você pode mandar testar seu aplicativo. Você pode dizer a ele para fazer algo como pressionar um botão ou ler as propriedades de um TextView.

Você pode escrever as instruções de como fazer o teste manualmente, mas como estamos apenas começando, vamos usar a função de gravação automática . É super simples.

Primeiro adicione um botão à sua IU para que tenhamos algo com que trabalhar. Eu fiz isso:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.myapp.MainActivity">

    <Button
        android:id="@+id/myButton"
        android:text="Click me"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</android.support.constraint.ConstraintLayout> 

Em seguida, pressione Executar> Gravar teste Espresso no menu.

insira a descrição da imagem aqui

Depois de iniciar, clique no botão no emulador e, para finalizar, escolha OK na caixa de diálogo Registro. Ele deve gerar automaticamente o seguinte código de teste.

@LargeTest
@RunWith(AndroidJUnit4.class)
public class MainActivityTest {

    @Rule
    public ActivityTestRule<MainActivity> mActivityTestRule = new ActivityTestRule<>(MainActivity.class);

    @Test
    public void mainActivityTest() {
        ViewInteraction appCompatButton = onView(
                allOf(withId(R.id.myButton), withText("Click me"), isDisplayed()));
        appCompatButton.perform(click());
    }
}

Ótimo! Você acabou de criar seu primeiro teste instrumentado! Isso foi super fácil. Você provavelmente deve adicionar uma afirmação para torná-lo um teste real, mas isso também é muito fácil de fazer com o gravador. Assista a este vídeo para se aprofundar um pouco mais.

Um estudo mais aprofundado

Eu primeiro assistia aos vídeos e depois lia a documentação. É tudo muito útil. O último link é para uma série de artigos que cobrem algumas coisas importantes para se pensar ao escolher o que testar.

Suragch
fonte
1
Ótima resposta @Suragch. Pergunta rápida: onde eu colocaria os arquivos de suporte para o caso de teste de unidade local? É hacky, mas ficaria feliz em colocar o caminho completo da base do teste, mas se eu executar no Android Studio, os testes serão/app executados em root_ , no entanto, se eu executar na linha de comando do Gradle (ou CI), então será _root . (Idealmente, gostaria de acessar assetspastas específicas quando executado de qualquer maneira).
mm2001
@ mm2001, escrevi esta resposta como uma forma de aprender a fazer testes por conta própria, então nem cheguei tão longe quanto você. Se você descobrir isso antes de mim, pode deixar um comentário?
Suragch
Achei útil: stackoverflow.com/a/42751502/19506 - diz para criar uma pasta test/resourcese colocar os arquivos lá, por exemplo, test.txte acessá-los com getClass().getClassLoader().getResource("test.txt"). Decidi que acessar os ativos do APK diretamente é provavelmente uma má ideia, então lidarei com isso copiando os arquivos para teste em uma etapa de compilação ou em um processo de atualização externo. Ainda há algumas dúvidas sobre as diferentes versões do Gradle, mas ainda não enfrentei isso.
mm2001
36

Editar: a partir de 0.1.8 agora é suportado no IDE . Siga as instruções lá, em vez de usar as instruções abaixo.

Seguindo o Guia do usuário do Android Gradle Plugin, consegui fazer com que os testes funcionassem na linha de comando realizando as seguintes etapas em um projeto recém-criado (usei o pacote padrão 'com.example.myapplication'):

  1. Adicione um diretório src / instrumentTest / java para os testes
  2. Adicione uma classe de teste (estendendo ActivityTestCase) no pacote com.example.myapplication.test
  3. Inicie um dispositivo virtual
  4. Na linha de comando (no diretório MyApplicationProject / MyApplication) use o comando '../gradlew connectedInstrumentTest'

Isso executou meus testes e colocou os resultados do teste em MyApplicationProject / MyApplication / build / reports / instrumentTests / connected. Eu sou novo em testar aplicativos Android, mas parece que funciona bem.

De dentro do IDE, é possível tentar e executar a mesma classe de teste. Você vai precisar

  1. Atualize build.gradle para listar o Maven Central como um repo
  2. Atualizar build.gradle adicionar JUnit 3.8 como uma dependência instrumentTestCompile, por exemplo, instrumentTestCompile 'junit: junit: 3.8'
  3. Em 'Estrutura do Projeto', mova manualmente JUnit para ser o primeiro na ordem de dependência

No entanto, isso falha (o caminho de classe usado ao executar os testes não contém o diretório de saída do teste). No entanto, não tenho certeza de que isso funcionaria independentemente, pois é meu conhecimento que um executor de teste específico do Android é necessário.

Chris
fonte
20

Eu sugeriria usar o arquivo gradle.build .

  1. Adicione um diretório src / androidTest / java para os testes (como Chris começa a explicar)

  2. Abra o arquivo gradle.build e especifique lá:

    android {
    
        compileSdkVersion rootProject.compileSdkVersion
        buildToolsVersion rootProject.buildToolsVersion
    
        sourceSets {
    
            androidTest {
                java.srcDirs = ['androidTest/java']
            }
        }
    }
  3. Pressione "Sincronizar projeto com arquivo Gradle" (no painel superior). Você deve ver agora uma pasta "java" (dentro de "androidTest") de cor verde.

  4. Agora você pode criar quaisquer arquivos de teste e executá-los.

Yuriy Chernyshov
fonte
Não se esqueça de androidTest.setRoot ('instrumentTest')
IgorGanapolsky
3
Na versão atual do Android Studio, não é necessário, mais - substitua tudo que tem um nome instrumentTest por androidTest
Yuriy Chernyshov
Os nomes 'instrumentTest' e 'androidTest' são totalmente arbitrários. Eles são apenas nomes de diretório para seu projeto de teste. Você também pode criar um diretório de 'testes'. Além disso, o nome do pacote do SDK na estrutura de teste é android.test.InstrumentationTestCase. Então, canonicamente, acredito que 'instrumento' ou 'instrumentação' ainda faz sentido para nomear os testes de alguém. Veja o seguinte código-fonte: grepcode.com/file/repository.grepcode.com/java/ext/…
IgorGanapolsky
7
Por favor, leia a documentação aqui: tools.android.com/tech-docs/new-build-system . Desde a versão 0.9.0, instrumentTest foi renomeado para androidTest .
Yuriy Chernyshov
1
@IgorGanapolsky Nomear a pasta como androidTest NÃO é arbitrária. Deve ser feito para que a pasta fique verde.
relojoeiro
12

Acho que este post de Rex St John é muito útil para testes de unidade com o Android Studio.


(fonte: rexstjohn.com )

Saeed Zarinfam
fonte
10

Android Studio v.2.3.3

Destaque o contexto de código que deseja testar e use a tecla de atalho: CTRL+ SHIFT+T

Use a interface de diálogo para completar sua configuração.

A estrutura de teste deve espelhar o layout do pacote do projeto para obter melhores resultados, mas você pode criar testes personalizados manualmente, desde que tenha o diretório correto e as configurações de compilação.

Hypersoft Systems
fonte
7

A partir de agora (estúdio 0.61), manter a estrutura adequada do projeto é o suficiente. Não há necessidade de criar um projeto de teste separado como no eclipse (veja abaixo).

Estrutura de testes

Daber
fonte
4

O Android Studio continua evoluindo, então as respostas acima eventualmente não serão mais aplicáveis. Para a versão atual do Android Studio 1.2.1.1, há um bom tutorial sobre testes em:

http://evgenii.com/blog/testing-activity-in-android-studio-tutorial-part-1/

AndroidDev
fonte
2
Sim, o AS continua evoluindo, então é bastante bobo alguém criar um artigo sobre tecnologia de ponta e nunca mencionar o número da versão a que se aplica. a única pista é uma data bem no fundo.
Tom
3

Parece que uma das principais mudanças é que, com o Android Studio, o aplicativo de teste é integrado ao projeto do aplicativo.

Não tenho certeza se isso ajuda no seu problema específico, mas encontrei um guia sobre como fazer testes com um projeto do Gradle. Guia do usuário do Android Gradle

Kage
fonte
3

A maneira mais fácil que encontrei é simplificada na minha seguinte postagem do blog :

  1. Crie uma pasta na qual você escreverá todos os seus testes de unidade (de preferência com.example.app.tests)
  2. Crie uma nova classe de teste (de preferência NameOfClassTestedTests, ou seja, BankAccountLoginActivityTests)
  3. Estenda InstrumentationTestCase
  4. Escreva um teste de unidade com falha para garantir que tenhamos sucesso na configuração dos testes de unidade
  5. Observe que o nome de um método de teste de unidade deve começar com a palavra "teste" (de preferência testTestedMethodNameExpectedResult (), ou seja, testBankAccountValidationFailedShouldLogout ())
  6. Configure seu projeto para testes de unidade:
  7. Abra o menu 'Executar ...' e clique em 'editar configurações'
  8. Clique no botão +
  9. Selecione o modelo de testes Android
  10. Insira um nome para sua configuração de execução (de preferência 'Testes AppName')
  11. Selecione seu aplicativo no módulo combobox
  12. Selecione o botão de opção “All In Package” (geralmente você deseja selecionar esta opção porque executa todos os testes de unidade em todas as suas classes de teste)
  13. Preencha o nome do pacote de teste da etapa 1 (ou seja, com.example.app.tests)
  14. Selecione o dispositivo em que deseja executar seus testes
  15. Aplicar e salvar a configuração
  16. Execute testes de unidade (e espere falha):
  17. Selecione sua configuração de testes recém-criada no menu Executar
  18. Clique em Executar e leia os resultados no console de saída

Boa sorte tornando seu código mais legível, sustentável e bem testado!

Nurnachman
fonte
A pergunta era sobre testes de instrumentação! Também tenho dificuldade em escrever alguns testes de instrumentação. Veja minha pergunta em stackoverflow.com/questions/35426990/…
Monica
2

O Android Studio tem sido um alvo em movimento, primeiro sendo uma prévia do desenvolvedor e agora em beta. O caminho para as classes de teste no projeto mudou com o tempo, mas não importa qual versão do AS você está usando, o caminho é declarado em seu arquivo .iml. Atualmente, com a versão 0.8.3, você encontrará o seguinte dentro do arquivo iml interno:

      <sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
  <sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
  <sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
  <sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
  <sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
  <sourceFolder url="file://$MODULE_DIR$/src/androidTest/groovy" isTestSource="true" />
  <sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
  <sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />

O arquivo .iml está informando onde colocar suas classes de teste.

Miguel El Merendero
fonte
0

Adicione a lib abaixo dentro do arquivo gradle

 androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })

Crie a classe HomeActivityTest dentro do diretório androidTest e antes de executar o teste adicione a string flurry_api_key e sender_id dentro do arquivo de recurso da string e altere o valor para o caso de falha e sucesso.

@RunWith(AndroidJUnit4.class)
public class HomeActivityTest
{
    private static final String SENDER_ID = "abc";
    private static final String RELEASE_FLURRY_API_KEY = "xyz";

    @Test
    public void gcmRegistrationId_isCorrect() throws Exception
    {
        // Context of the app under test.
        Context appContext = InstrumentationRegistry.getTargetContext();

        Assert.assertEquals(SENDER_ID, appContext.getString(R.string.sender_id));
    }

    @Test
    public void flurryApiKey_isCorrect() throws Exception
    {
        // Context of the app under test.
        Context appContext = InstrumentationRegistry.getTargetContext();

        Assert.assertEquals(RELEASE_FLURRY_API_KEY, appContext.getString(R.string.flurry_api_key));
    }
}
Bishwajeet Biswas
fonte