Enfrentando o desafio do teste em diversos canais

Testes que atravessam interfaces, de remoto para a web e de volta para remoto

Com o crescimento viral dos aplicativos remotos e com acesso à web, há novos desafios para o teste em diversos canais, ou a intercalação de um único cenário de teste em várias interfaces. Processos de negócios, e mesmo tarefas dentro desses processos, estão sendo executados em uma variedade cada vez maior de plataformas. Mover-se entre interfaces está tornando-se um requisito, especialmente de dispositivos móveis para web e de volta para os móveis. Um exame das abordagens que funcionaram no passado leva a uma discussão sobre como lidar com o futuro.

Monica Luke, Lifecycle Scenario Architect, IBM

author photoMonica Luke tem quase 20 anos de experiência em engenharia de software. Ela passou a fazer parte do software IBM Rational há nove anos, na organização de teste. Desde então, Monica liderou várias equipes de automação de teste, deteve o cargo de arquiteta de automação de testes e ganhou um Outstanding Technical Achievement Award por uma estrutura de automação de teste muito usada internamente na IBM. Em 2010, ela passou para a equipe IBM Rational Strategic Offerings, ajudando a criar integrações para acelerar o valor do cliente nas ferramentas de Collaborative Lifecycle Management, incluindo os demos gravados para "Five ALM Imperatives", disponíveis em jazz.net/blog. Em 2012, Monica lidera o esforço de acelerar o teste agile em um ambiente de ciclo de vida colaborativo, com a tecnologia Green Hat.



08/Out/2012

Diversos canais descreve aplicativos que têm mais de uma interface. Está se tornando mais comum com a evolução do desktop para a computação baseada na web e para o mundo da computação remota. Há mais e mais interfaces para o mesmo aplicativo devido à combinação de dispositivos (tablets, celulares, laptops, desktops) e maneiras de interagir com eles ("apps" de dispositivos específicos, navegadores e aplicativos clientes tradicionais). Por exemplo, pense em aplicativos financeiros, que usam a mesma lógica de negócios para um aplicativo da web, um aplicativo remoto e talvez uma CLI (interface da linha de comandos). Com a maior prevalência da arquitetura orientada a serviços (SOA) e dos serviços da web, em muitos sentidos o que os integradores fazem é recombinar serviços com novos frontends. Mas a lógica de negócios (também conhecida como serviço) continua a mesma.

Da mesma forma que as equipes de desenvolvimento estão reutilizando código para reduzir custos de manutenção e aumentar a produtividade, as equipes de teste precisam de maneiras de reutilizar cenários e automação de teste para acompanhar o ritmo.

Enfrentando o desafio do teste em diversos canais

Alguns anos atrás, eu fui arquiteta de automação de testes responsável pelo desenvolvimento de toda a automação de não um, mas dois aplicativos com mais de uma interface. Ambas tinham interfaces com o usuário "nativas" que usavam controles MFC (Microsoft Foundation Class) do Microsoft Windows de 32 bits, uma interface da web que usava JavaScript, ASP e JSP (Active Server Pages e JavaServer Pages), uma interface mais nova de Eclipse SWT (Standard Widget Toolkit) e uma interface de linha de comando. É claro que é impossível encontrar uma única ferramenta de automação que possa ser executada com relação a todas essas interfaces, mas deixemos isso de lado por enquanto.

Ao programar, estamos sempre concentrados em incentivar a reutilização para reduzir o volume de código a ser mantido. Com a programação orientada a objetos e a refatoração, são raros os motivos para deixar o mesmo código em mais de um lugar. No entanto, foi preciso criar uma arquitetura, para que eu pudesse pensar em como testar mais de uma interface a partir de uma única base de código de automação de teste. Embora todas as interfaces pertencessem ao mesmo aplicativo, em todas elas tinham as mesmas funcionalidades da mesma maneira. Mas havia muitos cenários focados no cliente (casos de uso) que tinham significado para serem testados em todas as interfaces.

No entanto, as equipes de teste responsáveis por projetar os casos e planos de teste não pensavam sobre o teste dessa maneira. Na verdade, estavam desconectados, divididos em silos de acordo com a interface em que trabalhavam. A equipe que desenvolveu e testou a CLI achava que precisavam apenas de alguns testes de cenário do cliente. Eles concentraram-se principalmente em testes de unidade e não consideraram um fluxo do cliente através da CLI. A equipe de teste responsável pela UI do Eclipse queria um grande número de recursos e funções da UI automatizados. Eles tinham uma longa lista de casos de teste para executar, completamente focados no fluxo do cliente, para atingir esse objetivo. Mas por que haveríamos de não querer essas informações, concluídas arduamente pelos especialistas para que fossem testadas todas as interfaces do aplicativo?

Uma abordagem hierárquica

