Connect(); 2016

Volume 31 - Número 12

Connect(); Mobile Test - Dimensione o teste de seu aplicativo móvel automatizado com o Xamarin Test Cloud

De Justin Raczak; 2016

Nos últimos anos, houve uma mudança drástica na forma como as equipes compilam e disponibilizam software. Onde antes se acreditava que os processos de obtenção de requisitos demorados garantiria a entrega de um produto perfeito com a primeira versão, agora já se sabe que o aprendizado rápido aliado a iterações rápidas é a chave do sucesso. Como o pensamento muda, os fluxos de trabalho também deverão mudar. Os ciclos de desenvolvimento que demoram meses ou anos seguidos pelas demoradas fases de QA em cascata não facilitam o aprendizado rápido. Os loops de comentários devem ser reduzidos e as pequenas alterações devem ser implementadas rapidamente e liberadas para os usuários. Para implantar rapidamente, deve ser conhecido que o software está sempre em bom estado. A automação de testes torna isso possível.

Os testes automatizados permitem que você teste seus aplicativos de formas que costumavam levar dias ou semanas. Em vez de aguardar até o fim de um sprint composto por centenas de linhas de código novo, você poderá testar pequenas alterações adicionadas a todas as confirmações. Esses testes contínuos mostram os defeitos assim que eles são introduzidos e reduzem o tempo necessário para depurá-los. E, como o comportamento do aplicativo é continuamente validado, você terá confiança para implantar para os usuários sempre que estiver preparado. Os testes automatizados tornam possível um mundo no qual você descreve defeitos e remete uma correção no mesmo dia. No entanto, o ecossistema móvel apresenta desafios únicos com uma paisagem diversa do dispositivo móvel e criadores de sistemas operacionais.

O Xamarin Test Cloud agiliza e simplifica o dimensionamento dos testes automatizados com alterações mínimas em seu fluxo de trabalho existente. Oferecendo mais de 400 configurações de dispositivo exclusivas, o Test Cloud permite validar o comportamento do seu aplicativo nos modelos de dispositivo e em versões do sistema operacional importantes para seus usuários sem a despesa ou a sobrecarga de gerenciamento que vem com a compilação e o gerenciamento em seu próprio laboratório de dispositivos. Na maioria dos casos, você pode acessar esse enorme valor com poucas ou nenhuma alteração em seu código.

O Test Cloud oferece suporte á criação de testes no C# (UITest), no Ruby (Calabash) e no Java (Appium e Espresso). Na parte de modificação do projeto deste artigo, me concentrarei na adição da estrutura de testes mais solicitada, Appium com JUnit, e mostrarei as alterações necessárias para fazer seu projeto executar seus testes existentes no Test Cloud. Também examinarei a interface da Web onde você examinará seus resultados de teste e solucionará os testes com falha. As modificações específicas necessárias podem mudar com o tempo. Encontre a versão mais recente destas instruções em bit.ly/2dhp2VQ.

Neste exemplo, suponho as seguintes pré-condições:

  • Uma conta ativa do Test Cloud (inscreva-se em bit.ly/2e3YgTy)
  • Uma ferramenta de linha de comando instalada (instruções em bit.ly/2dcrbXS)
  • Um projeto de aplicativo Android nativo
  • Um pacote de testes Appium existente e escrito em Java com JUnit (versão 4.9, pelo menos) de acordo com o Appium 1.5
  • Sistema de compilação do Maven (versão 3.3.9, pelo menos)

Mudanças no Sistema de Compilação

Antes de poder começar a usar o Test Cloud, será necessário adicionar a dependência para garantir que as tarefas de preparação dos arquivos de requisito estejam disponíveis para sua compilação.

Adicionar a Dependência do Test Cloud Para incluir o Test Cloud em seu projeto e garantir que seus drivers avançados do Android e do iOS estejam disponíveis em tempo de compilação, adicione a seguinte dependência ao seu arquivo pom.xml:

<dependency>
  <groupId>com.xamarin.testcloud</groupId>
  <artifactId>appium</artifactId>
  <version>1.0</version>
</dependency>

Adicionar o Perfil de Carregamento Adicione o perfil da Figura 1 ao seu pom.xml dentro da marca <profiles>. Se você ainda tiver uma seção <profiles>, crie uma e adicione o perfil. Esse perfil englobará suas classes de teste e todas as dependências na pasta de destino/carregamento onde elas podem ser carregadas no Test Cloud.

Figura 1 Perfil de Carregamento do Test Cloud

