Organização de autotestes no exemplo de um aplicativo móvel para EDMS



+ versão de capa melhor, mas menos engraçada
imagem

Mais cedo ou mais tarde, todo mundo vem para a AT. A situação em que isso acontece tarde é compreensível e quando é cedo? E como entender o que já é possível?

O artigo é baseado na experiência de uma equipe: falarei sobre nossos pré-requisitos e razões para a introdução do autoteste, quais critérios selecionamos para a disponibilidade de AT e quais ferramentas usamos no final. Spoiler: no final, alguns casos de sucesso e poucos casos com o Xamarin.UITest.

Introdução sobre o produto
. , , , , , . offline.

-.

image

O que a teoria diz


Considere a abordagem de automação usando a pirâmide de teste como exemplo. Como os níveis da pirâmide, tomarei os tipos de teste que usamos. Ou seja, testes de unidade, testes de integração e testes de ponta a ponta (E2E).
imagem

Os testes de unidade (testes de unidade) verificam a operação de pequenas partes individuais do sistema (função, método). Eles são pequenos, passam rapidamente, não exigem grandes custos de desenvolvimento e manutenção.

Testes de integração testam a operação do aplicativo com componentes externos. Por exemplo, com um banco de dados ou vários serviços. Eles levam mais tempo, tanto para escrever quanto para suportar testes, e para suas execuções. Para esses testes, na maioria das vezes você precisa configurar e dar suporte a algum tipo de ambiente. Nesse caso, eles geralmente se tornam mais frágeis, porque ambiente tendem a quebrar.

Testes de ponta a ponta verificam a operação do sistema como um todo, emulando as ações do usuário final. Na maioria das vezes, eles acessam o sistema através da interface do usuário: pressionam os botões como usuário, preenchem os campos, etc. Mas eles também podem ser usados ​​em sistemas sem interface. Esses testes são muito mais caros do que os considerados acima, porque requerem mais tempo para desenvolver e suportar os próprios testes e todo o ambiente. Além disso, eles são muito frágeis, porque são afetados por alterações em qualquer parte do sistema, e o comportamento inesperado de um emulador ou navegador pode afetar o resultado de um teste específico. A duração da execução desses testes também é significativamente maior que o restante: para executar qualquer ação individual do usuário, é necessário executar várias outras. Por exemplo, efetue login ou vá para o item de menu desejado.

De acordo com o princípio da pirâmide, quanto mais fácil, rápido e barato o teste, mais eles devem estar em uma porcentagem do número total de testes. Essa. um teste completo não deve verificar a atribuição de valores diferentes para um campo (a menos que você precise verificar a operação da interface do usuário nesses casos).

Para todos esses tipos de teste, foi atribuída uma função. Em algum momento do ciclo de vida do aplicativo, surge a necessidade de uma ou outra automação de teste. Seu produto pode funcionar facilmente apenas com testes de unidade e pode aumentar rapidamente para a necessidade de testes de ponta a ponta. A principal coisa ao planejar a automação é entender de que exatamente seu produto se beneficiará atualmente e para o qual você provavelmente perderá tempo.

Ao implementar a automação, não se esqueça dos testes manuais, mesmo com uma grande quantidade de automação, sempre haverá coisas que precisam ser verificadas manualmente. No mínimo, novas funcionalidades para as quais não é racional escrever testes imediatamente.

Mas toda a automação, na minha opinião, deve visar principalmente a redução do volume de testes manuais. E ao planejar testes manuais, vale a pena considerar quais casos já estão automatizados.

Como os testes automáticos são organizados conosco?


Cada produto individualmente possui testes de unidade, executados em cada PR. Eles são de responsabilidade dos desenvolvedores.

imagem

Os testes de integração verificam a interação do serviço da web com o EDMS.

Eles simulam a operação de um aplicativo cliente. Eles recorrem aos métodos de serviço da Web para obter e modificar dados do EDS.

Execute após cada compilação de uma nova versão do lado do servidor.

imagem

Testes de ponta a ponta simulam o desempenho do usuário final. Eles pressionam os botões na interface do aplicativo móvel, e o aplicativo funciona com o EDMS por meio de um serviço da web.

