EventoObtenha 50% de desconto no seu ingresso para MongoDB.local Londres em outubro 2. Use o código WEB50Saiba mais >>
Desenvolvedor MongoDB
Central de desenvolvedor do MongoDBchevron-right
Produtoschevron-right
Atlaschevron-right

Como escrever testes de unidade para MongoDB Atlas Functions

Lauren Schaefer10 min read • Published Jan 28, 2022 • Updated Sep 09, 2024
Sem servidorAtlasJavaScript
Ícone do FacebookÍcone do Twitterícone do linkedin
Avalie esse Tutorial
star-empty
star-empty
star-empty
star-empty
star-empty
Some features mentioned below will be deprecated on Sep. 30, 2025. Learn more.
I recently built a web app for my team using Atlas Functions. I wanted to be able to iterate quickly and frequently deploy my changes. To do so, I needed to implement DevOps infrastructure that included a strong foundation of test automation. Unfortunately, I didn't know how to do any of that for apps built using Atlas Functions.
Nesta série, guiarei você pelo que descobrir. Mostrarei como você pode criar um conjunto de testes automatizados e um pipeline deCI/CD para aplicativos da web criados em funções sem servidor.
Hoje, explicarei como você pode escrever testes de unidade automatizados para Atlas Functions. Abaixo está um resumo do que abordaremos:
Prefere aprender por vídeo? Muitos dos conceitos que abordo nesta série estão disponíveis neste vídeo.

Sobre o aplicativo de estatísticas sociais

Antes de falar sobre como testei meu aplicativo, quero dar a você um pouco de informações sobre o que o aplicativo faz e como ele é construído.
Meu time e eu precisvamos de uma maneira de acompanhar nossas estatísticas do Twitter juntos.
O Twitter oferece uma maneira de seus usuários baixarem estatísticas do Twitter. O download é um arquivo de valores separados por vírgula (CSV) que contém uma linha de estatísticas para cada Tuíte. Se você quiser experimentar, navegue até https://analytics.facebook.com/user/insert_ your_username_here/tweets e opte por exportar seus dados por Tuíte.
Depois que meus colegas de equipe e eu baixamos nossas estatísticas de Tweets, precisávamos de uma maneira de combinar regularmente nossas estatísticas sem duplicar dados de arquivos CSV anteriores. Então, decidiu construir um aplicativo da web.
O aplicativo é muito leve e, para ser completamente verdadeiro, muito feia. Atualmente, o aplicativo consiste em duas páginas.
A primeira página permite que qualquer pessoa da nossa equipe carregue seu arquivo CSV de estatísticas do Twitter.
A segunda página é um dashboard onde podemos fatiar e cortar nossos dados. Qualquer pessoa da nossa equipe pode acessar o painel para extrair estatísticas individuais ou obter estatísticas combinadas. O dashboard é útil tanto para meus membros de equipe quanto para nossa cadeia de gerenciamento.

Arquitetura do aplicativo

Vamos dar uma olhada em como arquitetei esse aplicativo, para que possamos entender como o testei.

Arquitetura sem servidor e Atlas

O aplicativo é construído usando uma arquitetura sem servidor. O termo "sem servidor" pode ser um pouco enganoso. Sem servidor não significa que o aplicativo não usa servidores. Sem servidor significa que os desenvolvedores não precisam gerenciar os próprios servidores. (Essa é uma grande vitória no meu livro!)
Quando você usa uma arquitetura sem servidor, você escreve o código para uma função. O provedor de nuvem lida com a execução da função em seus próprios servidores sempre que a função precisa ser executada.
As arquiteturas serverless têm grandes vantagens em relação às aplicações tradicionais e monolíticas:
  • Concentre-se no que importa. Os desenvolvedores não precisam se preocupar com servidores, contêineres ou infraestrutura. Em vez disso, podemos nos concentrar no código do aplicativo, o que pode levar a um tempo de desenvolvimento reduzido e/ou mais inovação.
  • Pague apenas pelo que você usar. Em arquiteturas sem servidor, você normalmente paga pelo poder de computação que usa e pelos dados que está transferindo. Normalmente, você não paga pelos servidores quando eles estão ociosos. Isso pode resultar em grandes economias de custos.
  • Escale facilmente. O fornecedor de nuvem lida com o dimensionamento de suas funções. Se o seu aplicativo se tornar um sucesso, as equipes de desenvolvimento e operações não precisam se preocupar.