<profile>
  <id>prepare-for-upload</id>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-dependency-plugin</artifactId>
        <version>2.10</version>
        <executions>
          <execution>
            <id>copy-dependencies</id>
            <phase>package</phase>
            <goals>
              <goal>copy-dependencies</goal>
            </goals>
            <configuration>
              <outputDirectory>${project.build.directory}
                /upload/dependency-jars/</outputDirectory>
              <useRepositoryLayout>true</useRepositoryLayout>
              <copyPom>true</copyPom>
            </configuration>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-resources-plugin</artifactId>
        <executions>
          <execution>
            <id>copy-pom-file</id>
            <phase>package</phase>
            <goals>
              <goal>testResources</goal>
            </goals>
            <configuration>
              <outputDirectory>${project.build.directory}
                /upload/</outputDirectory>
              <resources>
                <resource>
                  <directory>
                    ${project.basedir}
                  </directory>
                  <includes>
                    <include>pom.xml</include>
                  </includes>
                </resource>
              </resources>
            </configuration>
          </execution>
          <execution>
            <id>copy-testclasses</id>
            <phase>package</phase>
            <goals>
              <goal>testResources</goal>
            </goals>
            <configuration>
              <outputDirectory>${project.build.directory}
                /upload/test-classes</outputDirectory>
              <resources>
                <resource>
                  <directory>
                    ${project.build.testOutputDirectory}
                  </directory>
                </resource>
              </resources>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</profile>

Alterações nos Testes

Agora que sua compilação está configurada, você deverá modificar suas classes de teste para aproveitar as extensões Java do Test Cloud.

Adicionar as Importações às Classes de Teste Importe os seguintes pacotes para suas classes de teste:

import com.xamarin.testcloud.appium.Factory;
import com.xamarin.testcloud.appium.EnhancedAndroidDriver;
import org.junit.rules.TestWatcher;
import org.junit.Rule;

Instanciar o TestWatcher Insira esta instanciação em uma das suas classes de teste:

@Rule
public TestWatcher watcher = Factory.createWatcher();

Atualizar suas Declarações de Driver Substitua todas as declarações de AndroidDriver<MobileElement> com EnhancedAndroidDriver­<MobileElement>, desta forma:

private static EnhancedAndroidDriver<MobileElement> driver;

Atualizar suas Instanciações de Driver Substitua todas as instanciações do seu driver de forma que as linhas do formulário:

Driver = new AndroidDriver<MobileElement>(url, capabilities);

se tornem:

Driver = new EnhancedAndroidDriver<MobileElement>(url, capabilities);

O driver avançado permite “rotular” as etapas no teste usando driver.label(“myTestStepLabel”). Este método produzirá um rótulo para a etapa do teste e a captura de tela de acompanhamento que estará visível no relatório de teste no Test Cloud. Recomendo chamar o rótulo no método @After, que vai capturar uma captura de tela do aplicativo em seu estado final antes da conclusão do teste. A captura de tela será feita mesmo se o teste estiver falhando, o que pode fornecer informações valiosas sobre o motivo da falha. Na prática, isso poderia ser algo como:

@After
  public void tearDown(){
    driver.label("Stopping app");
    driver.quit();
  }

Carregar no Test Cloud

Agora que seu projeto está equipado com todos os pré-requisitos, você está pronto para preparar seus arquivos e executar no Test Cloud. Antes de prosseguir com as etapas de carregamento, é uma boa ideia experimentar uma execução local e garantir que tudo esteja funcionando como esperado. Se precisar solucionar problemas nas alterações de configuração que você acabou de fazer, será muito mais rápido fazer isso localmente.

Para empacotar suas classes de teste e todas as dependências na pasta de destino/carregamento, execute o seguinte comando:

mvn –DskipTests -P prepare-for-upload package

Talvez você queira verificar se o diretório de destino/carregamento existe agora na pasta raiz do seu projeto para garantir que está pronto para o carregamento. Se esse for um aplicativo novo no Test Cloud, será necessário criar o aplicativo como parte da execução do teste. Siga o fluxo para criar uma nova execução de teste para selecionar seus dispositivos, definir preferências e gerar o comando necessário para a execução. Para este exercício, recomendo a seleção de um pequeno número de dispositivos da categoria Camada 1 para que seus resultados estejam prontos para serem examinados rapidamente. Copie o comando gerado e execute-o na linha de comando.

Assim que o carregamento do arquivo tiver sido negociado e validado com êxito, os dispositivos serão provisionados, seu aplicativo será instalado e seus testes serão executados. O modelo operacional do Test Cloud se baseia na simultaneidade do dispositivo ou no número de dispositivos físicos que podem ser usados em paralelo. Por exemplo, um usuário com cinco dispositivos simultâneos pode testar um aplicativo no Nexus 5X, no Nexus 6P, no Samsung Galaxy S5, no Samsung Galaxy S6 e no HTC M8 ao mesmo tempo. Essa eficiência é uma das vantagens mais significativas do Test Cloud, facilitando o aumento da sua cobertura para se estender por mais dispositivos enquanto adiciona pouco ou quase nenhum tempo de espera adicional.