Os testes de integração e de ponta a ponta agora estão sendo feitos pelos testadores.

Por que precisamos de aplicativos móveis AT de ponta a ponta?


Antes de iniciar a automação, vale a pena considerar o problema que você deseja resolver introduzindo-o. A menos que você tenha objetivos específicos, não poderá explicar ao supervisor ou ao proprietário do produto por que deve dedicar tempo aos autotestes. Será difícil avaliar os benefícios de sua implementação.

Há muito tempo testamos aplicativos móveis manualmente. Embora esse fosse um aplicativo com pouca funcionalidade, lidamos com sucesso. Tudo o que foi desenvolvido foi ± em uma área, e os testes manuais podem ser organizados de forma a testar rápida e facilmente todos os recursos do aplicativo.

Mas depois de algum tempo, o aplicativo começou a crescer com novos recursos, que eram bastante independentes e exigiam mais atenção. Houve um problema com bugs na funcionalidade antiga, que só conseguimos encontrar nos últimos estágios do projeto.

Portanto, os objetivos iniciais da introdução de testes de interface do usuário de aplicativos móveis para nós eram:

  • Cobertura AT dos principais casos de aplicação;
  • reduzindo o número de erros na regressão antes do lançamento.

Atingir o primeiro objetivo deve automaticamente levar ao alcance do segundo, como execuções regulares de testes para funcionalidade básica em todo o projeto devem encontrar bugs nos estágios anteriores.

Depois de algum tempo, outro objetivo foi adicionado - reduzir o número de testes de regressão manual.

E quando é a hora de introduzir automação nos testes?


Antes de iniciar a automação de teste, você deve avaliar a prontidão do seu aplicativo para automação. E também sua disponibilidade para esse processo.

Funcionalidade estável


Para que o AT tenha a chance de ser útil, o aplicativo deve ter funcionalidade estável. E vale a pena cobrir autotestes. Caso contrário, você gastará muito tempo e esforço atualizando e atualizando testes como resultado de alterações no aplicativo.

Planos de desenvolvimento


A automação deve ser implementada apenas se o seu aplicativo tiver planos futuros de desenvolvimento para os próximos anos. Por que autotestes para um aplicativo que não muda?

Recursos


Você deve ter recursos para desenvolver testes e, o mais importante, para obter suporte adicional. Essa. Ao planejar a implementação da automação, é importante entender que os recursos não serão necessários apenas para escrever testes. Os testes certamente cairão por algum motivo. Os resultados das corridas precisarão ser analisados ​​e medidas tomadas. Incluindo mudar alguma coisa nos testes. Bem, além do suporte, não esqueça a necessidade de seu desenvolvimento.

Como decidir?


Ao pensar nos testes de interface do usuário de aplicativos móveis, criamos imediatamente grandes prateleiras com dispositivos ou farms nos quais os dispositivos são alugados. Houve muitos problemas nos testes devido à necessidade de verificar tamanhos e resoluções de tela diferentes. Sim, e não havia muita experiência em desenvolvimento. Foi tudo assustador e forçado a adiar os planos.

Os objetivos formulados anteriormente chegaram ao resgate e o principal foi um teste funcional. Portanto, começamos pequenos.

Como resultado, nossos testes:

  • execute uma vez por dia (isso é suficiente para encontrar a fonte do problema se algo acontecer);
  • executar localmente em nossos servidores;
  • em dois dispositivos (iOS e Android);
  • para Android, existem agora cerca de 50 testes, a execução leva cerca de uma hora (junto com a montagem);
  • para iOS - cerca de 40 testes, a execução leva cerca de 30 minutos;
  • os testes são escritos usando Xamarin.UITest;
  • eles são iniciados automaticamente por compilações no TFS, no mesmo local em que monitoramos os resultados das execuções.

imagem

Um pouco sobre o Xamarin.UITest


