Como testar funções e aplicações com tecnologia sem servidor
Os testes de funções com tecnologia sem servidor usam tipos e técnicas de teste tradicionais, mas você também deve considerar testar aplicações com tecnologia sem servidor como um todo. Os testes baseados em nuvem fornecem a medida mais precisa da qualidade das suas funções e aplicações com tecnologia sem servidor.
Uma arquitetura de aplicações com tecnologia sem servidor inclui serviços gerenciados que fornecem funcionalidade de aplicações críticas por meio de chamadas de API. Por esse motivo, seu ciclo de desenvolvimento deve incluir testes automatizados que verifiquem a funcionalidade quando sua função e seus serviços interagem.
Se você não criar testes baseados em nuvem, poderá encontrar problemas devido às diferenças entre o ambiente local e o ambiente implantado. Seu processo de integração contínua deve executar testes em comparação com um conjunto de recursos provisionados na nuvem antes de promover seu código para o próximo ambiente de implantação, como GQ, Preparação ou Produção.
Continue lendo este breve guia para aprender sobre estratégias de testes para aplicações com tecnologia sem servidor ou acesse o repositório de exemplos de testes com tecnologia sem servidor
Para testes com tecnologia sem servidor, você ainda escreverá testes unitários, de integração e de ponta a ponta.
-
Testes unitários: testes executados em comparação com um bloco de código isolado. Por exemplo, verificar a lógica de negócios para calcular a taxa de entrega de acordo com um item e um destino determinado.
-
Testes de integração: testes envolvendo dois ou mais componentes ou serviços que interagem, normalmente em um ambiente de nuvem. Por exemplo, a verificação de eventos de processos de uma função em uma fila.
-
Testes de ponta a ponta: testes que verificam o comportamento em toda a aplicação. Por exemplo, garantir que a infraestrutura seja configurada corretamente e que os eventos fluam entre os serviços conforme o esperado para registrar o pedido de um cliente.
Resultados de negócios direcionados
A configuração de soluções com tecnologia sem servidor pode levar mais tempo. Você deve verificar as interações conduzidas por eventos entre os serviços. Tenha em mente estas questões práticas de negócios ao ler este guia:
-
Aumentar a qualidade da sua aplicação
-
Diminuir o tempo para criar recursos e corrigir bugs
A qualidade de uma aplicação depende do teste de vários cenários. Considere seus cenários de negócios e automatize os testes para execução nos serviços em nuvem. Isso aumenta a qualidade da sua aplicação.
Bugs e problemas de configuração custam menos quando detectados no início do ciclo de desenvolvimento. Problemas que não são detectados até a produção exigem mais esforço e mais pessoas para serem corrigidos.
Uma boa estratégia de testes de tecnologia sem servidor melhora a qualidade do software e acelera as iterações. Ela verifica se suas funções e aplicações do Lambda funcionam conforme o esperado na nuvem.
O que testar
Recomendamos uma estratégia de testes que teste os comportamentos dos serviços gerenciados, a configuração da nuvem, as políticas de segurança e a integração com seu código. Os testes de comportamento, também conhecidos como testes de caixa fechada, verificam se um sistema funciona conforme o esperado sem o conhecimento dos componentes internos.
-
Execute testes unitários para verificar a lógica de negócios dentro das funções do Lambda.
-
Verifique se os serviços integrados foram realmente invocados e se os parâmetros de entrada estão corretos.
-
Verifique se um evento passa por todos os serviços esperados de ponta a ponta em um fluxo de trabalho.
Na arquitetura tradicional baseada em servidor, as equipes frequentemente testam apenas o código executado no servidor de aplicações. Outros componentes, serviços ou dependências são considerados externos e fora do escopo.
As aplicações sem servidor consistem em pequenas unidades de trabalho. Os exemplos incluem funções do Lambda que recuperam produtos de um banco de dados, processam itens de uma fila ou redimensionam uma imagem no armazenamento. Cada componente é executado no seu próprio ambiente. As equipes gerenciam muitas dessas pequenas unidades em uma única aplicação.
Algumas funcionalidades podem ser tratadas inteiramente por serviços gerenciados, como o Amazon S3, ou criadas sem código personalizado. Não é necessário testar esses serviços gerenciados. No entanto, você deve testar como seu código se integra a eles.
Como testar com tecnologia sem servidor
Provavelmente você sabe como testar aplicações implantadas localmente. Você escreve testes em relação ao código em seu desktop ou dentro de contêineres. Por exemplo, você pode chamar um serviço web local e, em seguida, verificar a resposta.
As soluções com tecnologia sem servidor usam o seu código de função e em serviços gerenciados baseados em nuvem, como filas, bancos de dados, barramentos de eventos e sistemas de mensagens. Esses componentes são conectados por meio de uma arquitetura conduzida por eventos, na qual as mensagens, chamadas de eventos, fluem de um recurso para outro. Algumas interações são síncronas, como um serviço web que retorna resultados imediatamente.
Outros são assíncronos, como colocar itens em uma fila ou iniciar uma etapa do fluxo de trabalho. Sua estratégia de testes deve cobrir ambos os tipos e testar as interações entre os serviços. Para interações assíncronas, talvez seja necessário detectar efeitos colaterais em componentes downstream que não são imediatamente visíveis.
Você não pode replicar totalmente um ambiente de nuvem localmente. Isso inclui filas, tabelas de banco de dados, barramentos de eventos e políticas de segurança. As diferenças entre ambientes locais e em nuvem causam problemas. Essas diferenças aumentam o tempo de reprodução e correção de bugs.
Em aplicações sem servidor, os componentes existem inteiramente na nuvem. É necessário testar o código e os serviços da nuvem para desenvolver recursos e corrigir bugs.
Técnicas de teste
Sua estratégia de teste provavelmente inclui uma combinação de técnicas. Você usa testes interativos rápidos para depurar funções no console. Você escreve testes unitários automatizados para verificar a lógica de negócios. Você verifica as chamadas para serviços externos com simulações. Você também pode testar em emuladores que imitam um serviço.
-
Testes na nuvem: você implanta infraestrutura e código para testar com serviços reais, políticas de segurança e configurações. Os testes baseados em nuvem fornecem a medida mais precisa da qualidade do seu código.
Depurar uma função no console é uma forma rápida de testar na nuvem. Você pode escolher entre eventos de teste de exemplo ou criar um evento personalizado. Você também pode compartilhar eventos de teste com sua equipe por meio do console.
Para automatizar os testes no ciclo de vida de desenvolvimento e compilação, teste fora do console. Consulte as seções de testes específicos da linguagem neste guia para obter estratégias de automação.
-
Testar com simulações: simulações são objetos no seu código que simulam um serviço externo. Elas fornecem um comportamento predefinido para verificar as chamadas e parâmetros de serviços. Uma imitação é uma simulação que usa atalhos para simplificar ou acelerar os testes. Por exemplo, a imitação de um objeto de acesso a dados pode retornar dados de um datastore na memória. As simulações podem simplificar dependências complexas, mas também podem levar a mais simulações para substituir dependências aninhadas.
-
Testando localmente usando AWS SAM CLI: use a AWS SAM CLI para invocar funções do Lambda localmente em contêineres do Docker que utilizam o mesmo ambiente de runtime que o AWS Lambda. É possível testar a lógica da função e o processamento de eventos sem precisar implantar na nuvem.
-
Testar com emulação: use a integração LocalStack no VS Code para emular vários AWS serviços localmente para testar integrações de serviços.
Testes na nuvem
Os testes na nuvem são valiosos para todas as fases dos testes: testes de unidade, testes de integração e testes de ponta a ponta. Os testes executados em códigos e serviços baseados em nuvem fornecem a medida mais precisa da qualidade do seu código.
Uma maneira simples de executar uma função do Lambda na nuvem é por meio de um evento de teste no Console de gerenciamento da AWS. Um evento de teste é uma entrada JSON para sua função. Se a função não necessitar de entrada, o evento poderá ser um documento JSON vazio ({}). O console fornece eventos de exemplo para muitas integrações de serviços. Você pode compartilhar eventos com sua equipe para facilitar os testes.
Saiba como depurar uma função de exemplo no console.
nota
Embora executar funções no console seja uma maneira rápida de depurar, a automatização dos ciclos de teste é essencial para aumentar a qualidade e a velocidade de desenvolvimento da aplicação.
Exemplos de automação de testes estão disponíveis no repositório de exemplos de testes com tecnologia sem servidor
python -m pytest -s tests/integration -v
Embora o teste seja executado localmente, ele conversa com recursos baseados na nuvem. Esses recursos foram implantados usando a ferramenta da linha de comando AWS Serverless Application Model e AWS SAM. O código de teste primeiro recupera as saídas da pilha implantada, como o endpoint da API, o ARN da função e a função de segurança.
Em seguida, ele envia uma solicitação para o endpoint da API. A resposta contém uma lista de buckets do Amazon S3. Esse teste é executado com recursos baseados na nuvem para verificar se eles estão implantados, protegidos e funcionando.
========================= test session starts =========================
platform darwin -- Python 3.10.10, pytest-7.3.1, pluggy-1.0.0
-- /Users/t/code/aws/serverless-test-samples/python-test-samples/apigw-lambda/venv/bin/python
cachedir: .pytest_cache
rootdir: /Users/t/code/aws/serverless-test-samples/python-test-samples/apigw-lambda
plugins: mock-3.10.0
collected 1 item
tests/integration/test_api_gateway.py::TestApiGateway::test_api_gateway
--> Stack outputs:
HelloWorldApi
= https://p7teqs3162.execute-api.us-east-2.amazonaws.com/Prod/hello/
> API Gateway endpoint URL for Prod stage for Hello World function
PythonTestDemo
= arn:aws:lambda:us-east-2:123456789012:function:testing-apigw-lambda-PythonTestDemo-iSij8evaTdxl
> Hello World Lambda Function ARN
PythonTestDemoIamRole
= arn:aws:iam::123456789012:role/testing-apigw-lambda-PythonTestDemoRole-IZELQQ9MG4HQ
> Implicit IAM Role created for Hello World function
--> Found API endpoint for "testing-apigw-lambda" stack...
--> https://p7teqs3162.execute-api.us-east-2.amazonaws.com/Prod/hello/
API Gateway response:
amplify-dev-123456789-deployment|myapp-prod-p-loggingbucket-123456|s3-java-bucket-123456789
PASSED
========================= 1 passed in 1.53s =========================
Para o desenvolvimento de aplicações nativas de nuvem, os testes na nuvem oferecem os seguintes benefícios:
-
Você pode testar todos os serviços disponíveis.
-
Você está sempre usando as APIs de serviço e os valores de retorno mais recentes.
-
Um ambiente de teste na nuvem se assemelha muito ao seu ambiente de produção.
-
Os testes podem abranger políticas de segurança, cotas de serviço, configurações e parâmetros específicos da infraestrutura.
-
Cada desenvolvedor pode criar rapidamente um ou mais ambientes de teste na nuvem.
-
Os testes na nuvem aumentam a confiança de que seu código está sendo executado corretamente na produção.
Os testes na nuvem têm algumas desvantagens. As implantações na nuvem geralmente demoram mais do que as implantações locais de desktop.
Ferramentas, como o AWS Serverless Application Model (AWS SAM) Accelerate, o AWS Kit de desenvolvimento em nuvem (AWS CDK) watch mode e o SST
nota
Veja como criar infraestrutura como código no Guia do desenvolvedor de tecnologia sem servidor para saber mais sobre o AWS Serverless Application Model, CloudFormation e AWS Cloud Development Kit (AWS CDK).
Diferentemente dos testes locais, os testes em nuvem usam recursos que podem gerar custos. Ambientes de teste isolados podem aumentar o trabalho para suas equipes de DevOps, especialmente em organizações com controles de conta rígidos. Mesmo assim, o tempo do desenvolvedor para configurar um ambiente local complexo pode custar mais do que usar ambientes de nuvem descartáveis criados com ferramentas de infraestrutura como código.
Testar na nuvem, mesmo com essas considerações, ainda é a melhor maneira de garantir a qualidade das suas soluções com tecnologia sem servidor.
Testar com simulações
Testar com simulações é uma técnica em que você cria objetos de substituição no seu código para simular o comportamento de um serviço em nuvem.
Por exemplo, você pode escrever um teste que usa uma simulação do serviço do Amazon S3. A simulação retorna uma resposta definida sempre que o método CreateObject é chamado. Não é necessário chamar o Amazon S3 ou qualquer outro endpoint de serviço.
Estruturas de simulação normalmente geram objetos simulados para você. Algumas estruturas são genéricas. Outros têm como alvo AWS SDKs, como o Moto
Os objetos simulados diferem dos emuladores. Os desenvolvedores criam simulações como parte do código de teste. Os emuladores são aplicações autônomas que expõem a mesma funcionalidade dos sistemas que eles imitam.
As vantagens de usar simulações incluem o seguinte:
-
Elas podem simular serviços de terceiros que estão além do controle da aplicação, como APIs e provedores de software como serviço (SaaS), sem precisar de acesso direto a esses serviços.
-
As simulações são úteis para testar condições de falha, especialmente quando essas condições são difíceis de simular, como uma interrupção do serviço.
-
A simulação pode fornecer testes locais rápidos depois de configurada.
-
As simulações podem fornecer um comportamento substituto para praticamente qualquer tipo de objeto. Portanto, as estratégias de simulação podem criar cobertura para uma variedade mais ampla de serviços do que os emuladores.
-
Quando novos recursos ou comportamentos são disponibilizados, os testes com simulações podem reagir mais rapidamente. Ao usar uma estrutura simulada genérica, você poderá simular novos recursos assim que o AWS SDK atualizado estiver disponível.
O teste com simulação tem as seguintes desvantagens:
-
As simulações geralmente exigem uma quantidade significativa de esforços de configuração, especificamente na tentativa de determinar valores de retorno de diferentes serviços para simular respostas adequadamente.
-
As simulações são escritas, configuradas e devem ser mantidas pelos desenvolvedores, aumentando suas responsabilidades.
-
Talvez você precise ter acesso à nuvem para entender as APIs e os valores de retorno dos serviços.
-
As simulações podem ser difíceis de manter. Quando as assinaturas simuladas da API de nuvem mudam ou os esquemas de valor de retorno evoluem, é preciso atualizar as simulações. As simulações também exigem atualizações se você estender a lógica da aplicação para fazer chamadas para novas APIs.
-
Os testes que usam simulações podem passar em ambientes de área de trabalho, mas falhar na nuvem. Os resultados podem não corresponder à API atual. A configuração e as cotas do serviço não podem ser testadas.
-
As estruturas simuladas se limitam a testar ou detectar uma política do AWS Identity and Access Management (IAM). Embora as simulações sejam melhores para simular quando a autorização falha ou uma cota é excedida, os testes não podem determinar qual resultado realmente ocorre em um ambiente de produção.
Testando localmente usando AWS SAM CLI
Utilize AWS SAMCLI para testar suas funções em contêineres do Docker usando o mesmo ambiente de tempo de execução do AWS Lambda. É possível testar a lógica da função e o processamento local de eventos sem precisar implantar na nuvem. Se sua função fizer chamadas de API para outras Serviços da AWS, essas chamadas alcançam recursos reais da AWS.
As vantagens de testar com contêineres locais incluem o seguinte:
-
Utiliza AWS Lambda ambientes de runtime para testes precisos.
-
Permite iterações rápidas de desenvolvimento local sem nenhuma implantação na nuvem.
-
Oferece suporte para depuração com ferramentas de desenvolvimento locais familiares.
O teste com contêineres locais aprensenta as seguintes limitações:
-
As chamadas AWS service (Serviço da AWS) da sua função interagem com recursos reais da AWS, o que pode gerar custos e afetar dados de produção.
-
Requer que o Docker seja instalado e executado localmente.
Testar com emulação
Os emuladores são aplicações executados localmente que imitam AWS serviços fornecendo APIs e valores de retorno semelhantes. LocalStack é uma ferramenta de emulação popular que fornece um ambiente de desenvolvimento local completo para testar integrações de serviços.
LocalStack é um emulador de nuvem AWS que você pode usar para testar aplicações sem servidor localmente. É possível testar funções do Lambda que se integram a serviços como DynamoDB, Amazon S3 e Amazon SQS sem se conectar a serviços reais AWS. É possível usar o LocalStack no AWS Toolkit para VS Code.
As vantagens do teste com emuladores incluem o seguinte:
-
Os emuladores podem ajudar a acelerar iterações de desenvolvimento local e testes.
-
Os emuladores fornecem um ambiente familiar para desenvolvedores acostumados a desenvolver código em um ambiente local. Por exemplo, se você estiver familiarizado com o desenvolvimento de uma aplicação de n camadas, talvez tenha um mecanismo de banco de dados e um servidor Web, semelhantes aos executados em produção na sua máquina local para fornecer uma capacidade de teste rápida, local e isolada.
-
Os emuladores não exigem qualquer alteração na infraestrutura de nuvem (como contas de desenvolvedores na nuvem). Por isso, é fácil implementar com os padrões de teste existentes.
-
Como os emuladores não utilizam recursos de AWS reais, você não receberá cobranças inesperadas ao iniciar vários serviços ou por deixar alguns recursos serem executados por longos períodos de tempo.
Testar com emuladores tem as seguintes desvantagens:
-
Os emuladores podem ser difíceis de configurar e replicar, especialmente quando usados em pipelines de CI/CD. Isso pode aumentar a workload da equipe de TI ou dos desenvolvedores que gerenciam seu próprio software.
-
Os recursos e APIs emulados geralmente ficam atrasados em relação às atualizações do serviço. Isso pode causar erros porque o código testado não corresponde à API real e impede a adoção de novos recursos.
-
Os emuladores precisam de suporte, atualizações, correções de bugs e aprimoramentos de paridade de recursos. Eles são de responsabilidade do autor do emulador, que pode ser uma empresa externa.
-
Os testes que dependem de emuladores podem fornecer resultados bem-sucedidos localmente, mas falham na nuvem devido a políticas de segurança de produção, configurações entre serviços ou excesso de cotas do Lambda.
Práticas recomendadas
As seções a seguir fornecem recomendações para testes bem-sucedidos de aplicações com tecnologia sem servidor.
Você pode encontrar exemplos práticos de testes e automação de testes no repositório de exemplos de testes com tecnologia sem servidor
Priorize os testes na nuvem
Os testes na nuvem fornecem a cobertura de teste mais confiável, precisa e completa. A realização de testes no contexto da nuvem testa de forma abrangente não apenas a lógica de negócios, mas também as políticas de segurança, as configurações de serviços, as cotas, as assinaturas de API e os valores de retorno mais atualizados.
Estruture seu código quanto à capacidade de teste
Simplifique seus testes e funções do Lambda separando o código específico do Lambda da sua principal lógica de negócios.
Seu manipulador de funções do Lambda deve ser um pequeno adaptador que absorve dados de eventos e transmite somente os detalhes importantes para seus métodos de lógica de negócios. Com essa estratégia, você pode realizar testes abrangentes na sua lógica de negócios sem se preocupar com detalhes específicos do Lambda. Suas funções do AWS Lambda não devem exigir a configuração de um ambiente complexo ou uma grande quantidade de dependências para criar e inicializar o componente em teste.
De um modo geral, você deve escrever um manipulador que extraia e valide dados do evento de entrada e dos objetos de contexto e, em seguida, envie essa entrada aos métodos que executam sua lógica de negócios.
Acelerar loops de feedback de desenvolvimento
Existem ferramentas e técnicas para acelerar os loops de feedback de desenvolvimento. Por exemplo, o AWS SAM Accelerate e o modo de observação do AWS CDK diminuem o tempo necessário para atualizar os ambientes de nuvem.
Os exemplos no repositório de exemplos de testes com tecnologia sem servidor
Também recomendamos que você crie e teste os recursos de nuvem o mais cedo possível durante o desenvolvimento, não somente após um registro no controle de origem. Essa prática permite uma exploração e experimentação mais rápidas no desenvolvimento de soluções. Além disso, automatizar a implantação em uma máquina de desenvolvimento ajuda a descobrir problemas de configuração da nuvem com mais rapidez e reduz o esforço desperdiçado em atualizações e processos de revisão de código.
Foco nos testes de integração
Ao criar aplicações com o Lambda, testar os componentes juntos é a melhor prática.
Os testes executados em comparação com dois ou mais componentes arquitetônicos são chamados de testes de integração. O objetivo dos testes de integração é entender não apenas como seu código é executado em todos os componentes, mas também como o ambiente que hospeda seu código se comporta. Testes de ponta a ponta são tipos especiais de testes de integração que verificam o comportamento em toda uma aplicação.
Para criar testes de integração, implante sua aplicação em um ambiente de nuvem. Isso pode ser feito em um ambiente local ou por meio de um pipeline de CI/CD. Em seguida, escreva testes para exercitar o sistema em teste (SUT) e validar o comportamento esperado.
Por exemplo, o sistema em teste pode ser uma aplicação que usa o API Gateway, Lambda e DynamoDB. Um teste pode fazer uma chamada HTTP sintética para um endpoint do API Gateway e validar se a resposta incluiu a carga útil esperada. Esse teste valida se o código do AWS Lambda está correto e se cada serviço está configurado corretamente para processar a solicitação, incluindo as permissões do IAM entre eles. Além disso, você pode criar o teste para gravar registros de vários tamanhos para verificar se suas cotas de serviço, como o tamanho máximo do registro no DynamoDB, estão configuradas corretamente.
Criar ambientes de teste isolados
Os testes na nuvem normalmente exigem ambientes de desenvolvedores isolados para que não haja sobreposição de testes, dados e eventos.
Uma abordagem é fornecer a cada desenvolvedor uma conta da AWS dedicada. Isso evita conflitos com a nomenclatura de recursos que podem ocorrer quando vários desenvolvedores trabalhando em uma base de código compartilhada tentam implantar recursos ou invocar uma API.
Os processos de teste automatizados devem criar recursos com nomes exclusivos para cada pilha. Por exemplo, você pode configurar scripts ou arquivos de configuração TOML para que os comandos sam deploy ou sam sync da CLI do AWS SAM especifiquem automaticamente uma pilha com um prefixo exclusivo.
Em alguns casos, os desenvolvedores compartilham uma conta da AWS. Isso pode ocorrer devido à existência de recursos em sua pilha que são caros para operar ou de provisionar e configurar. Por exemplo, um banco de dados pode ser compartilhado para facilitar a configuração e a propagação adequada dos dados.
Se os desenvolvedores compartilharem uma conta, você deverá definir limites para identificar a propriedade e eliminar a sobreposição. Uma maneira de fazer isso é prefixar os nomes das pilhas com os IDs de usuário dos desenvolvedores. Outra abordagem popular é configurar pilhas com base em ramificações de código. Com os limites das ramificações, os ambientes são isolados, mas os desenvolvedores ainda podem compartilhar recursos, como um banco de dados relacional. Essa abordagem é a melhor prática quando os desenvolvedores trabalham em mais de uma ramificação ao mesmo tempo.
Os testes na nuvem são valiosos para todas as fases dos testes, incluindo testes unitários, testes de integração e testes de ponta a ponta. Manter o isolamento adequado é essencial. Porém, você ainda quer que seu ambiente de GQ seja o mais parecido possível com seu ambiente de produção. Por esse motivo, as equipes adicionam processos de controle de mudanças para ambientes de GQ.
Para ambientes de pré-produção e de produção, geralmente são estabelecidos limites no nível da conta para isolar as workloads dos problemas de vizinho barulhento e implementar controles de segurança com privilégio mínimo para proteger dados confidenciais. As workloads têm cotas. Você não quer que seus testes consumam cotas alocadas para produção (vizinho barulhento) ou tenham acesso aos dados do cliente. O teste de carga é outra atividade que você deve isolar da sua pilha de produção.
Em todos os casos, os ambientes devem ser configurados com alertas e controles para evitar gastos desnecessários. Por exemplo, você pode limitar o tipo, a camada ou o tamanho dos recursos que podem ser criados e configurar alertas por e-mail quando os custos estimados excederem um determinado limite.
Use simulações para lógica de negócios isolada
As estruturas simuladas são uma ferramenta valiosa para escrever testes unitários rápidos. Elas são especialmente benéficas quando os testes abrangem lógicas de negócios internas complexas, como cálculos ou simulações matemáticas ou financeiras. Procure testes unitários que tenham um grande número de casos de teste ou variações de entrada, nos quais essas entradas não alterem o padrão ou o conteúdo das chamadas para outros serviços de nuvem.
O código coberto por testes unitários com simulações também deve ser abordado por testes na nuvem. Isso é recomendado porque o laptop de um desenvolvedor ou o ambiente de uma máquina de criação pode ser configurado de forma diferente de um ambiente de produção na nuvem. Por exemplo, suas funções do Lambda podem usar mais memória ou tempo do que o alocado quando executadas com determinados parâmetros de entrada. Ou seu código pode incluir variáveis de ambiente que não estão configuradas da mesma forma (ou não estão configuradas) e as diferenças podem fazer com que o código se comporte de forma diferente ou apresente falha.
O benefício das simulações é menor para testes de integração porque o nível de esforço para implementar as simulações necessárias aumenta com o número de pontos de conexão. Os testes de ponta a ponta não devem usar simulações porque eles geralmente lidam com estados e lógica complexa que não podem ser facilmente simulados com estruturas de simulação.
Por fim, evite usar serviços de nuvem simulados para validar a implementação adequada das chamadas de serviço. Em vez disso, faça chamadas de serviço de nuvem na nuvem para validar o comportamento, a configuração e a implementação funcional.
Usar emuladores com moderação
Os emuladores podem ser convenientes em alguns casos de uso, por exemplo, para uma equipe de desenvolvimento com acesso limitado, não confiável ou lento à Internet. Mas, na maioria das circunstâncias, opte por usar emuladores com moderação.
Ao evitar emuladores, você pode compilar e inovar com os recursos de serviço mais recentes e APIs atualizadas. Você não fica preso esperando os lançamentos de fornecedores para obter paridade de recursos. Você reduz suas despesas iniciais e contínuas de compra e configuração em vários sistemas de desenvolvimento e mecanismos de compilação. Além disso, você evita o problema de muitos serviços em nuvem simplesmente não terem emuladores disponíveis. Uma estratégia de teste que depende de emulação impossibilita o uso desses serviços (resultando em soluções alternativas potencialmente mais caras) ou produzirá código e configurações que não foram bem testados.
Ao usar a emulação para testes, você ainda deve testar na nuvem para verificar a configuração e testar as interações com serviços em nuvem que só podem ser simulados ou reproduzidos em um ambiente emulado.
Testes de desafios no local
Ao usar emuladores e chamadas simuladas para testar no desktop local, você pode observar inconsistências de teste à medida que seu código progride de ambiente para ambiente em seu pipeline de CI/CD. Os testes de unidade para validar a lógica de negócios da aplicação no desktop podem não testar com precisão aspectos críticos dos serviços em nuvem.
Os exemplos a seguir fornecem casos a serem observados nos testes realizados no local com simulações e emuladores:
Exemplo: a função do Lambda cria um bucket do S3
Se a lógica de uma função do Lambda depender da criação de um bucket do S3, um teste completo deverá confirmar que o Amazon S3 foi chamado e que o bucket foi criado com sucesso.
-
Em uma configuração de teste de simulação, você pode simular uma resposta bem-sucedida e potencialmente adicionar um caso de teste para lidar com uma resposta de falha.
-
Em um cenário de teste de emulação, a API CreateBucket pode ser chamada, mas você precisa estar ciente de que a identidade que faz a chamada local não se origina do serviço do Lambda. A identidade da chamada não assume uma função de segurança como na nuvem. Portanto, uma autenticação de espaço reservado é usada em seu lugar, possivelmente com uma função ou identidade de usuário mais permissiva que é diferente quando executada na nuvem.
As configurações de simulação e emulação testam o que a função do Lambda faz se chamar o Amazon S3; no entanto, esses testes não verificam se a função do Lambda, conforme configurada, é capaz de criar com êxito o bucket do Amazon S3. Você deve garantir que a função atribuída à função tenha uma política de segurança anexada que permita que a função execute a ação s3:CreateBucket. Caso contrário, a função provavelmente falha quando implantada em um ambiente de nuvem.
Exemplo: a função do Lambda processa mensagens de uma fila do Amazon SQS
Se uma fila do Amazon SQS for a origem de uma função do Lambda, um teste completo deverá verificar se a função do Lambda vai ser invocada com êxito quando uma mensagem for colocada em uma fila.
Os testes de emulação e simulação geralmente são configurados para executar o código da função do Lambda diretamente e para simular a integração do Amazon SQS passando uma carga útil de eventos JSON (ou um objeto desserializado) como entrada do manipulador da função.
O teste local que simula a integração do Amazon SQS testa o que a função do Lambda faz quando é chamada pelo Amazon SQS com uma determinada carga útil, mas o teste não verifica se o Amazon SQS invoca com êxito a função do Lambda quando ela é implantada em um ambiente de nuvem.
Alguns exemplos de problemas de configuração que você pode encontrar com o Amazon SQS e o Lambda incluem o seguinte:
-
O tempo limite de visibilidade do Amazon SQS é muito baixo, resultando em várias invocações quando apenas uma foi planejada.
-
O perfil de execução da função do Lambda não permite a leitura de mensagens da fila (por meio de
sqs:ReceiveMessage,sqs:DeleteMessageousqs:GetQueueAttributes). -
O evento de exemplo que é passado para a função do Lambda excede a cota de tamanho de mensagem do Amazon SQS. Portanto, o teste é inválido porque o Amazon SQS nunca seria capaz de enviar uma mensagem desse tamanho.
Como mostrado nesses exemplos, os testes que abrangem a lógica de negócios, mas não as configurações entre os serviços de nuvem, provavelmente fornecerão resultados não confiáveis.
Perguntas frequentes
Tenho uma função do Lambda que executa cálculos e retorna um resultado sem chamar qualquer outro serviço. Preciso realmente testá-la na nuvem?
Sim. As funções do Lambda têm parâmetros de configuração que podem alterar o resultado do teste. Todo código de função do Lambda tem uma dependência nas configurações de tempo limite e memória, o que pode causar falha da função se essas configurações não forem definidas corretamente.
As políticas do Lambda também permitem o registro de saída padrão para o Amazon CloudWatch
Como os testes na nuvem podem ajudar nos testes unitários? Caso esteja na nuvem e se conecte a outros recursos, não é um teste de integração?
Nós definimos testes de unidade como testes que operam isoladamente em componentes da arquitetura, mas isso não impede que os testes incluam componentes que possam chamar outros serviços ou usar alguma comunicação de rede.
Muitas aplicações com tecnologia sem servidor têm componentes da arquitetura que podem ser testados isoladamente, mesmo na nuvem. Um exemplo é uma função do Lambda que recebe entradas, processa os dados e envia uma mensagem para uma fila do Amazon SQS. Um teste unitário dessa função provavelmente testaria se os valores de entrada resultariam na presença de determinados valores na mensagem colocada em fila.
Considere um teste escrito usando o padrão Organizar, Agir, Declarar:
-
Organizar: aloque recursos (uma fila para receber mensagens e a função em teste).
-
Agir: chame a função em teste.
-
Declarar: recupere a mensagem enviada pela função e valide a saída.
Uma abordagem de teste de simulação consistiria em simular a fila com um objeto simulado em andamento e em criar uma instância em andamento da classe ou do módulo que conteria o código da função do Lambda. Durante a fase Declarar, a mensagem colocada em fila seria recuperada do objeto simulado.
Em uma abordagem baseada em nuvem, o teste criaria uma fila do Amazon SQS para fins do teste e implantaria a função do Lambda com variáveis de ambiente configuradas para usar a fila isolada do Amazon SQS como destino de saída. Depois de executar a função do Lambda, o teste recuperaria a mensagem da fila do Amazon SQS.
O teste baseado em nuvem executaria o mesmo código, declararia o mesmo comportamento e validaria a correção funcional da aplicação. No entanto, ele teria a vantagem adicional de poder validar as configurações da função do Lambda: o perfil do IAM, as políticas do IAM e as configurações de tempo limite e memória da função.
Próximas etapas e recursos
Use os recursos a seguir para saber mais e explore os exemplos práticos dos testes.
Exemplos de implementações
O repositório de exemplos de testes com tecnologia sem servidor
Outras fontes de leitura
Visite o Serverless Land
A leitura das seguintes publicações do blog da AWS também é recomendada:
-
Acelerar o desenvolvimento com tecnologia sem servidor com o AWS SAM Accelerate
(publicação do blog da AWS) -
Aumentar a velocidade do desenvolvimento com o CDK Watch
(publicação no blog da AWS) -
Simular integrações de serviços com o AWS Step Functions Local
(publicação no blog da AWS) -
Conceitos básicos dos testes de aplicações com tecnologia sem servidor
(publicação no blog da AWS)
Ferramentas