Back-End

16 jun, 2017

Automação como Serviço – Apresentando o Scriptflask

Publicidade

Introdução

Há menos de um ano, os engenheiros da Netflix compartilharam os vencedores de testes e desafios que estavam por vir enquanto testavam globalmente o High Impact Titles – HITs (Títulos de alto impacto). Tudo isso enquanto garantíim que o ritmo da inovação na Netflix não desacelerasse. Desde então, foram constatadas melhoras significantes em sua automação. Então, nesse post, eles vão comentar sobre a evolução que tiveram desde o ano passado.

O foco do seu tima ainda é fornecer a cobertura global dos testes do HITs (antes e depois do lançamento) e garantir que todos os testes lógicos A/B sejam completamente verificados antes do lançamento do teste. Este objetivo foi alcançadp graças a uma junção de testes manuais e automatizados.

Em posts anteriores, eles falaram sobre a construção de um conjunto de utilidades comuns – Scripts shell ou Python que se comunicariam com cada micro serviço no ecossistema de serviços da Netflix – o que rendeu uma maneira simples de coletar dados e fazer suas análises em qualquer parte do fluxo de dados do serviço. No entanto, o limite do modelo foi atingido mais rápido do que o esperado. Na sessão a seguir, veremos alguns dos obstáculos que enfrentados e quais suas soluções.

Escalabilidade

Como o escopo dos testes cresceu para cobrir um número substancial de micro serviços no fluxo de serviços da Netflix, o problema da escalabilidade se tornou mais proeminente. Então, eles começaram a criar scripts (shell e Python) que serviriam como utilitários para acessar os dados de cada micro serviço e isso rapidamente trouxe alguns problemas.

Especificamente,

  1. Aumento do tempo necessário para se familiarizar com os micro serviços e a criação dos scripts para eles não era trivial: cada vez que que um utilitário era criado para um novo serviço, eles precisavam gastar tempo entendendo quais os itens solicitados com mais frequência para aquele serviço, qual a arquitetura de serviço que permitia acesso e como poderiam solicitar modificações nos dados expostos para obter o que era necessário para os testes. O esforço necessário não escalou.
  2. A manutenção desses scripts ficou cara conforme o tempo: como a velocidade de cada equipe responsável por esses serviços variava, era responsabilidade deles caminharem juntos para garantir que os problemas fossem tratados imediatamente e seus investidores não fossem afetados. Novamente, com a composição da sua equipe, esse era um esforço que veio com um grande custo (tanto de recursos quanto de tempo).

Existem centenas de micro serviços no ecossistema da Netflix e muitos outros que estão constantemente em algum estágio de evolução para suportar uma ideia de um novo produto. Eles queriam ter uma maneira de criar utilitários para testes de uma aplicação que pudessem ser próprios dos membros da equipe da aplicação e seus testers. Isso vai acelerar os testes e as equipes de funcionalidades poderiam criar os utilitários em parceria. Assim, era possível manter o time de integração no ciclo, mas o investimento de tempo e recursos da nossa equipe foi reduzida.

Usabilidade

Como uma equipe de testes de integração, o objetivo não é apenas em criar novos testes, mas também tornar os mesmos testes mais fáceis de serem executados por outras equipes, para que a organização do produto possa, como um todo, se beneficiar dos esforços iniciais.

No entanto, isso significa que deveria haver apenas uma linguagem comum para esses testes para que quando os testers / desenvolvedores / outros estejam tentando executá-los, eles possam aprender facilmente como utilizar os testes e seus resultados para seus propósitos. A maioria das equipes foca em suas aplicações, mas com um conjunto de utilitários comuns, assim o time de integração poderia dar poder para os testers escreverem testes end-to-end com um investimento mínimo de tempo. Isso aceleraria os testes de integração e o desenvolvimento em geral.

Mas com os scripts shell/ Python, eles precisam ser baixados do repositório para serem testados, e a correção geralmente exige um membro da equipe e além disso os dados retornados por cada micro serviço não tem a mesma formatação, fazendo com que as análises não sejam tarefas triviais para quem utilize os scripts.

Eles já possuiam cases benéficos em ter equipes utilizando suas ferramentas. Como exemplo, durante o recente esforço para produzir as avaliações por “joinhas”, as equipes de controle de qualidade que trabalharam no projeto utilizaram muitos dos seus utilitários para executar testes funcionais antes da implantação. A equipe de MAP que entrega as landing pages para todos os tipos de aparelhos também encontrou utilidade para seus utilitários de testes para executar testes de integração. Sendo assim, uma API centralizada beneficiará imensamente todas as equipes de testes.

Extensibilidade

Vamos pegar um caso de teste como exemplo – Verificar que seja apresentado para um membro do teste um título específico (que é determinado pelo algoritmo como uma combinação para ele) e obtém o título nas primeiras 3 linhas da sua landing page após o login. Esse teste simples é fácil de ser verificado manualmente, mas quando se trata de automação, não é uma verificação de um único passo. Existem múltiplos serviços que precisam ser verificados para executar as declarações para esse teste. Então, ele foi quebrado, como mostrado no diagrama abaixo.