As estruturas típicas de automação de teste que usam programação orientada a objetos (OOP) abstraem os detalhes da implementação do conjunto de controles em vez de a ação conceitual expressa pelos controles. Essa é, de fato, a abordagem que muitas ferramentas comerciais de automação de GUI usam. Por exemplo, todos os campos de texto tomam texto, definem uma classe textfield com um método setText(string) e usam isso em todas as versões do aplicativo. Mas isso não funciona em todos os casos quando estamos desenvolvendo automação de teste que funcione em várias interfaces. O que acontece quando uma GUI usa um botão de opções e outra, uma caixa de seleção? Não é possível confiar que as interfaces serão iguais para a mesma operação. Essa abordagem OOP tradicional é mostrada abaixo.

Figura 1. Hierarquia de controle de GUI
Hierarquia de controle de GUI

Em nosso caso, as interfaces variavam muito, mas as operações e processos de negócios representados eram basicamente os mesmos. Para maximizar a reutilização, decidimos usar uma hierarquia de lógica de negócios (veja a Figura 2) para permitir reutilização de cenários de teste entre as interfaces. Isso não apenas maximizou a reutilização do código, mas também significou deixar as ferramentas de teste gerenciarem as interfaces GUI, exatamente o que elas foram criadas para fazer. A Figura 2 mostra a abordagem. Você talvez reconheça o padrão de factory abstrato.

Figura 2. Hierarquia de lógica de negócios
Hierarquia de lógica de negócios

Ao adotar uma abordagem de lógica de negócios, cada fluxo pelo aplicativo pode ser expresso como o conjunto de operações que foram definidas como métodos nas classes abstratas. Embora cada interface possa ter algumas etapas diferentes dentro da operação, todas elas permitiram, entenderam e precisaram das mesmas operações. Isso significava desenvolver uma estrutura de teste específica para o aplicativo, que o representasse nas tarefas e negócios para fins de teste. A abordagem significava definir um conjunto de objetos, nos quais fossem contidos os dados e informações necessários para realizar operações dentro do aplicativo. Em seguida, precisamos definir um conjunto de métodos nesses objetos para descrever as operações e coletar dados adicionais necessários exclusivamente para a operação, como os que são definidos pelo fragmento de código na Figura 3.

Figura 3. Exemplo de código para classe abstrata
Exemplo de código para classe abstrata

Visualize o código da Figura 3 em forma de texto.

Query é uma classe abstrata que coleta os dados interessantes para criar e executar consultas, junto com operações interessantes, como executar, criar, editar e renomear. O método de renomeação requer o parâmetro adicional do novo nome, mas, quando tem sucesso, ele automaticamente atualiza o valor de nome do objeto de consulta. Não há suposições sobre a interface com o usuário com nesse nível. Os detalhes da interface são expressos apenas nas classes concretas específicas da interface. Para executar uma dada interface, é necessário instanciar uma classe concreta no tempo de execução para cada interface e chamar a operação, desta forma:

Query myQuery = (parent_location, findRecords); myQuery.rename(renamedQuery);

Estrutura baseada em aplicativo

Como consequência da definição de classes de lógica de negócios descrevendo as operações que deveriam ser testadas, era possível recombinar os métodos definidos em novos fluxos. Também era possível especificar no tempo de execução em qual interface executar. Essa é uma combinação eficiente, que realiza várias coisas:

  • As operações do aplicativo são definidas apenas uma vez
  • Os elementos de GUI são descobertos e manipulados apenas uma vez
  • Cenários de teste criados para uma interface podem ser executados em outra
  • A manutenção é reduzida drasticamente, porque a reutilização aumenta

O truque, obviamente, era criar o código para fazer qualquer operação dada em cada uma das interfaces a testar. Era um volume significativo de trabalho logo no início, mas, após uma interface ter sido concluída, havia muitos scripts de teste que poderiam ser usados para qualquer outra interface. Isto era tudo que precisava ser implementado em cada interface seguinte:

  • Incluir as etapas reais para executar a operação naquela interface
  • Complementar a estrutura para abordar qualquer funcionalidade que não exista nas outras interfaces

Outro benefício da abordagem é que, embora seja expressa como código, ela parece pseudocódigo de um nível alto o suficiente a ponto de poder ser entendida por SMEs que não são programadores. Isso permite que pessoas que não são programadores criem scripts automatizados, executem e entendam os scripts de testes entregues pela equipe de automação.

A Listagem 1 é um exemplo de código que interage com visualizações do Eclipse.

Listagem 1. Código que interage com visualizações do Eclipse
Perspective resource = new Perspective("Resource");
Perspective general = new Perspective("General");
app.start();
EclipseView bookmarks = new EclipseView("Bookmarks", resource);
EclipseView explorer = new EclipseView("Project Explorer",general);
resource.open();
resource.reset();
bookmarks.open();
explorer.open();
bookmarks.switchTo();
explorer.switchTo();
bookmarks.maximize();
bookmarks.restore();
bookmarks.minimize();
bookmarks.restore();
bookmarks.close();
resource.reset();
app.exit();

Essa abordagem foi adotada para reduzir os custos de manutenção e garantir que, para qualquer parte da GUI, houvesse apenas um lugar para fazer ajustes no código de automação de teste. Mas os benefícios dessa abordagem ficaram realmente claros após implementar as etapas concretas para fazer a lógica de negócios na CLI.

