Hoje eu, o Toni Isidoro e Bruno Abreu vamos falar sobre uma alternativa muito interessante ao Page Objects: o Screenplay Pattern.

Se você é do mundo de testes automatizados, com certeza já ouviu falar no padrão Page Objects. Este padrão surgiu quando o Selenium se popularizou e passou a ser muito utilizado, principalmente por desenvolvedores inexperientes que criavam scripts de teste sem nenhum padrão e/ou organização do código.

Como consequência, testes instáveis (flaky tests) começaram a aparecer e jogaram a culpa no Selenium dizendo que o framework era instável. Foi aí que Simon Stewart, principal committer do Selenium, publicou um artigo dizendo que a culpa não era da ferramenta, e sim do mal uso da mesma através da falta de utilização de padrões de código para o desenvolvimento dos testes.

Simon então propôs na wiki do próprio Selenium a utilização do padrão Page Objects, aplicando os princípios de orientação a objetos para ter uma melhor separação de responsabilidades e melhor organização do código de teste.

Explicando resumidamente, para cada página (ou componentes de páginas) é criado uma classe separada onde é mapeado os localizadores (ou seletores) de elementos de página e os métodos de ações a serem executadas na página.

Na figura acima, em um script de teste sem aplicação do padrão do Page Objects (“Non POM Structure”), o mapeamento dos elementos da página e métodos de ações que interagem com estes elementos ficam na mesma classe do método de teste.

Já no padrão de Page Objects (“POM Based Structure”), para cada página é criada uma nova classe, havendo assim a separação entre os métodos de teste e os métodos que interagem com os elementos da página. Isso facilita a manutenção do código, pois caso algo seja alterado na página só é preciso alterar somente a classe que representa aquela página e não os vários métodos que interagem com a mesma.

Algumas limitações do Page Objects

De uma forma geral, o Page Objects é um bom padrão que, como vimos anteriormente, tem suas vantagens. No entanto, é um padrão que exige constante refatoração do código e aplicação de boas práticas de desenvolvimento para que o mesmo não fique difícil de manter e ser compreendido.

Porém, uma grande limitação que o padrão apresenta é que há somente uma primeira camada de abstração. Essa limitação se agrava quando pensamos em projetos de testes grandes e complexos nos quais precisamos ter uma suíte de testes manutenível, escalável e robusta, que é o desafio que lidamos com muita frequência em nossos projetos na Sofist.

Você também já deve ter tentado aplicar o padrão do Page Objects para a automatização de testes de API e viu que o pattern não é direcionado para este propósito, dificultando assim o desenvolvimento dos testes de API e Frontend seguindo o mesmo padrão de desenvolvimento e também dificultando o aproveitamento de código entre ambos.

Uma situação muito comum também que a maioria já enfrentou na utilização do Page Objects é o problema de classes extremamente grandes, dado que o pattern nos leva a modelar os testes de acordo com como a página é atualmente, e não modelar o problema em si, ou a jornada do usuário na aplicação. Consequentemente, acabamos criando código difícil de manter e de escalar.

Uma classe extremamente grande é um indicador de que outros bons princípios de programação também não estão sendo seguidos. Por exemplo, uma classe muito grande provavelmente tem muitas responsabilidades, o que acaba violando o Princípio do SOLID da Responsabilidade Única, tornando mais difícil entender onde mudanças são necessárias no código quando há a necessidade de manutenção ou implementação de novos testes.

Também é mais provável que classes grandes contenham duplicação, o que pode resultar em um bug sendo corrigido em um local, mas recorrente em outro local.

Por exemplo, veja a classe listada abaixo. Colocamos ela de um forma que reforça seu tamanho, que totaliza 245 linhas. Seria fácil e rápido para você ler todo o conteúdo e entender? (clique na imagem para abrir todo o código).

Ao modelar os testes através da visão de como a página está atualmente, quem está automatizando os testes pode esquecer o comportamento esperado da aplicação e focar muito no comportamento atual, o que pode gerar falsas expectativas e a não detecção de problemas com páginas que foram desenvolvidas através da interpretação errada das regras de negócio.

Aí então, assim como nós aqui na Sofist, você deve ter se questionado… será que existe alguma outra forma de aplicar boas práticas de código em um projeto de testes que não seja utilizando o Page Objects, e que resolva essas limitações tão comuns do padrão?

A resposta é… SIM, existe! O nome dele é Screenplay Pattern.

The Screenplay Pattern: uma solução para escalar seus testes automatizados

O Screenplay Pattern (anteriormente conhecido como The Journey Pattern) é uma elegante e poderosa abordagem de design e implementação dos testes, que provê um número imenso de melhorias sobre as abordagens tradicionais de desenvolvimento de testes de GUI como, por exemplo, o Page Objects. Ele existe desde 2007 e surgiu de forma totalmente independente ao Page Objects, porém, também é conhecido como “Refactored Page Objects”, sugerindo que ele é uma evolução ao padrão já existente e conhecido por todos.

Ao contrário do que muitos pensam e o nome do padrão sugere, o Screenplay não é um padrão que somente é aplicável a testes de interface gráfica: podemos aplicar o screenplay em testes de API também. O nome do padrão “Screenplay” refere-se a um roteiro, como se fosse o script de um filme ou novela onde os atores têm papéis e tarefas definidas no script.