Cada um dos passos acima exige a chamada para um micro serviço com um conjunto específico de argumentos e então a analise de suas respostas. Cada um desses passos é chamado de “declaração de teste simples” pois cada operação é uma chamada simples de “passo/REST/HTTP” para um serviço. Conforme ilustrado no diagrama – esse caso de teste tem interface com 4 serviços diferentes (indicados pelas cores diferentes) o que significa que existem 4 pontos possíveis para haver falha caso haja uma mudança na API.

A intenção era criar uma ordem superior de “declarações de testes complexos” na qual seria possível ter muitos testes chamados ao mesmo tempo. Isso significaria efetivamente que todos os passos do teste acima (que são declarações simples) podem ser encapsuladas por uma declaração de ordem superior que faça tudo em um passo, assim:

– Declarar (declaração complexa) – onde uma declaração complexa = 3ª linha da landing page para um novo membro (que é o alvo para o título) contém o título.

A vantagem de criar declarações de testes complexas é que elas permitem aos testers de integração escrever testes muito específicos que podem ser reutilizados de maneiras simples, ex.: pelos desenvolvedores para encontrar erros, por outras equipes para verificar comportamentos específicos que eles próprios não tem conhecimento/ visibilidade. A abordagem existente tinha obstáculos demais para a criação dessas declarações e para atingir o nível de extensibilidade que era desejado para o framework de testes. Era então preciso uma camada de abstração para que o objetivo fosse atingido.

Apresentando o Scriptflask

Para vencer as desvantagens da escalabilidade, usabilidade e extensibilidade encontradas, eles refatoraram seu framework em uma aplicação de primeira ordem no ecossistema da Netflix. Funcionalmente, tiveram um grande sucesso com a abordagem de automatizar os testes dos endpoints REST. A intenção era futuramente construir esse modelo – dessa maneira, o Scriptflask serviu como um próximo passo lógico para nossa automação de testes. O conjunto existente de scripts utilitários em Python pegou um conjunto de parâmetros e realizou uma função em isolamento. No centro disso, o Scriptfask é uma agregação desses utilitários expostos como endpoints REST.

Como chegaram lá?

Sua infraestrutura costumava parecer com isso:

Seus casos de testes eram scripts shell que dependiam de utilitários e realizariam uma função cada. Aqueles utilitários então acessavam micro serviços individuais e recuperavam ou modificavam os dados dos usuários. Para que mais equipes na Netflix utilizassem esses utilitários, foram consideradas duas opções.

  1. Publicar os utilitários como bibliotecas que poderiam ser utilizadas por outras equipes.
  2. Expor os utilitários como um endpoint REST

A opção número 2 foi escolhida por um motivo simples que eliminaria a necessidade de conflitos de versão, e também eliminaria a necessidade de resgatar qualquer código, já que as interações poderiam ser alcançadas via chamadas HTTPS.

Por que o Flask?

Foi utilizado o servidor web Flask para executar seus scripts Python.

Seu requisito primário era utilizar uma API REST, e sendo assim, não havia interesse em construir uma UI, ou utilizar bancos de dados, o Flask funcionava perfeitamente. O Flask também é utilizado em múltiplas aplicações na Netflix, propiciando um fácil suporte interno. Também foi analisado o Django e o Pyramid, e eventualmente foi escolhido o Flask – que ofereceu a maior adaptabilidade e facilidade de implementação.

O Scriptflask consiste tem dois componentes:

  1. Utilitários: são os utilitários da automação de testes, refatorados como funções Python e contendo mais lógica de negócios e dando poder à estratégia de treinamentos de “declarações de testes complexos”
  2. API: essa é a implementação do servidor de web Flask. Consite na verificação das entradas, descoberta de serviços, auto-testes e verificações da saúde, e a exposição da funcionalidade dos utilitários como endponts REST, retornando dados formatados como JSON.

Benefícios do Scriptflask

Escalabilidade

O Scriptflask é escalável porque fazer adições a ele é fácil. Cada dono de aplicação pode adicionar um utilitário único que interaja com sua aplicação, e fazer isso é relativamente muito simples. Levou um dia de um dos desenvolvedores obter o código fonte, implantar localmente, e implementar endpoints REST para um novo micro serviço que eles tenham implementado.

Isso reduz significativamente o tempo de implementação. Como equipe de integração, eles também podem focar em executar os testes e aumentar sua cobertura de testes dessa maneira.

Como uma aplicação de primeira ordem no ecossistema da Netflix, também poderiam se beneficiar de facilmente agendar compromissos, escalas e integração contínua utilizando o Spinnaker.

Usabilidade

O Scriptflask tornou muito fácil iniciar a implementação de um endpoint – todos os registos, tratamento de erros, a codificação dos dados é tratada diretamente na caixa, exigindo que pouco código personalizado seja escrito. Um endpoint é bem simples de ser implementado, com o corpo da solicitação sendo o único componente que precisa ser implementado – o restante veio de graça.

