O Google tem o compromisso de promover a igualdade racial para as comunidades negras. Saiba como.

Exemplo de testes de auto-instrumentação

Quando um teste de instrumentação é iniciado, seu pacote de destino é reiniciado com o código de instrumentação injetado e iniciado para execução. Uma exceção é que o pacote de destino aqui não pode ser o framework de aplicações Android em si, ou seja, o pacote android , porque isso levaria à situação paradoxal onde quadro Android precisaria ser reiniciado, que é o que suporta as funções do sistema, incluindo a instrumentação em si.

Isso significa que um teste de instrumentação não pode se injetar na estrutura do Android, também conhecido como servidor do sistema, para execução. A fim de testar o quadro Android, o código de teste pode invocar superfícies API só públicos, ou aqueles expostos por meio de interface Android Definition Language AIDL disponível na árvore de origem plataforma. Para esta categoria de testes, não é significativo direcionar nenhum pacote específico. Portanto, é habitual para tais instrumentações para ser declarado para atingir o seu próprio pacote de aplicativos de teste, tal como definido no seu próprio <manifest> tag de AndroidManifest.xml .

Dependendo dos requisitos, os pacotes de aplicativos de teste nesta categoria também podem:

  • Atividades de pacote necessárias para teste.
  • Compartilhe o ID do usuário com o sistema.
  • Seja assinado com a chave da plataforma.
  • Ser compilado com base na fonte da estrutura, e não no SDK público.

Essa categoria de testes de instrumentação às vezes é chamada de auto-instrumentação. Aqui estão alguns exemplos de testes de auto-instrumentação na fonte da plataforma:

O exemplo coberto aqui é escrever um novo teste de instrumentação com pacote de destino definido em seu próprio pacote de aplicativo de teste. Este guia usa o seguinte teste para servir de exemplo:

É recomendável navegar pelo código primeiro para obter uma impressão aproximada antes de continuar.

Decidir sobre um local de origem

Normalmente, sua equipe já terá um padrão estabelecido de locais para fazer o check-in do código e locais para adicionar testes. A maioria das equipes possui um único repositório git ou compartilha um com outras equipes, mas tem um subdiretório dedicado que contém o código-fonte do componente.

Assumindo o local raiz para a sua fonte componente está em <component source root> , a maioria dos componentes têm src e tests pastas abaixo dela, e alguns arquivos adicionais, tais como Android.mk (ou divididos em adicionais .mk arquivos), o arquivo de manifesto AndroidManifest.xml , e 'AndroidTest.xml' o arquivo de configuração de teste.

Desde que você está adicionando um teste novo, você provavelmente vai precisar para criar a tests diretório ao lado de seu componente src , e preenchê-lo com conteúdo.

Em alguns casos, sua equipe pode ter outras estruturas de diretórios sob tests , devido à necessidade de embalar diferentes suites de testes em apks individuais. E, neste caso, você precisa criar um novo diretório sub sob tests .

Independentemente da estrutura, você vai acabar de preencher a tests diretório ou o diretório sub recém-criado com arquivos semelhantes ao que está na instrumentation diretório na mudança gerrit amostra. As seções abaixo explicarão em mais detalhes de cada arquivo.

Arquivo de manifesto

Assim como um aplicativo normal, cada módulo de teste de instrumentação precisa de um arquivo de manifesto. Se você nomear o arquivo como AndroidManifest.xml e fornecê-lo ao lado Android.mk para o seu módulo de teste, ele vai ficar incluído automaticamente pelo BUILD_PACKAGE makefile núcleo.

Antes de prosseguir, é altamente recomendável que passar pela App Manifest Overview primeiro.

Isso fornece uma visão geral dos componentes básicos de um arquivo de manifesto e suas funcionalidades. Ver o exemplo na platform_testing / testes / exemplo / instrumentação / AndroidManifest.xml .

