Testar aplicações móveis com Xamarin Test Cloud

Âmbito

Este artigo tem como objetivo mostrar como podemos testar as aplicações móveis usando Xamarin Test Cloud, sejam estas aplicações Xamarin ou aplicações nativas.

Introdução

O desenvolvimento móvel tem tido um crescimento exponencial, trazendo com isso um “booom” de aplicações para as diversas lojas. Claro está, que muitas das vezes quantidade não significa qualidade e quantas vezes nós próprios nos deparamos com potências aplicações que apenas precisam de melhorias, e em alguns casos a aplicação funciona bem numa plataforma e noutra não (por razões diversas). Com este crescimento e com base nas diversas necessidades muitas soluções têm surgido no mercado para que os programadores possam acompanhar o desempenho da aplicação durante a sua utilização.

Independentemente da forma como os programadores acompanham as suas aplicações para fazer manutenção corretiva, coloca-se a seguinte questão: será que isto é uma boa solução? Isto é, será que é bom serem os nossos utilizadores a encontrar os bugs e comportamentos não esperados? Porque isto é ou tem sido uma realidade… Ou será que os programadores devem-se preocupar com estratégias de testes antes de esta chegar ao utilizador final?

Seguindo boas práticas podemos dizer que cada aplicação deve ser testada antes de chegar ao utilizador final, e deve-se definir pelo menos os testes unitários e os testes de aceitação (em alguns casos pode haver necessidade de definir os testes de integração, com serviços externos, como por exemplo o BackEnd). Com a criação de testes vamos conseguir provar que o comportamento desenvolvido é o que está a ser testado, e se alguma alteração quebrar os testes ou o bom funcionamento da aplicação, é possível colocar em causa se houve um erro inicial, um erro no momento da alteração ou se o problema em causa não foi tido em conta, e claro está, proceder à correção.

Tipos de testes

A fase de testes é o processo que permite garantir que o desenvolvimento realizado faz efetivamente o que foi definido inicialmente. Esta fase pode incluir vários tipos de testes, tendo cada um o seu propósito, resumidamente podemos dizer que:

  • Os testes unitários são testes escritos normalmente pelo(s) programador(es) que visa validar as várias funcionalidades de forma isolada, ie, o programador cria vários testes para verificar que um determinado método, classe, módulo ou componente é válido de acordo com os requisitos e faz o que é expetável.
  • Os testes de integração são testes criados com o objetivo de validar a integração de classes, módulo ou componentes umas com as outras. No caso de aplicações móveis podemos dar como exemplo para testes de integração a comunicação entre o backend e a aplicação móvel.
  • Os testes de aceitação são testes criados maioritariamente pela equipa de QA, e que visa testar a aplicação como sendo uma caixa negra, ie, é sabido à partida que é possível realizar um conjunto de operações e ao efetuar essas operações é expetável um resultado final.

Na figura 1, podemos ver outros tipos de testes, e a relação custo/esforço e nº de testes, claro está que o mais comum é a criação de testes unitários, e nem sempre é feita a cobertura de todos os tipos de testes.

Xamarin Test Cloud: vários tipos de testes

Figura 1: Vários tipos de testes

Execução automática de testes

Outra questão extremamente relevante, é a execução dos diversos testes ser um processo automático, ie, à medida que as alterações se vão refletindo se possa confirmar que tudo o que estava a funcionar está efetivamente a funcionar, sem que se tenha que recorrer a processos manuais. Por esta razão, muitas vezes é criando um sistema de integração continua (usando por exemplo Team City ou TFS Online), em que na operação de checkin / push para o gestor de controlo de versões são executados todos os testes, referente à aplicação, e só após a confirmação de que todos os testes estão OK é que são aceites as novas funcionalidades ou alterações por parte do servidor.

Um programador mais atento vai questionar-se: é verdade que posso executar os testes unitários e de integração em processo automático, usando as ferramentas de desenvolvimento e de testes (seja NUnit ou MSTest), mas então, e os testes de aceitação? Uma vez que para verificar os diversos testes de aceitação é preciso executar a aplicação!? Vou ter constantemente uma equipa de QA a fazer o processo manualmente?

Neste artigo vamos ver como podemos escrever e executar os testes de aceitação de forma automática recorrendo à solução da Xamarin, o Test Cloud.

Descrição

Para dar suporte ao artigo, consideremos a aplicação TODO, desenvolvida com base na plataforma Xamarin, cujo código fonte pode ser obtido no seguinte endereço https://github.com/xamarin/xamarin-forms-samples/tree/master/Todo.

Xamarin Test Cloud: aplicação TODO

Figura 2: Aplicação TODO

Consideremos agora que foi terminada uma das fases de desenvolvimento, e que existe um conjunto de funcionalidades testadas recorrendo a testes unitários e de integração. Visto isto, a equipa de desenvolvimento e/ou a equipa de QA pretende proceder à criação de testes de aceitação, para validar todo o fluxo da aplicação e as diversas funcionalidades. Desta forma, vamos proceder à criação dos testes de aceitação, recorrendo à biblioteca Xamarin.UITest.

Xamarin.UITest

A Xamarin.UITest é uma biblioteca desenvolvida pela Xamarin que permite escrever os testes automáticos de aceitação, ao nível da UI, de aplicações desenvolvidas com base na plataforma Xamarin. Esta biblioteca é baseada em Calabash – uma biblioteca que permite escrever testes automáticos de aceitação, ao nível UI, para aplicações nativas iOS e Android.

Na figura 3, podemos ver o diagrama de decisão relativo às frameworks que podemos utilizar nas aplicações móveis.

Xamarin Test Cloud: escolha de framework de testes