A ferramenta de linha de comando transmitirá atualizações no status da execução do teste e fornecerá um link para o relatório de teste logo após a execução do teste. Siga os três níveis de granularidade para examinar seus resultados.

Existem três níveis de granularidade com os quais você pode exibir seus resultados:

  • Relatório de visão geral.
  • Grade do dispositivo.
  • Relatório de detalhes do dispositivo.

Discutiremos cada um deles separadamente.

O Relatório de Visão Geral A visão geral oferece informações de resumo sobre uma execução de teste, incluindo detalhes de aprovação/falha, estatísticas de falha por versão de sistema operacional, fabricante e fator forma, além de detalhes sobre a própria execução, incluindo configurações de dispositivo direcionadas e o tempo de execução total (veja a Figura 2).

O Relatório de Visão Geral
Figura 2 O Relatório de Visão Geral

Se sua execução de teste produzir falhas, provavelmente desejará se aprofundar para explorar as causas raiz e coletar dados para depuração. A grade de dispositivo é o próximo nível de detalhe.

A Grade de Dispositivo A grade de dispositivo oferece um mecanismo altamente eficiente para a navegação em seus resultados de teste detalhados ao longo das capturas de tela de cada etapa. Com falhas claramente indicadas nas etapas do teste, você pode rapidamente acessar uma etapa com falha e examinar o estado visual do seu aplicativo em cada dispositivo. Para conjuntos de dispositivos maiores, você pode filtrar os dispositivos exibidos para ver somente os com falha para criar um campo mais claro para inspeção. Se a causa da falha não estiver aparente neste nível de detalhe, faça uma busca detalhada em mais um nível para exibir os detalhes do dispositivo (veja a Figura 3).

O Relatório de Grade do Dispositivo
Figura 3 O Relatório de Grade do Dispositivo

O Relatório de Detalhes do Dispositivo A exibição detalhada do dispositivo oferece o mesmo acesso para testar a navegação em etapas e as capturas de tela, mas oferece detalhes adicionais específicos do dispositivo selecionado, incluindo uso de CPU e de memória. Dessa exibição, você também pode acessar os logs de dispositivo e o rastreamento de pilha, artefatos que provavelmente serão os mais úteis ao investigar uma falha de teste (veja a Figura 4).

O Relatório de Detalhes do Dispositivo
Figura 4 O Relatório de Detalhes do Dispositivo

Neste ponto, segui o fluxo de trabalho mais comum no Test Cloud:

  1. Execute o teste (manualmente ou por meio da integração contínua, ou CI).
  2. Examine os resultados.
  3. Recupere artefatos de depuração.
  4. Corrija.

Em seguida, discutirei algumas maneiras simples de pensar sobre a estratégia de direcionamento de dispositivo e de otimização do fluxo de trabalho de teste para desempenho para manter seu pipeline fluindo rapidamente.

Considerações sobre a Cobertura do Dispositivo

A seleção dos dispositivos para os quais sua organização dará suporte e, por fim, testará é quase tão importante quanto os próprios testes. Embora existam várias fontes de agregações e de dados de mercados generalizados que possam ajudar a guiar suas ideias nesta área, a origem mais impactante é de dados de uso da sua própria base de usuários. A exceção a isso, é claro, é um aplicativo que só seja distribuído internamente para um conjunto de dispositivos conhecidos e gerenciados. Para aplicativos externos e de consumidor e aplicativos internos distribuídos sob uma política BYOD (traga seu próprio dispositivo), os dados de uso são sua melhor fonte.

Muitas ferramentas do mercado podem ajudar a reunir informações nos dispositivos usados por seu público-alvo. Esse é o conjunto de dados do qual você pode extrapolar sua lista de dispositivos com suporte. Você e sua organização escolherão a metodologia exata usada para determinar quais dispositivos deverão ter suporte da lista agregada. Na maioria dos casos, não fará sentido dar suporte a todos os dispositivos dos dados de uso, pois eles se tornam difíceis e caros com muita rapidez. Talvez você decida cobrir o máximo de dispositivos que componham uma determinada porcentagem da sua base de usuários. Ou talvez você decida pensar em termos de números de usuários e oferecer suporte ao número necessário de dispositivos para deixar menos de 500 dispositivos de usuários cobertos. Se você tiver um aplicativo de comércio eletrônico, talvez queira fazer uma referência cruzada de seus dados de uso com dados de transação, garantindo que os dispositivos que representam os maiores gastos e as transações mais frequentes sejam cobertos. Novamente, a abordagem específica usada para desenvolver sua lista de suporte a dispositivos deve se basear nas necessidades e nas metas da sua empresa.