Um instantâneo está incluído aqui para sua conveniência:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="android.test.example.helloworld" >

    <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="21" />

    <application>
        <uses-library android:name="android.test.runner" />
    </application>

    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
                     android:targetPackage="android.test.example.helloworld"
                     android:label="Hello World Test"/>

</manifest>

Alguns comentários selecionados sobre o arquivo de manifesto:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="android.test.example.helloworld" >

O package atributo é o nome do pacote do aplicativo: este é o identificador único que usa o framework de aplicações Android para identificar um aplicativo (ou neste contexto: seu aplicativo de teste). Cada usuário no sistema pode instalar apenas um aplicativo com esse nome de pacote.

Além disso, este package atributo é o mesmo que o que ComponentName#getPackageName() retorna, e também o mesmo que você usaria para interagir com vários pm sub comandos via adb shell .

Observe também que, embora o nome do pacote seja normalmente do mesmo estilo de um nome de pacote Java, na verdade, ele tem muito poucas coisas a ver com ele. Em outras palavras, seu pacote de aplicativo (ou teste) pode conter classes com quaisquer nomes de pacote, embora, por outro lado, você possa optar pela simplicidade e ter o nome do pacote Java de nível superior em seu aplicativo ou teste idêntico ao nome do pacote do aplicativo.

android:sharedUserId="android.uid.system"

Isso declara que, no momento da instalação, este apk deve receber o mesmo ID de usuário, ou seja, identidade de tempo de execução, que a plataforma principal. Note que este é dependente do apk ser assinado com o mesmo certificado como a plataforma central (ver LOCAL_CERTIFICATE na seção acima), mas eles são conceitos diferentes:

  • algumas permissões ou APIs são protegidas por assinatura, o que requer o mesmo certificado de assinatura
  • algumas permissões ou APIs requer que o system identidade do usuário do chamador, o que requer o pacote chamando à participação ID do usuário com system , se é um pacote separado de si mesma plataforma central
<uses-library android:name="android.test.runner" />

Isso é necessário para todos os testes de Instrumentação, uma vez que as classes relacionadas são empacotadas em um arquivo de biblioteca jar de estrutura separado, portanto, requer entradas de caminho de classe adicionais quando o pacote de teste é chamado pela estrutura de aplicativo.

android:targetPackage="android.test.example.helloworld"

Você deve ter notado que o targetPackage aqui é declarado o mesmo que o package atributo declarado no manifest tag deste ficheiro. Conforme mencionado na noções básicas de teste , esta categoria de teste de instrumentação são normalmente destinados a medir APIs-quadro, por isso não é muito significativa para que eles tenham um pacote de aplicativo específico alvejado, outro então em si.

Arquivo de configuração simples

Cada novo módulo de teste deve ter um arquivo de configuração para direcionar o sistema de construção com metadados do módulo, dependências de tempo de compilação e instruções de empacotamento. Na maioria dos casos, a opção de arquivo Blueprint baseada em Soong é suficiente. Para mais detalhes, consulte Configuração de teste simples .

Arquivo de configuração complexo

Para esses casos mais complexos, você também precisa escrever um arquivo de configuração de teste para equipamento de teste do Android, Federação do Comércio .

A configuração de teste pode especificar opções especiais de configuração de dispositivo e argumentos padrão para fornecer a classe de teste. Veja o exemplo na /platform_testing/tests/example/instrumentation/AndroidTest.xml .

Um instantâneo está incluído aqui para sua conveniência:

<configuration description="Runs sample instrumentation test.">
  <target_preparer class="com.android.tradefed.targetprep.TestFilePushSetup"/>
  <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
    <option name="test-file-name" value="HelloWorldTests.apk"/>
  </target_preparer>
  <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer"/>
  <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer"/>
  <option name="test-suite-tag" value="apct"/>
  <option name="test-tag" value="SampleInstrumentationTest"/>

  <test class="com.android.tradefed.testtype.AndroidJUnitTest">
    <option name="package" value="android.test.example.helloworld"/>
    <option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/>
  </test>
</configuration>