Como nunca fui fã de gerenciar infraestrutura, decidi criar o aplicativo Social Stats usando uma arquitetura sem servidor.
O MongoDB Atlas oferece vários serviços de cloud sem servidor - incluindo MongoDB Atlas Data API, Atlas GraphQL API e MongoDB Atlas Triggers - que facilitam a criação de aplicativos sem servidor.

Arquitetura de estatísticas sociais

Vamos dar uma olhada em como o aplicativo Social Stats é arquitetado. Abaixo está um diagrama de fluxo de como as partes do aplicativo funcionam juntas.
Quando um usuário deseja carregar seu arquivo CSV de estatísticas do Twitter, ele navega para index.html em seu navegador. index.html pode ser hospedado em qualquer lugar. Ops por hospedar index.html usando oStatic Hosting. Curto a simplicidade de manter meus arquivos hospedados e funções sem servidor em um projeto hospedado em uma plataforma.
Quando um usuário opta por carregar seu arquivo CSV de estatísticas do Twitter,index.html codifica o arquivo CSV e o passa para a Atlas FunctionprocessCSVdo Atlas.
A processCSV função decodifica o CSV e passa os resultados para a storeCsvInDb Atlas Function .
A funçãostoreCsvInDb chama a Atlas Function removeBreakingCharacters que remove qualquer emophyllum ou outros caracteres de quebra dos dados. Em seguida, a funçãostoreCsvInDb converte os dados limpos em documentosJSON (JavaScript Object Notation) e armazena esses documentos em um MongoDB database hospedado pelo Atlas.
Os resultados do armazenamento dos dados no banco de dados são transmitidos pela cadeia de funções.
O dashboard que exibe os gráficos com as estatísticas do Twitter é hospedado pelo MongoDB Charts. O melhor desse dashboard é que não precisei fazer nenhuma programação para criá-lo. Concedi acesso ao Charts ao meu banco de dados e, em seguida, usei a interface do usuário do Charts para criar gráficos com filtros personalizáveis.
(Nota: vincular a um painel completo do Atlas Charts funcionou bem para o meu aplicativo, mas sei que nem sempre é o ideal. O Atlas Charts também permite que você incorpore gráficos individuais em seu aplicativo por meio de um iframe ou SDK.)

Testes de unidade para funções do Atlas

Agora que expliquei o que tinha que testar, vamos explorar como testei. Hoje, falaremos sobre os testes que formam a base da Pirâmide de testes:testes de unidade.
Os testes de unidade são projetados para testar as pequenas unidades do seu aplicativo. Nesse caso, as unidades que queremos testar são funções sem servidor. Os testes de unidade devem ter uma entrada e saída claras. Eles não devem testar como as unidades interagem umas com as outras.
Os testes de unidade são valiosos porque:
  1. Normalmente são mais rápidos de escrever do que outros testes automatizados.
  2. Podem ser executados de forma rápida e independente, pois não dependem de outras integrações e sistemas.
  3. Revele bugs no início do ciclo de vida de desenvolvimento de software, quando é mais barato corrigi-los.
  4. Dê aos desenvolvedores a confiança de que não estamos introduzindo regressões à medida que atualizamos e refatoramos outras partes do código.