Estamos falando de um padrão de desenvolvimento de testes automatizados centrados no usuário (user centered), uma vez que ele força a reflexão sobre quem são os usuários do seu sistema, o que eles querem atingir interagindo com o sistema, e como eles vão fazer isso.

Como qualquer outro padrão de desenvolvimento o Screenplay Pattern requer disciplina para começar a utilizá-lo, e a curva de aprendizagem no início pode ser um pouco alta. No entanto, os benefícios tornam-se aparentes rapidamente quando a suite de testes é escalada e o conjunto de componentes reutilizáveis criados ajudam a acelerar o processo de escrita de testes a uma taxa sustentável, reduzindo o atrito geralmente associado à manutenção contínua de conjuntos de testes automatizados.

A proposta por trás do Screenplay Pattern

O Screenplay aplica os princípios de design do SOLID para desenvolvimento de testes automatizados, o que facilita muito a manutenção e entendimento do código dos testes devido a boas práticas aplicadas durante o desenvolvimento do mesmo.

O SOLID é um acrônimo criado por Michael Feathers e Robert Martin (o famoso Uncle Bob) que encapsula 5 boas práticas de programação orientada a objetos:

  • Single Responsibility Principle (Principio da Responsabilidade Única)
  • Open Closed Principle (Princípio do Aberto/Fechado)
  • Liskov Substitution Principle (Princípio da Substituição de Liskov)
  • Interface Segregation Principle (Princípio da Segregação de Interfaces)
  • Dependency Inversion Principle (Princípio da Inversão de Dependências)

Os princípios que mais têm impacto na refatoração do padrão Page Objects são o Princípio da Responsabilidade Única (Single Responsibility Principle) e o Princípio do Aberto/Fechado (Open Closed Principle).

O Princípio da Responsabilidade Única (SRP) afirma que uma classe deve ter somente uma responsabilidade e, portanto, somente uma única razão para mudar. Isso reduz o risco de afetar outros comportamentos não relacionados quando fazemos as alterações necessárias.

Já o Princípio do Aberto/Fechado (OCP) afirma que uma classe deve ser aberta para extensão, mas fechada para modificação. Isso significa que deve ser possível estender o comportamento escrevendo uma nova classe sem precisar alterar um código existente que está funcionando. Iremos detalhar estes dois princípios, com exemplos de código, em um próximo artigo.

Quando pensamos em desenvolvimento de uma aplicação olhando para o negócio, temos um match ideal com o Screenplay, pois ele encoraja que validar os comportamentos deve ser a principal preocupação dos testes, e a implementação deve ser a preocupação secundária.

Isso se torna ainda mais importante se você estiver aplicando BDD e escrevendo testes de aceitação onde as habilidades do usuário para atingir determinado objetivo são mais relevantes do que uma eventual solução. Por essas razões, o Screenplay propõe algumas perspectivas diferentes, como por exemplo:

  • Who (Quem)  – Para quem é isso? Que papel eles desempenham?
  • Why (Por que) – Por que eles estão aqui e que resultado eles esperam? Qual é o objetivo deles?
  • What (O que) – O que eles precisam fazer para alcançar seu objetivo? Quais tarefas eles precisam executar?
  • How (Como) – Como eles completarão cada tarefa? Como serão as suas interações específicas com o sistema?

O Screenplay Pattern em uma figura

Como já comentado anteriormente, o Screenplay foca em fazer com que os testes sejam expressados do ponto de vista do usuário, ou seja, ele foca “no quê” e não “no como”.

O padrão prevê a existência de atores (Actors) que possuem habilidades (Abilities), como por exemplo “navegar na internet utilizando um browser”, e esses atores executam tarefas (Tasks) focadas no negócio para atingir seus objetivos na aplicação, como por exemplo “realizar uma pesquisa por uma frase específica”.

As tarefas são compostas por ações ou interações (Actions or Interactions), como por exemplo “digitar um termo no campo de busca”. Os atores também podem fazer perguntas (Questions) sobre o estado da aplicação, como por exemplo validar o estado de um resultado na tela.

O diagrama a seguir exemplifica bem como o padrão trabalha para permitir que os testes robustos sejam criados em escala, orientados totalmente ao negócio, e com maior facilidade de manutenção.

Diagrama sobre Screenplay Pattern
Podemos te dizer por experiência própria que se você começar a automatizar seus testes tomando como base esse diagrama você mudará a forma como você analisa o domínio do problema que irá resolver e como você irá modelar seus testes.

Esse tipo de pensamento vai te afastar do pensamento de “pages”, que é bem comum no Page Objects. Sabendo que no Screenplay nós temos atores com habilidades específicas para realizar determinadas ações (dado o seu papel), cada cenário de teste acaba então por se tornar uma narrativa descrevendo as tarefas e como se espera que a estória seja concluída para um ator específico.

Essa perspectiva, combinada com os princípios de design da orientação a objetos, é o que nos distancia do Page Objects como padrão selecionado para uso em projetos complexos. Já aplicamos o Screenplay há anos, e podemos dizer que nós e nossos clientes estão plenamente satisfeitos.

Para finalizar, colocamos abaixo um exemplo de implementação de alguns passos de um cenário de login usando o Screenplay Pattern em Java. Observe como o código fica fácil de ler e entender.

Achou interessante? Deixe um comentário para nós! 🙂 Em próximos textos, iremos entrar em mais detalhes da aplicação desse padrão nos testes automatizados. Fique ligado!