Um desafio significante que foi encontrado em sua iteração anterior de automação de testes foi manter um registro dos utilitários que haviam sido implementado como uma equipe. Essa é uma razão para incluirem as especificações do OpenAPI como uma funcionalidade obrigatória, quando foram levantados os requisitos para o Scriptflask. A implementação do OpenAPI facilita para que os usuários do Scriptflask executem operações também assim como identifiquei endpoints que estejam faltando.

Extensibilidade

Outro desafio enfrentado com sua implementação anterior era que outras equipes não estavam tão dispostas a utilizar sua automação de testes porque havia uma curva de aprendizado envolvida. Eles quiseram mitigar isso fornecendo a eles uma maneira mais fácil de obter certos testes convertendo casos de testes inteiros em um endpoint REST que executaria o teste, e na resposta enviar os dados que foram gerados ou manipulados, assim como os resultados de qualquer validação.

Isso possibilitou expor as múltiplas verificações do seu back-end para o HITs como endpoints REST para as equipes de front-end. Também foi possível mostrar os testes end-to-end para um micro serviços como uma série de endpoints REST.

Outra vantagem de exibir casos de teste dessa maneira é que eles são independentes das linguagens, e isso permite que equipes que trabalhem com frameworks diferentes incorporem casos de testes.

Outras vantagens da utilização do Scriptflask

Redução da complexidade

O Scriptflask reduz significantemente a complexidade dos testes de integração. Cada caso de teste agora é uma sequência simples de chamadas REST. Em alguns casos, o teste em si é uma “declaração complexa” que pode ser executada como um passo. Para um cliente do Scriptflask, utilizá-lo não é diferente de utilizar qualquer outro serviço REST. Para os interessados em contribuir, instalar e começar a utilizar o Scriptflask e seus testes de integração, agora a instalação é limpa, em dois passos e uma pessoa com os mínimos conhecimentos de Python consegue instalar e configurar para utilização em menos de dez minutos.

Isso ajuda a trazer novos testers rapidamente para seu framework e reduz as barreiras para que comecem a contribuir com os esforços de testes. Assim, eles estão conseguindo atrair desenvolvedores e testes de uma variedade de equipes de funcionalidades para contribuir com o Scriptflask e isso tem resultado em muitas discussões ativas sobre os testes e ferramentas, o que estimula mais inovação e criatividade.

Navegando pelos problemas de confiabilidade e disponibilidade para os serviços

Os micro serviços da Netflix são utilizados em múltiplas regiões do AWS. Utilizando o Scriptflask, foi possível atingir algo que antes não era possível atingir eficientemente no sistema anterior – fazer a recuperação de uma região para outra para todos os serviços que estejam com utilização ativa-ativa. Também construiram uma hospedagem para quando a equipe de confiabilidade executasse exercícios caóticos que impactem os serviços.

A vantagem que ganharam com o Scriptflask é que agora eles podem tomar decisões inteligentes sobre o roteamento sem que o tester tenha que entender e dominar logicas adicionais. Isso ajuda a reduzir para o tester a responsabilidade de tratar variáveis externas no sistema, o que poderia tornar o teste mais frágil.

Velocidade da execução dos testes

Conforme começaram a utilizar o Scriptflask para os testes, descobriram uma redução significativa nos tempos de execução dos testes. Em um caso, foi visto que o tempo de execução do teste caiu de 5 minutos para 56 segundos. Isso aconteceu porque os filtros complicados e a lógica de processamento foram delegados ao Scriptflask onde eles puderam otimizar muitos dos mais intrincados passos do teste e isso resultou na economia de tempo. Essa melhora na velocidade resulta em fazer os testes focarem em asserções que sejam rápidas e fáceis de serem verificadas ao invés de analisar falsos-positivos causados por ineficiências do sistema.

Como eles não planejaram melhorar a velocidade de execução dos testes no início, isso foi um benefício de todo o exercício muito bem-vindo.

Melhorias futuras

O objetivo de curto prazo é promover o Scriptflask dentro da organização e tornar os testes de todos os aspectos do fluxo de serviços da Netflix simples e intuitivos para o aprendizado. Para fazer isso será necessário:

– Engajamento: Envolver outras equipes de funcionalidades no processo de desenvolvimento para que eles possam testemunhar os benefícios, e criar um sentimento de propriedade que vai gerar um ciclo virtuoso de adoção e participação;

– Melhorias: Criar ferramentas para gerar automaticamente modelos de códigos para novos endpoints e novos serviços. Isso futuramente reduzirá as barreiras do início, ajudando a trazer novos engenheiros mais rápido.

– Expanção: As integrações com os fluxos do Spinnaker vão expandir o escopo do Scriptflask possibilitando que as equipes expandam a cobertura dos seus testes executando testes end-to-end como parte das implantações dos testes.

Além das melhorias nas quais a Netflix está focada, eles também estão considerando abrir o código de alguns aspectos do Scriptflask.

Em um longo prazo, mais mudanças são esperadas. O time sempre está explorando novas maneiras de testar e melhorar a velocidade geral da adição de novas funcionalidades e acelerar a liberação dos testes A/B.

 

***

Fonte: https://medium.com/netflix-techblog/automation-as-a-service-introducing-scriptflask-17a8e4ad954b