Existem muitas frameworks de teste JavaScript.Ops por usar oJest para criar meus testes de unidade, pois é uma escolha popular na comunidade JavaScript. Os exemplos abaixo usam o Jest, mas você pode aplicar os princípios descritos nos exemplos abaixo a qualquer framework de testes.

Modificando funções do Atlas para serem testáveis

Cada Atlas Function atribui uma função para a variável global exports. Abaixo está o código de uma função boilerplate que retorna "Hello, world!"
Esse formato de função é problemático para testes de unidade: chamar essa função de outro arquivo JavaScript é impossível.
Para contornar esse problema, podemos adicionar as três linhas a seguir à parte inferior dos arquivos de origem da função:
Vamos detalhar o que está acontecer aqui. Se o tipo do módulo forobject, a função está sendo executada fora de um ambiente Atlas, portanto, precisamos atribuir nossa função (armazenada em exports) a module.exports. Se o tipo do módulo não for um object, podemos presumir com segurança que a função está sendo executada em um ambiente Atlas, portanto não precisamos fazer nada de especial.
Depois de adicionarmos essas três linhas às nossas funções sem servidor, estamos prontos para começar a escrever testes de unidade.

Funções autônomas de teste de unidade

As funções de teste de unidade são mais fáceis quando as funções são independentes, o que significa que as funções não chamam nenhuma outra função nem utilizam nenhum serviço, como um banco de dados. Então, vamos começar por aqui.
Vamos começar testando a funçãoremoveBreakingCharacters. Esta função remove emojis e outros caracteres de quebra das estatísticas do Twitter. Abaixo está o código-fonte da funçãoremoveBreakingCharacters.
Para testar esta função, criei um novo arquivo de teste denominado removeBreakingCharacters.test.js. Comece importando afunçãoremoveBreakingCharacters.
Em seguida, importe várias constantes de constantes.js. Cada constante representa uma linha de dados em um arquivo CSV de estatísticas do Twitter.
Então eu estava pronto para começar a testar. Comece com o caso mais simples: um único Tuíte válido.
O teste SingleValidTweetcria uma constante chamadacsv. csv é uma combinação de um cabeçalho válido, um novo caractere de linha e um Tweet válido. Como o Tweet é válido, removeBreakingCharacters não deve remover nenhum caractere. O teste verifica se, quando csv é passado para a funçãoremoveBreakingCharacters, a função retorna uma string igual a csv.
Os Emojis eram um grande problema que estavam quebrando meu aplicativo, então decidimos criar um teste só para eles.
O testeEmojiTweet cria duas constantes:
  • csvBefore armazena um cabeçalho válido, um novo caractere de linha e estatísticas sobre um Tweet que contém três emojis.
  • csvAfter armazena o mesmo cabeçalho válido, um novo caractere de linha e estatísticas sobre o mesmo Tweet, exceto que os três emojis foram removidos.
O teste então verifica se quando passo a constante csvBeforepara a funçãoremoveBreakingCharacters, a função retorna uma String igual a csvAfter.
Criei outros testes de unidade para a funçãoremoveBreakingCharacters. Você pode encontrar o conjunto completo de testes de unidade em removeBreakingChaacters.test.js.

Testes de unidade para funções usando mocks

Infelizmente, o teste de unidade da maioria das funções sem servidor não será tão simples quanto o exemplo acima. As funções sem servidor tendem a depender de outras funções e serviços.
O objetivo do teste de unidade é testar unidades individuais, não como as unidades interagem umas com as outras.
Quando uma função depende de outra função ou serviço, podemos simular a função ou serviço com um objeto de simulação. Objetos de simulação permitem que os desenvolvedores "simulem" o que uma função ou serviço está fazendo. As simulações nos permitem testar unidades individuais.
Vamos dar uma olhada em como testei a funçãostoreCsvInDb. Abaixo está o código-fonte da função.
Em um nível elevado, a funçãostoreCsvInDbestá fazendo o seguinte:
  • Chamada da funçãoremoveBreakingCharacterspara remover caracteres de quebra.
  • Convertendo os Tuítes nos documentos CSV para JSON.
  • Percorrendo os documentos JSON para limpar e armazenar cada um no banco de dados.
  • Retornar um objeto que contém uma lista de Tweets que foram inseridos, atualizados ou que não puderam ser inseridos ou atualizados.