Figura 3: Diagrama de decisão

Esta biblioteca:

  • É baseada em C# e usa a biblioteca NUnit (versão 2.6.4)
  • Está apenas disponível para Xamarin.iOS e Xamarin.Android
  • É suportada pelos diversos IDE (Xamarin Studio e Visual Studio)
  • O Xamarin Studio disponibiliza projetos template para Xamarin.iOS, Xamarin.Android e Cross-Platform
  • O Visual Studio apenas disponibiliza projetos template para projetos Cross-Platform
  • Está disponível através de pacote Nuget – cuja versão atual é Xamarin.UITest 1.2.0
  • É executado sobre um agente, Xamarin Test Cloud Agent, que vai permitir executar os testes sobre a aplicação (quer estejamos perante o simulador ou um dispositivo)

Criação de projeto

Comecemos por abrir o projeto TODO no Xamarin Studio, como podemos visualizar nas imagens seguintes.

Xamarin Test Cloud: adicionar novo projeto

Figura 4: Adicionar novo projeto
Xamarin Test Cloud: seleção do projeto

Figura 5: Seleção do projeto
Xamarin Test Cloud: definição do nome do projeto

Figura 6: Definição do nome do projeto
Xamarin Test Cloud: solução com o projeto de testes

Figura 7: Solução com o projeto de testes

O template do projeto de testes, que acabamos de criar, inclui dois ficheiros: AppInitializer.cs e Test.cs.

AppInitializer

A classe AppInitializer, com apenas um método (StartApp) irá:

  • Definir a aplicação sobre qual correm os testes
    • Com base no pacote APK, IPA ou bundle (.app)
      app = ConfigureApp.iOS.AppBundle("../../path/todo.app");
      app = ConfigureApp.Android.ApkFile("../../path/todo.apk");
      
    • Com base no nome da aplicação instalada no dispositivo
      app = ConfigureApp.iOS.InstalledApp("com.xamarin.todo");
      app = ConfigureApp.Android.InstalledApp("com.xamarin.todo");
      
    • Com base no projeto definido na solução
  • Definir o dispositivo que irá executar os testes (por omissão é usado o simulador)
  • Iniciar a aplicação, quando o método StartApp é invocado

Para saber mais detalhes, consulte a documentação fornecida pela Xamarin:

Para o caso da aplicação TODO iremos ter o seguinte code snippet:

public class AppInitializer
{
        public static IApp StartApp (Platform platform)
        {
            // TODO: If the iOS or Android app being tested is included in the solution 
            // then open the Unit Tests window, right click Test Apps, select Add App Project
            // and select the app projects that should be tested. 
            // The iOS project should have the Xamarin.TestCloud.Agent NuGet package
            // installed. To start the Test Cloud Agent the following code should be
            // added to the FinishedLaunching method of the AppDelegate:
            //    #if ENABLE_TEST_CLOUD
            //    Xamarin.Calabash.Start();
            //    #endif
            if (platform == Platform.Android) {
                return ConfigureApp
                    .Android

                    .ApkFile ("../../../Todo.Droid/bin/Debug/TodoDroid.apk")
                    .StartApp ();
            }

            return ConfigureApp
                .iOS
                .AppBundle ("../../../Todo.iOS/bin/iPhoneSimulator/Debug/TodoiOS.app")
                .StartApp ();
        }
}

De realçar que na configuração inicial do pacote da aplicação para iOS, é possível surgir o erro

SetUp: System.Exception: The app bundle in XTC/Todo/PCL/Todo.iOS/bin/iPhoneSimulator/Debug/TodoiOS.app does not seem to be properly linked with Calabash. Please verify that it includes the Calabash component.

que significa que a aplicação iOS não contém a referência para o Xamarin Test Cloud Agent ou não contém a chamada ao método Xamarin.Calabash.Start() no event handler AppDelegate.FinishedLaunching. Para o caso em que este erro continue a surgir e esteja tudo bem configurado, é recomendável que se apague a pasta bin do projeto de iOS e se faça build novamente.

Xamarin Test Cloud: adicionar o pacote Xamarin Test Cloud Agent ao projeto de iOS

Figura 8: Adicionar o pacote Xamarin Test Cloud Agent ao projeto de iOS
Tests

A classe Tests define um método que é designado por setup que permite iniciar os testes sobre a UI da aplicação, e contém os vários testes para as diversas plataformas (na prática podem existir mais do que uma classe com testes, dependendo da organização destes).

Por omissão, esta classe está definida para lançar os testes nas duas plataformas, isto porque a classe está decorada com os seguintes atributos:

[TestFixture (Platform.Android)]
[TestFixture (Platform.iOS)]
public class Tests { ... }

Isto significa, se os testes definidos estiverem a suportar mais do que uma plataforma, a sua execução originará que vários simuladores iniciem a aplicação ao mesmo tempo (em alguns casos poderá ter interesse analisar em simultâneo o comportamento da aplicação nas diversas plataformas, não sendo, no entanto, um cenário comum).

O IDE irá lançar a aplicação no simulador ou no dispositivo, consoante o que estiver configurado. No caso da plataforma Android é requisito haver pelo menos um dispositivo conectado ao ADB, para que assim seja possível executar a aplicação e consequentemente os testes. É também requisito que a aplicação tenha permissões de internet, independentemente se esta requer o envio/receção de dados, uma vez que a anatomia da biblioteca requer esta permissão.

Nota: Sendo a biblioteca Xamarin.UI.Tests baseada em NUnit, é possível usar o atributo [Category] para categorizar os testes e desta forma organizar os diversos testes.

Publicado na edição 52 (PDF) da Revista PROGRAMAR.