A arte do teste de layout com Galen Framework
Publicados: 2022-03-10Ao projetar uma interface gráfica de usuário, sempre há uma pergunta em aberto: como automatizamos os testes para isso? E como podemos garantir que o layout do site permaneça responsivo e seja exibido corretamente em todos os tipos de dispositivos com várias resoluções? Acrescente a isso as complicações decorrentes de conteúdo dinâmico, requisitos de internacionalização e localização, e isso se torna um verdadeiro desafio.
Neste artigo, vou guiá-lo através de uma nova e interessante técnica de teste de layout. Usando o Galen Framework, fornecerei um tutorial detalhado para escrever testes de layout generalizados significativos, que podem ser executados em qualquer navegador e em qualquer dispositivo e ao mesmo tempo usados como uma única fonte de verdade em sua documentação de design.
Leitura adicional no SmashingMag:
- Desenvolvimento orientado a testes visuais para design de interface responsivo
- Noções básicas de automação de teste para aplicativos, jogos e a Web móvel
- Diversas estruturas de automação de teste para aplicativos nativos de reação
Também demonstrarei como criei um teste otimizado para uma página de mensagens em nosso site de classificados, Marktplaats. Aprenderemos como estender a sintaxe do Galen com nossa própria linguagem, como melhorar o código de teste e como transformar uma rotina de teste de layout em arte.
Introdução ao quadro de Galen
Galen Framework foi abordado há um ano em “Desenvolvimento Orientado a Testes Visuais para Design de Interface Responsivo”. Na época, sua sintaxe era limitada. Ele melhorou muito desde então e ganhou muitos novos recursos, que veremos aqui.
Caso você não esteja familiarizado com o Galen Framework, ele é uma ferramenta para testes de layout responsivo e cross-browser e testes funcionais, com sua própria linguagem de teste, chamada Galen Specs. Ele é baseado no Selenium WebDriver e também possui uma rica API JavaScript que permite trabalhar diretamente com o WebDriver. Como você tem controle sobre o WebDriver, você pode executar testes em qualquer navegador, na nuvem (SauceLabs, BrowserStack, PerfectoMobile, etc.) ou em dispositivos móveis reais usando Appium.
Instalando e Executando
Configurar o Galen Framework é fácil. Basta executar o seguinte comando para instalá-lo via npm:
npm install -g galenframework-cli
Se você não usa o npm, basta baixar o arquivo mais recente do Galen Framework, extrair o pacote e seguir as instruções de instalação.
Uma vez instalado, Galen Framework pode ser iniciado de várias maneiras. Por exemplo, você pode usar o comando check
para iniciar um teste rápido de uma única página. Para este comando, você precisa fornecer um arquivo .gspec
com suas validações de layout e, em seguida, pode invocá-lo assim:
galen check loginPage.gspec --url https://example.com --size 1024x768 --include desktop --htmlreport reports
Este comando iniciará um navegador, abrirá a URL especificada, redimensionará a janela do navegador para 1024 × 768 pixels e executará todas as validações declaradas no arquivo loginPage.gspec
. Como resultado, você obterá um relatório HTML detalhado.
Gerenciando suítes de teste
No mundo real, um aplicativo da Web real não consiste apenas em páginas estáticas. Muitas vezes você terá que realizar algumas ações para chegar ao local que deseja verificar. Nesse caso, Galen oferece suítes de teste JavaScript e a API JavaScript GalenPages para implementar o modelo de objeto de página. Aqui está um exemplo simples de um teste JavaScript Galen:
test("Home page", function() { var driver = createDriver("https://galenframework.com", "1024x768"); checkLayout(driver, "homePage.gspec", ["desktop"]); });
E aqui está uma implementação do modelo de objeto de página para uma página de login, tirada de um projeto real.
WelcomePage = $page("Welcome page", { loginButton: "#welcome-page .button-login" }); LoginPage = $page("Login page", { username: "input[name='login.username']", password: "input[name='login.password']", loginButton: "button.button-login" loginAs: loggedFunction ("Log in as ${_1.username} with password ${_1.password}", function(user) { this.username.typeText(user.username); this.password.typeText(user.password); this.loginButton.click(); }) }); test("Login page", function() { var driver = createDriver("https://testapp.galenframework.com", "1024x768"); var welcomePage = new WelcomePage(driver).waitForIt(); welcomePage.loginButton.click(); new LoginPage(driver).waitForIt(); checkLayout(driver, "loginPage.gspec", ["desktop"]); });
Para uso avançado, aconselho você a olhar para o projeto Galen Bootstrap. É uma extensão JavaScript construída especificamente para Galen. Ele fornece algumas funcionalidades extras para testes de interface do usuário e uma maneira mais fácil de configurar navegadores e executar conjuntos de testes complexos.
Teste de layout simples
Deixe-me começar apresentando um teste de layout simples no Galen Framework. Em seguida, passarei para casos de uso avançados e demonstrarei como estender a sintaxe Galen Specs. Para isso, veremos um cabeçalho com um ícone e uma legenda:

No código HTML, pode ser algo assim:
<body> <!-- … --> <div> <img class="header-logo" src="/imgs/header-logo.png"/> <h1>My Blog</h1> </div> <!-- … --> </body>
A forma mais simples de um teste de layout Galen seria algo como o seguinte. Primeiro, temos que declarar objetos com seletores CSS.
@objects header #header icon #header img caption #header h1
Em seguida, declaramos uma seção de teste com um nome significativo e colocamos todas as nossas validações abaixo dela.
= Icon and Caption = icon: left-of caption 10 to 15px width 32px height 32px inside header 10px top caption: aligned horizontally all header inside header
Aqui testamos dois elementos de cabeçalho: o ícone e a legenda. Todas as validações listadas nos elementos ícone e legenda são, na verdade, especificações padrão do Galen. Essas especificações são os blocos de construção fundamentais com os quais você pode montar sua própria solução de teste de layout. Cada especificação verifica uma única propriedade (como largura, altura, texto), posicionamento relativo (como dentro, à esquerda de, acima) ou pixels na captura de tela (como esquema de cores, imagem).
Testando vários elementos usando loops forEach
O exemplo anterior demonstra um cenário simples. Vamos ver como podemos lidar com uma situação mais complicada: um menu horizontal. Primeiro, vamos tentar uma técnica de teste de layout simples.

Comece combinando vários elementos na página. Com o código a seguir, estamos dizendo a Galen para procurar elementos que correspondam ao seletor CSS #menu ul li
.
@objects menu #menu item-* ul li
Mais tarde, podemos nos referir a esses itens com nomes como menu.item-1
e menu.item-2
e iterar sobre todos os itens de menu usando um loop @forEach
.
= Menu = menu.item-1: inside menu 0px top left bottom @forEach [menu.item-*] as menuItem, next as nextItem ${menuItem}: left-of ${nextItem} 0px aligned horizontally all ${nextItem}
Como você pode ver, mesmo que a verificação real não seja tão complexa, o código já se tornou menos intuitivo. Imagine se tivéssemos mais código semelhante em nossos testes. Em algum momento, isso se tornaria uma bagunça insustentável. Deve haver uma maneira de melhorá-lo.
Repensando o teste de layout
Se você pensar no exemplo anterior, parece que poderíamos expressar o layout em apenas uma ou duas frases. Por exemplo, poderíamos dizer algo como: “Todos os itens do menu devem ser alinhados horizontalmente, sem margem entre eles. O primeiro item do menu deve estar localizado no lado esquerdo do menu, sem margem.” Como formulamos frases para explicar o layout que queremos, por que não podemos simplesmente usá-las em nosso código? Imagine se pudéssemos escrever o código assim:
= Menu = |first menu.item-* is in top left corner of menu |menu.item-* are aligned horizontally next to each other
Na verdade, esse é um código de trabalho real, copiado do meu projeto. Nessas duas últimas linhas (começando com o pipe, |
), estamos invocando funções personalizadas que coletam seus argumentos analisando essas duas instruções. Obviamente, o exemplo acima não funcionará como está. Para compilar, precisamos implementar os manipuladores para essas duas instruções. Voltaremos a esta implementação mais tarde.
O ponto chave com o exemplo acima é que o teste de layout mudou de testes orientados a objetos para testes orientados a expressões . Pode não ser óbvio a partir de um exemplo tão pequeno, mas é definitivamente perceptível em uma escala maior. Então, por que isso é significativo? A resposta curta é que isso muda nossa mentalidade e afeta a maneira como projetamos nosso software e escrevemos testes para ele.
Usando essa técnica, não tratamos nossa página como um monte de objetos com relacionamentos específicos entre eles. Não testamos as propriedades CSS de elementos individuais. E evitamos escrever códigos complicados e não triviais. Em vez disso, estamos tentando pensar em padrões de layout comuns e declarações significativas. Em vez de testar o item de menu 1, o item de menu 2 e assim por diante separadamente, aplicamos declarações genéricas que:
- são reproduzíveis em outros elementos;
- não contém valores de pixel codificados;
- são aplicadas a abstrações e não a objetos concretos;
- e, por último, mas não menos importante, realmente fazem sentido quando os lemos.
Como funciona
Deixe-me explicar o mecanismo de expressões de layout personalizado usando este exemplo simples:

Neste exemplo, devemos verificar se o botão se estende até o painel, sem margem no lado esquerdo ou direito. Sem regras personalizadas, podemos abordá-lo de diferentes maneiras, mas prefiro a seguinte solução:
button: inside some_panel 0px left right
O código acima nos dá a flexibilidade de declarar margem personalizada nas laterais e também testa implicitamente se o botão está contido completamente dentro do painel. A desvantagem é que não é muito legível, e é por isso que vou colocar essa validação atrás do button stretches to some_panel
. Para que isso funcione, precisamos escrever uma regra personalizada como esta:
@rule %{elementName} stretches to %{parentName} ${elementName}: inside ${parentName} 0px left right
É isso. Agora podemos colocá-lo em nosso teste em apenas uma linha:
| button stretches to some_panel
Como você pode ver, essa regra recebe dois argumentos: elementName
e parentName
. Isso nos permite aplicá-lo a outros elementos também. Basta substituir os nomes desses dois objetos.
| login_panel stretches to main_container | header stretches to screen | footer stretches to screen # etc.
Implementando sua própria linguagem de teste
Vamos voltar aos exemplos iniciais de expressões de layout para o menu horizontal.
= Menu = | first menu.item-* is in top left corner of menu | menu.item-* are aligned horizontally next to each other
Podemos implementar a primeira regra da seguinte maneira:
@rule first %{itemPattern} is in %{cornerSides} corner of %{parentElement} @if ${count(itemPattern) > 0} ${first(itemPattern).name}: inside ${parentElement} 0px ${cornerSides}
Quando usado em nosso exemplo, ele analisaria os argumentos da seguinte forma:
-
itemPattern
=menu.item-*
-
cornerSides
=top left
-
parentElement
=menu
Como terminamos nossa primeira expressão, podemos passar para a próxima. Na segunda expressão, devemos testar o alinhamento horizontal de todos os itens do menu. Proponho três passos simples:
- Encontre todos os itens do menu.
- Iterar sobre todos eles até o penúltimo elemento.
- Verifique se o elemento
n
está localizado à esquerda do elementon+1
e se as bordas superior e inferior estão alinhadas.
Para fazê-lo funcionar, precisamos pegar um loop @forEach
e as especificações left-of
e aligned
. Felizmente, em Galen você pode consultar o item anterior ou seguinte em um loop. Caso você tenha declarado uma referência ao próximo elemento, ele irá iterar apenas até o penúltimo elemento, que é exatamente o que precisamos.
@rule %{itemPattern} are aligned horizontally next to each other @forEach [${itemPattern}] as item, next as nextItem ${item}: left-of ${nextItem} 0px aligned horizontally all ${nextItem}
Você pode perguntar: E se tivermos que especificar uma margem em nosso teste (como ~ 20px
ou 10 to 20px
)? Então, sugiro implementar uma regra separada ou estender a existente para suportar um argumento %{margin}
.
@rule %{itemPattern} are aligned horizontally next to each other with %{margin} margin @forEach [${itemPattern}] as item, next as nextItem ${item}: left-of ${nextItem} ${margin} aligned horizontally all ${nextItem}
É isso! Criamos uma expressão genérica que nos ajuda a validar o menu horizontal. No entanto, devido à sua flexibilidade, podemos fazer muito mais do que isso. Podemos usá-lo para testar quaisquer outros elementos na página. Podemos até usá-lo para testar o alinhamento de dois botões:

| menu.item-* are aligned horizontally next to each other with 0px margin | submit_button, cancel_button are aligned horizontally next to each other with 20px margin
Você pode notar nesses dois exemplos que declaramos o primeiro argumento de duas maneiras diferentes. Na primeira expressão, o primeiro argumento é “menu.item-*”
e na segunda expressão é declarado como “submit_button, cancel_button”
. Isso é possível porque o loop @forEach
nos permite usar uma lista de objetos separados por vírgula junto com o operador estrela. Mas ainda não terminamos com a refatoração. Poderíamos melhorar ainda mais o código e torná-lo mais legível. Se criarmos grupos para os itens de menu e os botões do formulário de login, poderíamos fazer algo assim:

@groups menu_items menu_item-* login_form_buttons submit_button, cancel_button = Testing login page = | &menu_items are aligned horizontally next to each other with 0px margin | &login_form_buttons are aligned horizontally next to each other with 20px margin
Neste caso, temos que usar o símbolo &
, que significa uma declaração de grupo. Isso já é um bom teste. Primeiro, ele simplesmente funciona e podemos testar o que precisamos. Além disso, o código é claro e legível. Se outra pessoa perguntar como deve ser a página de login e quais são os requisitos de design, você pode dizer a ela para examinar o teste.
Como você pode ver, implementar expressões personalizadas para padrões de layout complexos não é realmente um grande problema. Pode ser desafiador no começo, mas ainda se assemelha a uma atividade criativa.
Margens dinâmicas
Vejamos outro padrão de layout raro que você pode encontrar às vezes em vários sites. E se quiséssemos testar se os elementos têm uma distância igual entre si? Vamos tentar implementar outra regra para isso, mas desta vez usando uma implementação JavaScript. Proponho tal afirmação: “box_item-* are aligned horizontally next to each other with equal distance”
. Isso vai ser um pouco complicado porque não sabemos a margem entre os elementos e não podemos apenas codificar valores de pixel. Portanto, a primeira coisa que temos a fazer é recuperar a margem real entre o primeiro e o último elemento.