A equipe responsável por testar esse recurso tinha declarado o trabalho concluído, sem defeitos significativos. A automação foi implementada para garantir um conjunto de regressão para releases futuros. Mas, quando executamos os scripts de teste criados para testar uma GUI nas implementações de CLI, encontramos mais de 50 defeitos! E eram defeitos importantes, que certamente seriam encontrados por nossos clientes.

Como testadores, sempre ficamos animados ao encontrar os defeitos primeiro, devido à óbvia economia gerada ao encontrar problemas antecipadamente. Além disso, é empolgante criar automação que faz mais do que validar a estabilidade do produto. Também é importante não esquecer os benefícios de negócios em termos de reputação, satisfação do cliente e nas melhorias de qualidade gerais entregues através dessa abordagem de automação de teste.


Teste em diversos canais hoje

Durante os projetos descritos acima, pudemos escolher apenas uma única interface no tempo de execução. Um script de teste tinha que ser completamente automatizado e precisava implementar um conjunto completo de operações de lógica de negócios para cada interface a ser testada. Essa abordagem era razoável e aceitável no momento, pois um usuário final geralmente não alterna entre um cliente desktop e um cliente da web durante um conjunto de operações.

Mas as coisas mudaram. Não é irracional pensar em um cenário de teste que possa começar no cliente da web, passar para um app remoto e voltar para a web, talvez com uma verificação independente com relação ao backend do banco de dados.

Imagine um cenário em que alguém está dando lances no eBay. É mais fácil procurar e pesquisar um item usando um desktop e um navegador (cliente da web). Após escolher um item, o usuário dá o lance. Ele pode sair do computador e receber uma notificação no celular de que alguém de um lance melhor, então o usuário atualiza o lance no celular. Ao ganhar o leilão, o usuário volta ao computador, para inserir informações de pagamento no navegador.

Nesse cenário de teste, em vez de validar o sucesso da transação a partir de uma parte da interface na tela (usando screen scraping ou propriedades de objeto), seria melhor usar o banco de dados e verificar o registro diretamente. Essa verificação independente da interface é mais robusta e mais estável. Podemos chamar essa abordagem de cenário de teste "híbrido". E teoricamente cenários híbridos deveriam permitir a mistura com execução de teste manual para melhorar a cobertura de teste quando algumas áreas de produtos são muito difíceis ou caras para automatizar.

Então eu comecei a imaginar como implementar um fluxo como esse juntando diferentes interfaces e implementações de operação em um fluxo completo, que se move de forma integrada entre interfaces. É certo que há desafios, e eles podem provar-se insuperáveis. Era relativamente simples saber quais dados deviam ser movidos entre operações quando o ambiente de tempo de execução era restrito. Pode não estar claro de imediato quais dados precisam ser transferidos entre aplicativos quando eles também precisam cruzar interfaces. Usando o exemplo acima, seria necessário um login no cliente da web e no celular. A autenticação é um problema óbvio, mas certamente haverá muitas complicações na implementação desses cenários de teste híbridos.

Mas não tem problema, esse é só o Everest. Vamos lá! Diga o que você pensa ou compartilhe suas ideias, fazendo parte da discussão na IBM Rational Functional Tester Network no LinkedIn ou enviando um comentário para este artigo.

Recursos

Aprender

Obter produtos e tecnologias

  • Faça download de uma versão gratuita de avaliação do software Rational.
  • Avalie outros softwares IBM da forma que melhor lhe convier: faça o download da versão de avaliação, experimente-a on-line, use-a em um ambiente de nuvem ou passe algumas horas no SOA Sandbox para saber como implementar arquitetura orientada a serviço de maneira eficiente.

Discutir

Comentários

developerWorks: Conecte-se

Los campos obligatorios están marcados con un asterisco (*).


Precisa de um ID IBM?
Esqueceu seu ID IBM?


Esqueceu sua senha?
Alterar sua senha

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

 


A primeira vez que você entrar no developerWorks, um perfil é criado para você. Informações no seu perfil (seu nome, país / região, e nome da empresa) é apresentado ao público e vai acompanhar qualquer conteúdo que você postar, a menos que você opte por esconder o nome da empresa. Você pode atualizar sua conta IBM a qualquer momento.

Todas as informações enviadas são seguras.

Elija su nombre para mostrar



Ao se conectar ao developerWorks pela primeira vez, é criado um perfil para você e é necessário selecionar um nome de exibição. O nome de exibição acompanhará o conteúdo que você postar no developerWorks.

Escolha um nome de exibição de 3 - 31 caracteres. Seu nome de exibição deve ser exclusivo na comunidade do developerWorks e não deve ser o seu endereço de email por motivo de privacidade.

Los campos obligatorios están marcados con un asterisco (*).

(Escolha um nome de exibição de 3 - 31 caracteres.)

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

 


Todas as informações enviadas são seguras.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=80
Zone=Rational
ArticleID=839267
ArticleTitle=Enfrentando o desafio do teste em diversos canais
publish-date=10082012