Essa é uma estrutura para teste automático da interface do usuário para projetos no Xamarin.iOS e Xamarin.Android (também é anunciado o suporte a Objective-C / Swift e Java). Os testes são gravados em C # usando o NUnit. Projetos de conteúdo podem ser facilmente integrados.

O princípio da operação da estrutura é baseado em dois componentes: pesquisando um elemento (Consultas) e executando quaisquer ações com ele (Ações), por exemplo, pressionando ou executando um furto.

Aqui, por exemplo, está um teste que verifica a exibição do erro ao inserir um login inválido:

public void ShowErrIncorrectLoginOrPassword_IfLoginIsWrong()
  {
    var wrongLogin = TestsSettings.UserLogin + "1";
    app.EnterLoginAndPassword(wrongLogin, TestsSettings.UserPassword);
    app.WaitForElement(Resources.Identifiers.ErrorMessage, "Login is incorrect, alert message wasn't shown.", TestsSettings.Delay);
    Assert.AreEqual(CoreResources.ErrIncorrectLoginOrPassword, ErrorMessage);
  }


private string ErrorMessage => 
app.Query(x => x.Marked(Resources.Identifiers.ErrorMessage)).First().Text;

O método de entrada de credencial usado nele:

public static void EnterLoginAndPassword(this AndroidApp app, string login, string password)
    {
      app.WaitForElement(Resources.Identifiers.LoginEdit, TestsSettings.Delay);
      app.EnterText(Resources.Identifiers.LoginEdit, login);
      app.EnterText(Resources.Identifiers.PasswordEdit, password);
      app.Tap(Resources.Identifiers.LoginButton);
    }

Neste exemplo, os métodos de estrutura padrão são usados ​​- aguardando um elemento, inserindo texto, clicando em um elemento.

Ao desenvolver e depurar testes, é conveniente usar o utilitário de console REPL (read-eval-print-loop), que permite exibir a árvore de elementos localizados agora na tela e executar métodos de estrutura padrão.

Para ser inesperado para nós


Às vezes, abordar elementos da interface não leva ao que esperávamos.

Por exemplo, quando uma nova janela em um aplicativo é aberta com um fragmento na mesma atividade, o usuário vê apenas essa nova janela na tela. Mas, neste caso, haverá aqueles elementos na árvore de elementos visíveis que o usuário não vê agora com seus olhos. A busca por esse elemento "invisível" será bem-sucedida e você poderá executar uma ação com ele. Isso é apenas um clique será executado na janela que o usuário vê. Essa. de fato, será um falso positivo.

A árvore pode conter vários elementos idênticos; por padrão, a ação será executada com o primeiro elemento adequado da árvore. E se em um teste você acessou um elemento por meio de um rótulo e, em seguida, tiver um elemento com o mesmo rótulo em algum lugar, o teste começará a cair (ou talvez não, se o elemento necessário for o primeiro).

Tivemos um caso em que um teste escrito e depurado caiu no primeiro lançamento de combate. Porque os testes foram executados em um dispositivo com um tamanho de tela diferente. E o elemento clicado neste dispositivo apareceu em outro elemento da interface.

imagem

A pasta Caixa de saída estava sob o botão Criar tarefa e, nesse caso, clicar na pasta levava a clicar no botão. Esta é uma situação familiar para o usuário, ele simplesmente rolará a tela. Mas na árvore de elementos essa sobreposição não é visível.

Tais problemas causam pequenos inconvenientes e fazem você pensar em alguns testes com mais cuidado. E, às vezes, apenas encaixamos os dados no banco de dados para que nada interfira no teste. Afinal, o objetivo neste exemplo é abrir uma pasta e não verificar se nada impede sua abertura.

Outra surpresa e decepção foi a incapacidade de executar e depurar testes iOS do Visual Studio para Windows. Esse recurso ainda não foi implementado. Eu tenho que trabalhar no estúdio para MacOS.

Alguns resultados do capitão


Implemente a automação, se fizer sentido.

Deixe seus testes com um mínimo de configurações, execute-os manualmente e apenas uma vez por mês, mas se eles resolverem seus problemas e o ajudarem - por que não?

Bem, não se esqueça do princípio da pirâmide.

All Articles