Alguns comentários selecionados sobre o arquivo de configuração de teste:

<target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
  <option name="test-file-name" value="HelloWorldTests.apk"/>
</target_preparer>

Isso diz à Trade Federation para instalar o HelloWorldTests.apk no dispositivo de destino usando um target_preparer especificado. Existem muitos preparadores de destino disponíveis para desenvolvedores na Trade Federation e eles podem ser usados ​​para garantir que o dispositivo seja configurado corretamente antes da execução do teste.

<test class="com.android.tradefed.testtype.AndroidJUnitTest">
  <option name="package" value="android.test.example.helloworld"/>
  <option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/>
</test>

Isso especifica a classe de teste Trade Federation a ser usada para executar o teste e passa no pacote no dispositivo a ser executado e na estrutura do executor de teste que é JUnit neste caso.

Para mais informações, consulte Teste Módulo Configs .

Recursos JUnit4

Utilizando android-support-test biblioteca como corredor de teste permite a adoção de novas classes de teste de estilo JUnit4, ea mudança gerrit amostra contém algum uso básico de suas características. Veja o exemplo na /platform_testing/tests/example/instrumentation/src/android/test/example/helloworld/HelloWorldTest.java .

Embora os padrões de teste sejam geralmente específicos para equipes de componentes, existem alguns padrões de uso geralmente úteis.

@RunWith(JUnit4.class)
public class HelloWorldTest {

Uma diferença significativa no JUnit4 é que os testes não precisam mais herdar de uma classe de teste de base comum; em vez disso, você escreve testes em classes Java simples e usa anotações para indicar certas configurações e restrições de teste. Neste exemplo, estamos instruindo que esta classe deve ser executada como um teste JUnit4.

    @BeforeClass
    public static void beforeClass() {
    ...
    @AfterClass
    public static void afterClass() {
    ...
    @Before
    public void before() {
    ...
    @After
    public void after() {
    ...
    @Test
    @SmallTest
    public void testHelloWorld() {
    ...

Os @Before e @After anotações são usados em métodos de JUnit4 para executar configuração de teste pré e desmontagem pós teste. Da mesma forma, os @BeforeClass e @AfterClass anotações são usados em métodos de JUnit4 para executar a configuração antes de executar todos os testes em uma classe de teste, e desmontagem depois. Observe que os métodos de configuração e desmontagem do escopo da classe devem ser estáticos. Quanto aos métodos de ensaio, ao contrário da versão anterior do JUnit, eles não são mais necessários para iniciar o nome do método com o test , em vez disso, cada um deles deve ser anotado com @Test . Como de costume, os métodos de teste devem ser públicos, não declarar nenhum valor de retorno, não aceitar parâmetros e podem lançar exceções.

Importante: os métodos de teste em si são anotados com @Test anotação; e nota que para os testes de ser executado através de APCT, eles devem ser anotado com tamanhos de testes: o exemplo anotado método testHelloWorld como @SmallTest . A anotação pode ser aplicada no escopo do método ou no escopo da classe.

acessando instrumentation

Apesar de não ser abordado no exemplo básico Olá mundo, é bastante comum para um teste de Android para exigir acesso Instrumentation exemplo: esta é a interface API núcleo que fornece acesso a contextos de aplicação, APIs de teste de ciclo de vida relacionada atividade eo mais.

Porque o JUnit4 testa já não necessitam de uma classe base comum, ele não é mais necessário para obter Instrumentation exemplo, através InstrumentationTestCase#getInstrumentation() , em vez disso, o novo corredor de teste administra-lo através InstrumentationRegistry onde configuração contextual e ambiental criado por quadro instrumentação é armazenado.

Para acessar a instância de Instrumentation classe, simplesmente chamar método estático getInstrumentation() em InstrumentationRegistry classe:

Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation()

Construir e testar localmente

Para a maioria dos casos de uso comum, empregar Atest .

Para os casos mais complexos que exigem personalização mais pesado, siga as instruções de instrumentação .