Tenha em mente que o mercado móvel se move rapidamente. Isso significa que, para que sua lista de suporte seja precisa e significativa, você deverá inspecionar seus dados de uso regularmente. Analise os sinais do mercado que possam sugerir que seja uma boa hora para examinar os dados novamente, como a distribuição de um novo modelo de dispositivo ou sistema operacional.

Otimização do seu Pipeline de Testes

A melhor maneira de extrair o maior valor da automação de testes é testar com antecedência e com frequência. Isso reduz o tempo e o custo associados à correção de bugs e garante que o pipeline de implantação permaneça limpo. Mas à medida que as equipes e as operações aumentam, a latência pode crescer no pipeline e a produtividade do desenvolvedor pode diminuir. Vamos examinar formas de manter o pipeline limpo e a produtividade alta.

Nem Todos os Testes São Iguais À medida que os projetos aumentam com o tempo, a execução dos pacotes de teste demora mais. Há um ponto de inflexão no qual a execução do pacote de teste após uma alteração simples se torna dolorosa e incômoda, quase sempre levando a maus hábitos, como ignorar os testes. Você pode se apropriar disso ao pensar com antecedência sobre os caminhos críticos do seu aplicativo. Ou seja, quais fluxos e experiências em seu aplicativo devem funcionar? Usando o exemplo anterior de aplicativo de comércio eletrônico, isso pode significar que o usuário pode navegar pelos produtos, adicionar produtos ao carrinho e fazer check-out. É menos importante que os usuários possam definir suas preferências de notificação. Com essa estrutura pronta, fica muito mais prático executar testes em cada envio por push ou mesmo em cada confirmação. Em vez de executar o pacote de teste completo para pequenas alterações, você pode executar somente aqueles que façam parte dos caminhos críticos. Como, exatamente, você executa essa delimitação dependerá da estrutura de teste usada.

Os Dispositivos Certos no Momento Certo Embora testar todos os envios por push para uma ramificação de funcionalidade possa ser ideal de uma perspectiva da qualidade, isso rapidamente se tornará caro para equipes maiores, especialmente aquelas que dão suporte a várias configurações de dispositivo diferentes. Você pode reduzir a sobrecarga aqui ao aplicar uma estratégia progressiva para seu dispositivo direcionando para essas execuções de teste. Uma compilação de uma ramificação de não produção precisa ser testada em todos os dispositivos aos quais você presta suporte? A resposta provavelmente é não. Em vez disso, você pode selecionar um número razoável de dispositivos que equilibre os testes efetivos com tempos de espera menores. Para uma compilação de pré-produção do CI, uma amostra dos modelos de dispositivo populares e das versões do sistema operacional da lista de suporte do seu dispositivo oferecerá um nível valioso de cobertura sem elevar o tempo de compilação para além de uma hora. Para um desenvolvedor individual que esteja testando a partir de uma estação de trabalho local, os testes em um ou dois dispositivos deve ser suficiente.

Existem poucos exemplos apenas sobre as formas de pensar sobre a configuração do seu fluxo de trabalho de testes. O ponto mais amplo é investir o tempo para questionar se o fluxo do seu pipeline é ideal. Mesmo se você tiver respondido essa questão antes, como acontece com tudo o que você faz, sempre será uma boa ideia inspecionar e adaptar diariamente.

Conclusão

Neste artigo, você viu como é fácil migrar da execução de seus teste em um simulador ou um dispositivo local único para aproveitamento do poder de centenas de configurações de dispositivo usando o Xamarin Test Cloud. Eu também toquei em algumas estratégias para a organização do seu fluxo de trabalho de testes e a extração do maior valor dos seus recursos de teste. Se você ainda não estiver usando o Test Cloud, poderá se inscrever em uma avaliação gratuita em bit.ly/2e3YgTy para começar a usá-la com seus projetos hoje.


Justin Raczak é gerente sênior de programas na Microsoft e lidera o serviço de automação de testes móveis. Embora ele só tenha ingressado na Microsoft recentemente, se concentrou em testes automatizados e em sua função na entrega contínua avançada pelos três últimos anos. Entre em contato com ele pelo email justin.raczak@microsoft.com.

Agradecemos aos seguintes especialistas técnicos da Microsoft pela revisão deste artigo: Simon Søndergaard
Simon Søndergaard é engenheiro de software na Microsoft.