Para testar esta função, criei um novo arquivo chamado storeCsvInDB.test.js. O topo do arquivo é muito semelhante ao topo de removeBreakingCharacters.test.js: importei a função que queria testar e importei constantes.
Em seguida, comecei a criar simulações. A função interage com o banco de dados, portanto, eu sabia que precisava criar simulações para dar suporte a essas interações. A função também chama a funçãoremoveBreakingCharacters, então criei um mock para ela também.
Adicionei o seguinte código a storeCsvInDB.test.js.
Jest executa a funçãobeforeEach antes de cada teste no arquivo fornecido. Optei por colocar a instanciação das simulações dentro de beforeEach para que eu pudesse adicionar verificações de quantas vezes uma determinada simulação é chamada em um determinado caso de teste. Colocar simulações dentro de beforeEach também pode ser útil quando queremos alterar o que a simulação retorna na primeira vez que é chamada em comparação com a segunda.
Depois de criar minhas simulações, eu estava pronto para começar a testar. Eu criei um teste para o caso mais simples: um único tweet.
Vamos ver o que esse teste está fazendo.
Assim como vimos nos testes anteriores deste post, comecei criando uma constante para representar os Tweets CSV. csvTweets consiste em um cabeçalho válido, um caractere de nova linha e um Tweet válido.
O teste então chama a funçãostoreCsvInDb, passando a constantecsvTweets . O teste afirma que a função retorna um objeto que mostra que o Tuíte que passamos foi armazenado com sucesso no banco de dados.
Em seguida, o teste verifica se a simulação da função removeBreakingCharacters foi chamada com nossa constantecsvTweets .
Por fim, o teste verifica se a funçãoupdateOnedo banco de dados foi chamada com os argumentos que esperávamos.
Depois de concluir esse teste unitário, escrevi um teste adicional que verifica se a funçãostoreCsvInDblida corretamente com vários Tweets.
Você pode encontrar o conjunto completo de testes de unidade em storeCsvInDB.test.js.

Encerrando

Os testes unitários podem ser extremamente valiosos. Eles são uma das melhores maneiras de encontrar bugs no início do ciclo de vida de desenvolvimento de software. Eles também estabelecem uma base sólida para CI/CD.
Tenha em mente as duas dicas a seguir ao escrever testes de unidade para o Atlas Functions:
  • Modifique as exportações do módulo no arquivo de origem de cada função, para que você possa chamar as funções dos seus arquivos de teste.
  • Use simulações para simular interações com outras funções, bancos de dados e outros serviços.
O código-fonte do aplicativo Social Stats e os arquivos de teste associados estão disponíveis em um repositório do GitHub: https://github.com/mongodb-developer/SocialStats. O readme do repositório contém instruções detalhadas sobre como executar os arquivos de teste.
Fique atento à próxima publicação desta série, em que mostrarei como escrever testes de integração para aplicativos sem servidor.
Confira os seguintes recursos para obter mais informações:

Ícone do FacebookÍcone do Twitterícone do linkedin
Avalie esse Tutorial
star-empty
star-empty
star-empty
star-empty
star-empty
Relacionado
Exemplo de código

Final Space API


Jul 07, 2022 | 1 min read
Tutorial

Um exercício prático do Atlas Device SDK para web com sincronização (visualização)


May 16, 2024 | 21 min read
Tutorial

Como criar um sistema RAG com LlamaIndex, OpenAI e MongoDB Vector Database


Feb 16, 2024 | 10 min read
exemplo de código

EHRS-Peru


Sep 11, 2024 | 3 min read
Sumário