Assim que obtivermos essa margem, podemos declará-la em um loop @forEach
semelhante a como fizemos antes. Proponho implementar essa regra usando a API JavaScript porque a lógica necessária é um pouco mais complexa do que em todos os nossos exemplos anteriores. Vamos criar um arquivo chamado my-rules.js
e digite este código:
rule("%{objectPattern} are aligned horizontally next to each other with equal margin", function (objectName, parameters) { var allItems = findAll(parameters.objectPattern), distance = Math.round(Math.abs(allItems[1].left() - allItems[0].right())), expectedMargin = (distance - 1) + " to " + (distance + 1) + "px"; if (allItems.length > 0) { for (var i = 0; i < allItems.length - 1; i += 1) { var nextElementName = allItems[i + 1].name; this.addObjectSpecs(allItems[i].name, [ "aligned horizontally all " + nextElementName, "left-of " + nextElementName + " " + expectedMargin ]); } } });
Em nosso código de teste, usaremos assim:
@script my-rules.js # … = Boxes = | box_item-* are aligned horizontally next to each other with equal distance
Como você pode ver, no Galen Framework podemos escolher entre duas linguagens ao implementar as regras: Galen Specs e JavaScript. Para expressões simples, Galen Specs é mais fácil de usar, mas para expressões complexas sempre escolho JavaScript. Se você quiser saber mais sobre as regras de JavaScript, consulte a documentação.
Extras de Galeno
Tendo brincado bastante com vários padrões de layout, percebi que todas essas regras de Galen poderiam ser facilmente aplicadas em qualquer outro projeto de teste. Isso me deu uma ideia de compilar as expressões de layout mais comuns em sua própria biblioteca. Foi assim que criei o projeto Galen Extras. Abaixo estão alguns exemplos do que esta biblioteca é capaz de:
| header.icon should be squared | amount of &menu_items should be > 3 | &menu_items are aligned horizontally next to each other | &list_items are aligned vertically above each other with equal distance | every &menu_item is inside menu 0px top and has width > 50px | first &menu_item is inside menu 0px top left | &menu_items are rendered in 2 column table | &menu_items are rendered in 2 column table, with 0 to 1px vertical and 10px horizontal margin | &login_form_elements sides are vertically inside content_container with 20px margin login_panel: | located on the left side of panel and takes 70 % of its width # etc …
A biblioteca Galen Extras contém muitos dos padrões de layout que você normalmente encontra em sites, e eu continuo atualizando assim que descubro um padrão útil. Uma vez que esta biblioteca foi configurada, decidi experimentá-la em um projeto de teste real.
Testando o aplicativo de mensagens
Atualmente, trabalho como engenheiro de software na Marktplaats. Em algum momento, decidi aplicar toda a experiência que ganhei em um projeto real. Eu precisava testar a página de mensagens em nosso site. Aqui está o que parece:

Para ser honesto, implementar testes para essas páginas sempre me pareceu um pouco assustador, especialmente testes de layout. Mas com a biblioteca Galen Extras instalada, tudo correu bem, e logo consegui criar este código:
@import ../selected-conversation.gspec @groups (message, messages) messenger.message-* first_two_messages messenger.message-1,messenger.message-2 first_message messenger.message-1 second_message messenger.message-2 third_message messenger.message-3 (message_date_label, message_date_labels) messenger.date_label-* first_date_label messenger.date_label-1 second_date_label messenger.date_label-2 = Messages panel = = Messages and Date labels = |amount of visible &message_date_labels should be 1 |first &message_date_label has text is "17 november 2015" |amount of visible &messages should be 3 |&first_two_messages should be located at the left inside messenger with ~ 20px margin |&third_message should be located at the right inside messenger with ~ 20px margin |&messages are placed above each other with 10 to 15px margin |text of all &messages should be ["Hi there!", "I want to buy something", "Hello! Sure, it's gonna be 100 euros"] = Styling = |&first_two_messages should be styled as others message |&third_message should be styled as own message
Extraindo intervalos de pixels
O teste parecia bom: era compacto e legível, mas ainda longe de ser perfeito. Eu realmente não gostei de todas essas definições de margem ( ~ 20px
, 10 to 15px
). Alguns deles foram repetidos, e era difícil entender o que cada um deles representava. É por isso que decidi esconder cada margem atrás de uma variável significativa.
# ... @set messages_side_margin ~ 20px messages_vertical_margin 10 to 15px = Messages panel = = Messages and Date labels = |amount of visible &message_date_labels should be 1 |first &message_date_label has text is "17 november 2015" |amount of visible &messages should be 3 |&first_two_messages should be located at the left inside messenger with ${messages_side_margin} margin |&third_message should be located at the right inside messenger with ${messages_side_margin} margin |&messages are placed above each other with ${messages_vertical_margin} margin # ...
Como você pode ver, movi as margens para messages_vertical_margin
e messages_side_margin
. Também declarei uma margem minimal
, que é um intervalo entre 0 e 1 pixel.
# ... @set minimal 0 to 1px = Conversations Panel = | &conversations are aligned above each other with ${minimal} margin # ...
Validação baseada em imagem e expressões personalizadas
Tendo coberto o posicionamento de todos os elementos principais na página, decidi também testar o estilo. Eu queria validar que cada mensagem tem uma cor de fundo específica para a função do usuário. Quando os usuários estiverem logados, as mensagens terão um fundo azul claro. As mensagens para outros usuários teriam um fundo branco. Caso uma mensagem não tenha sido enviada, o alerta de erro teria um fundo rosa. Aqui está a regra que me ajudou a validar esses estilos:
@set OWN_MESSAGE_COLOR #E1E8F5 OTHERS_MESSAGE_COLOR white ERROR_MESSAGE_COLOR #FFE6E6 @rule %{item} should be styled as %{style} message ${item}: @if ${style === "own"} color-scheme > 60% ${OWN_MESSAGE_COLOR}, 0.2 to 20 % ${MAJOR_TEXT_MESSAGE_COLOR} @elseif ${style === "error"} color-scheme > 60% ${ERROR_MESSAGE_COLOR}, 0.2 to 20 % ${MAJOR_TEXT_MESSAGE_COLOR} @else color-scheme > 60% ${OTHERS_MESSAGE_COLOR}, 0.2 to 20 % ${MAJOR_TEXT_MESSAGE_COLOR}
A especificação do color-scheme
de cores verifica a distribuição proporcional de cores dentro de um elemento. Ele corta uma captura de tela da página e analisa a distribuição de cores. Assim, para verificar a cor de fundo de um elemento, basta verificar se sua distribuição é maior que 60% do intervalo total de cores. No teste, esta regra é invocada assim:
= Styling = |&first_two_messages should be styled as others message |&third_message should be styled as own message
Configurando suítes de teste
O aplicativo de mensagens é um aplicativo dinâmico que funciona em conjunto com a API RESTful Messaging. Portanto, para testar seus layouts em todos os estados diferentes, precisamos preparar os dados de teste. Decidi simular a API de mensagens para poder configurar todas as minhas mensagens de teste no conjunto de testes. Aqui está um fragmento do meu conjunto de testes que mostra como nossos testes são estruturados.
// ... testOnAllDevices("Unselected 2 conversations", "/", function (driver, device) { mock.onGetMyConversationsReturn(sampleConversations); refresh(driver); new MessageAppPage(driver).waitForIt(); checkLayout(driver, "specs/tests/unselected-conversations.gspec", device.tags); }); testOnAllDevices("When clicking a conversation it should reveal messages", "/", function (driver, device) { mock.onGetMyConversationsReturn(sampleConversations); mock.onGetSingleConversationReturn(sampleMessages); refresh(driver); var page = new MessageAppPage(driver).waitForIt(); page.clickFirstConversation(); checkLayout({ driver: driver, spec: "specs/tests/three-simple-messages-test.gspec", tags: device.tags, vars: { expectedTextProvider: textProvider({ "messenger.message-1": "Hi there!\n11:02", "messenger.message-2": "I want to buy something\n12:02", "messenger.message-3": "Hello! Sure, it's gonna be 100 euros\n13:02" }) } }); }); // ...
Pegando Bugs
A implementação dessas expressões simples compensa rapidamente. Vamos ver que tipo de bugs podemos detectar com nosso conjunto de testes.
Problema de estilo
Aqui está um exemplo de quando algo dá errado em nossa base de código CSS e, como resultado, todas as mensagens são renderizadas com o mesmo plano de fundo.

Se você comparar esta captura de tela com a original, notará que a última mensagem tem um fundo branco, enquanto deveria ser azul claro. Vamos ver como Galen relata esse problema:

Para o objeto destacado, ele exibe a color #e1e8f5 on “messenger.message-3” is 0% but it should be greater than 60%
. Para ser honesto, essa mensagem de erro não parece tão clara, mas como essa verificação foi gerada a partir de uma regra personalizada, sempre podemos procurar seu nome original em uma ramificação de relatório:

Se você rolar para cima, verá que a instrução original é &third_message should be styled as own message
. Esse é outro benefício de usar expressões personalizadas: elas ajudam você a entender a falha e descrevem bem todas as validações geradas.
Problema de posicionamento
Aqui está outro exemplo de quando o layout dá errado devido ao alinhamento incorreto de um elemento. Na captura de tela a seguir, você pode ver que a última mensagem está posicionada à esquerda da janela de visualização de mensagens, em vez da direita.

Vamos olhar novamente para a captura de tela com a mensagem de erro:

A captura de tela destaca o contêiner de mensagens e o último elemento da mensagem. Junto com isso, ele mostra a seguinte mensagem de erro: “messenger.message-3” is 285px right which is not in range of 22 to 28px
. Pode não estar claro para um desenvolvedor web por que uma margem de 22 a 28 pixels é esperada no lado direito. Novamente, você teria que procurar uma declaração de validação na ramificação do relatório:

A declaração original para essa verificação é &third_message should be located at the right inside messenger with ~ 25px margin
. Isso faz muito mais sentido. Além disso, outros engenheiros de front-end entenderão este relatório de teste, mesmo que não tenham escrito os testes.
Diretrizes de teste de layout
Com todos esses diferentes experimentos em mente, decidi formalizar todo o aprendizado em diretrizes gerais de teste de layout. Aqui está uma lista de verificação rápida das etapas a serem seguidas para facilitar sua rotina de testes.
- Identificar padrões de layout no projeto.
- Generalize declarações de validação. Tente condensar a maioria das validações em frases únicas.
- Componente! É sempre melhor mover testes de elementos repetidos para componentes dedicados.
- Use nomes significativos para seções, regras e objetos.
- Evite pixels. Tente substituir os valores de pixel (sejam valores exatos ou intervalos) por variáveis significativas.
- Ajuste o código do seu site para facilitar o teste. Isso ajudará você a estruturar e manter seu código de produção e teste.
Critérios de aceitação para o resgate
Muitas vezes recebo perguntas como: “Então, quão detalhado deve ser um teste de layout? E o que devemos testar especificamente?” Uma resposta geral é difícil de dar. O problema é que quando a cobertura do teste é pequena, você perde bugs. Por outro lado, se você tiver testes muito detalhados, poderá obter muitos falsos positivos e, no futuro, poderá se perder na manutenção do teste. Então, há uma troca. Mas eu descobri uma diretriz geral para mim. Se você dividir o trabalho em histórias de usuários menores, fica mais fácil estruturar o design de uma página na forma de critérios de aceitação. No final, você pode colocar esses critérios de aceitação no seu código de teste. Por exemplo, algumas dessas instruções podem ser definidas na forma de regras personalizadas, conforme mostrado em todos os exemplos de código anteriores. Um bom exemplo de critérios de aceitação seria algo assim:
- Os pop-ups devem ser centralizados vertical e horizontalmente na tela.
- Eles devem ter 400 pixels de largura.
- Os botões devem ser alinhados horizontalmente.
- E assim por diante
Depois de descrever o design em frases simples, fica mais fácil convertê-las em instruções reutilizáveis e organizar seu código de teste.
Conclusão
Como você pode ver, esse exercício ajuda você a estruturar um design e descobrir padrões gerais de layout que podem ser compartilhados em vários componentes de página. Mesmo que a página seja complexa e consista em muitos elementos, você sempre pode encontrar uma maneira de agrupá-los em suas expressões de layout. Com essa abordagem, o teste de layout se torna mais uma ferramenta para desenvolvimento orientado a testes, ajudando você a projetar, implementar e entregar software de forma incremental, o que é especialmente útil em um ambiente ágil.
Recursos
- Galen Framework (site oficial)
- Galen Framework, GitHub
- Galen Extras (biblioteca), GitHub
- Galen Bootstrap, GitHub
- “Tutoriais do Galen Framework”, YouTube