Alura > Cursos de Programação > Cursos de Automação e Produtividade > Conteúdos de Automação e Produtividade > Primeiras aulas do curso n8n para devs: Automatizando testes e integrando IA ao fluxo de trabalho

n8n para devs: Automatizando testes e integrando IA ao fluxo de trabalho

Planejamento de testes - Apresentação

Apresentando o instrutor e o curso

Bem-vindos ao curso da Alura de N8n para Desenvolvedores. Meu nome é Ricardo Bugan, sou responsável pela Rede Operacional e Rede de Produto, além de ser formado em desenvolvimento. Serei o instrutor deste curso.

Audiodescrição: Ricardo é um homem branco, com cabelo curto castanho e olhos castanhos. Ele veste uma camisa azul e está em um ambiente de escritório, com uma parede clara ao fundo e uma estante com livros à sua direita.

Explorando o N8n e sua integração com LLMs

Neste curso, continuaremos explorando o N8n, trazendo mais ferramentas para o nosso dia a dia. Nosso objetivo é compreender como essa ferramenta de automação funciona e como podemos integrá-la de maneira mais eficaz com os LLMs, os modelos de linguagem natural generativos, para que eles nos ajudem a resolver problemas cotidianos.

Trabalharemos com o modelo de linguagem utilizando um VectorStore (armazenamento vetorial), o que nos permitirá fornecer mais contexto para a inteligência artificial. Também entenderemos a importância de fornecer o contexto completo e específico da nossa aplicação para a IA.

Manipulando dados e utilizando agentes de IA

Vamos trabalhar com outros nós dentro do N8n para gestão de fluxo e transformação de dados, manipulando dados de maneira semelhante ao que fazemos em código, mas utilizando ferramentas e métodos diferentes. Além disso, vamos trabalhar com o agente de IA, fornecendo as ferramentas necessárias para que ele tome decisões e alcance o objetivo definido por meio de um prompt.

Criando e mantendo prompts para automação

Falando em prompt, teremos alguns para a criação de testes que utilizaremos durante o curso. Esses testes serão integrados com tudo o que já temos, incluindo versionamento e manutenção, cuidando desse prompt como uma peça de software que estamos utilizando. Pensaremos no futuro, considerando como manter um prompt a longo prazo, especialmente em projetos de automação, onde ele precisará ser executado e chamado constantemente. Vamos explorar maneiras de facilitar nosso dia a dia, organizando os prompts de forma que entendamos e simplifiquemos a manutenção e o trabalho em equipe.

Trabalhando com funções no N8n

Também veremos como trabalhar com funções dentro do N8n. Vamos criar uma função separada para reduzir a complexidade do nosso fluxo principal. O curso está repleto de conteúdo, e esperamos que você goste.

Planejamento de testes - Relembrando o papel dos testes

Introduzindo a importância dos testes de software

Para começar o nosso curso, vamos relembrar a base sobre a qual trabalharemos, fornecendo um plano de fundo para o nosso aprendizado. Vamos explorar o n8n e entrar na parte de automação, mas inicialmente, vamos recordar a importância dos testes de software, que servirão como base para o nosso curso.

Quando criamos um software ou sistema, independentemente de qual seja, precisamos testá-lo, seja de maneira manual ou automatizada através de código. O objetivo dos testes é garantir a qualidade e provar que o sistema não possui erros. Além disso, queremos validar que o software, conforme está escrito, não apresenta falhas. O código deve não apenas rodar, compilar e funcionar, mas também operar conforme especificado, atendendo às especificações funcionais e não funcionais. Precisamos verificar se a regra de negócio que o software deveria atender está sendo cumprida corretamente, se o número de requisições por minuto ou por segundo que ele deveria suportar está sendo alcançado e se as regras de segurança estão sendo respeitadas.

Explorando os tipos de testes e suas funções

Os testes nos ajudam a garantir essa qualidade e aumentam a confiança e a confiabilidade do software que estamos entregando. Quando o entregamos para produção, podemos afirmar que ele foi testado e está funcionando conforme o esperado. No entanto, enfrentamos um desafio: os testes, especialmente os automatizados, representam mais um sistema, uma arquitetura e um projeto de código que precisamos manter. Por outro lado, os testes manuais são lentos, exigindo a repetição constante das mesmas tarefas e testes. Idealmente, o teste manual deveria ser o mínimo possível, mas em alguns casos, ainda será necessário. Portanto, precisamos de um sistema de código para realizar os testes, mas isso representa mais um sistema para mantermos.

Dentro desse sistema, encontramos a famosa pirâmide dos testes. A maioria dos testes nesse novo sistema será de unidade, focando nas menores partes do sistema, como funcionalidades individuais e o código em si. Aqui, falamos de teste de caixa branca, que se diferencia do teste de caixa preta. Nos testes de unidade, analisamos especificamente uma função, classe, código ou módulo, testando aquela unidade do nosso código.

Detalhando os testes de integração e end-to-end

Em seguida, temos os testes de integração, que garantem que um módulo, classe ou função está bem integrado com outras partes do mesmo sistema. Por fim, temos os testes de end-to-end (de ponta a ponta), que abrangem toda a stack do sistema. Esses testes percorrem todos os módulos, focando em regras de negócio, como verificar se uma rota de API está funcionando conforme esperado. Testamos a rota completa, incluindo o banco de dados, para garantir que tudo está funcionando de ponta a ponta. No entanto, esses testes são mais lentos, por isso, geralmente, temos uma quantidade menor deles em comparação com os testes de integração e, certamente, com os testes de unidade.

No final, o que deveria ser uma menor quantidade, e que deveríamos evitar ao máximo, são os testes manuais. Em alguns casos, vamos precisar deles, especialmente em situações muito complexas de automação ou em testes que ainda não conseguimos automatizar por falta de tempo. Nesses casos, recorremos aos testes manuais. Idealmente, deveríamos ter zero ou o mínimo possível de testes manuais, pois não é viável testar manualmente o sistema o tempo todo.

Decidindo quando criar testes

Diante disso, surge a questão: quando devemos criar nossos testes? Quando devemos produzir esse código adicional para testar o sistema que estamos desenvolvendo? No ambiente de desenvolvimento, podemos optar por desenvolver o teste antes, criando primeiro o código do teste para depois desenvolver o código do sistema. Isso é conhecido como TDD (Test-Driven Development, ou Desenvolvimento Guiado por Testes). Alternativamente, podemos criar os testes depois, o que é chamado de test after. Essa nomenclatura pode ser encontrada de duas maneiras: test before e test after, ou TDD no caso do test before. Ambas significam o momento em que estamos criando o teste.

No test after, desenvolvemos primeiro o sistema, implementamos a funcionalidade solicitada e, em seguida, criamos os testes. Neste curso, trabalharemos com a ideia de test after. Partiremos do princípio de que a funcionalidade já está desenvolvida e, então, criaremos os testes para ela. Se utilizarmos TDD, poderíamos aplicar a mesma ideia que vamos trabalhar no curso, ajustando algumas etapas do processo. No entanto, aqui, vamos focar na ideia de testar depois que a funcionalidade já está pronta.

Planejando a criação do ambiente de testes

Para começar a pensar em como criar o ambiente de testes, já que nossa intenção é automatizar todo esse processo, precisamos implementar uma matriz de implementação. Essa matriz é uma tabela grande, onde cada linha representa um teste. As colunas contêm os detalhes de cada teste, como a funcionalidade que estamos testando, o cenário de teste, o tipo de teste (funcional, regra de negócio, validação, resiliência), o nível (integração, unitário, end to end), a prioridade (alto ou baixo impacto no negócio, alto risco) e o status.

Se estivermos trabalhando com ferramentas como Kanban, Trello, PipeFile ou ClickUp, cada linha dessa matriz pode se tornar um cartão, com um status indicando seu progresso, como "em desenvolvimento". Essa matriz de implementação conterá nossos casos de teste e tudo o que vamos testar.

A primeira etapa é começar a configurar o N8n para nos ajudar a montar essa tabela. Nosso papel durante este curso será automatizar o fluxo de geração dessa matriz de implementação, escrever o código e colocá-lo no GitHub. Portanto, a primeira etapa é o planejamento, que na fase dos testes envolve a criação dessa matriz de implementação.

Planejamento de testes - Montando o planejamento

Retornando ao projeto de automação no N8n

Para implementar nossa matriz de automação no N8n, retornamos ao projeto do nosso time de desenvolvimento, onde trabalhamos no curso anterior. Nesse projeto, exploramos o básico do N8n, incluindo funções, gatilhos e alguns nós interessantes para montar fluxos e realizar automações básicas. Utilizamos integrações com GitHub, Data Table, Trello, Slack e e-mail, além de código dentro do N8n. Agora, estamos no mesmo ambiente e projeto, com credenciais já configuradas, incluindo a do OpenAI, que usaremos para demonstrar diferenças em relação ao Gemini.

Vamos iniciar um novo workflow, pois trabalharemos com um cenário diferente: a criação de testes, em vez da validação de pull requests (PRs) do time. Utilizaremos o mesmo gatilho, que é a criação de um PR no GitHub. Estamos usando uma API de e-commerce em Node.js com Express, que já possui módulos como autorização, carrinho, autenticação, categorias, pedidos, pagamento, produto e usuário. Estamos adicionando uma funcionalidade de cupom de desconto a esse sistema.

Configurando o workflow de automação

Para criar testes ou a matriz de implementação, configuraremos nosso workflow de automação. O gatilho será a criação de um PR, como usamos anteriormente. No GitHub, ao criar um novo PR, esperamos que o N8n fique ouvindo e nos forneça uma resposta. Vamos fixar essa informação, pois ela disparará nossa automação. Para cada novo PR, queremos que isso ocorra automaticamente. Nomearemos este workflow como "criação de testes do projeto", para que possamos trabalhar nele sempre que quisermos criar ou modificar testes.

Com o GitHub configurado, passaremos a informação adiante para criar nossa matriz de implementação. Queremos automatizar tudo, e a matriz de implementação é um planejamento inicial dos testes. Utilizaremos uma IA generativa, como o ChatGPT, para auxiliar na criação desse plano. O próximo nó será um nó de IA, usando o OpenAI para enviar uma mensagem de texto, pois não precisamos de imagem, áudio ou arquivo.

Utilizando IA para criar a matriz de implementação

Nossa conta já está configurada, mas, se necessário, basta criar uma chave de API no ChatGPT e trazê-la para cá. Vamos trabalhar com recurso de texto, enviando uma mensagem para o modelo e esperando uma resposta. Usaremos o modelo 5.1, que é básico para responder texto, não para criação de código. Para isso, o OpenAI tem o Codecs, específico para código.

Enviaremos uma mensagem de texto para um usuário, assistente ou sistema. Como assistente, adotaremos um perfil específico. Temos um prompt pronto, que define o assistente como um engenheiro de software especializado em testes automatizados para um sistema Node com Express, focado em estratégia de teste e análise de risco. Queremos que ele receba um diff do código do GitHub, analise as mudanças e gere exclusivamente a matriz de implementação de testes, com regras claras para não gerar código ou exemplos.

Definindo o contexto e o prompt

Para isso, utilizamos o seguinte contexto:

{
    "type": "object",
    "properties": {
        "message": {
            "type": "string"
        }
    },
    "additionalProperties": false,
    "required": ["message"]
}

O prompt detalha o escopo de análise, incluindo novas funções, métodos, alterações de regras de negócio, fluxos condicionais, tratamento de erro e validação de entrada. Para criar um bom prompt, é necessário conhecer o sistema e a área em questão. Para cada item relevante, queremos descrição do comportamento, cenários positivos e negativos, edge cases, tipo e nível de teste apropriado, e a matriz de implementação com ID do teste, arquivo, mudança do diff, comportamento esperado, cenário de teste, tipo de teste, prioridade e observações.

O tipo de teste será funcional, regra de negócio, validação, e o nível será unitário, integração, contrato, com prioridade alta, média ou baixa. Ajustamos o prompt para que o nível de teste seja tratado como tipo de teste. Copiaremos o prompt como assistente, mas dividiremos em duas mensagens: uma como assistente e outra como usuário, para passar o contexto e, em seguida, a tarefa de análise do diff.

Configurando o esquema de saída

Vamos substituir a variável do GIF pelo URL do GIF que está no canto, proveniente do nosso input e do nosso PR, passando para ele esse contexto. Estamos utilizando dois tipos de input: um para o assistente e outro para a pessoa usuária, solicitando que ele realize algumas tarefas.

Além disso, para facilitar nosso trabalho no futuro, desejamos uma matriz de implementação que nos indique quais testes devem ser criados, por que devem ser criados e como devem ser feitos. Para tratar isso na automação, será mais fácil se utilizarmos algo estruturado. Assim como no curso anterior, pedimos para o Gemini responder em formato JSON, indicando se foi aprovado ou reprovado, com um comentário. Queremos fazer o mesmo aqui, mas o Chat GPT, da OpenAI, já nos oferece essa opção.

Criando o esquema JSON para a matriz

Nas opções, temos o formato de Output ou Output Format. Ele nos mostra como configurar esse esquema de saída. O JSON esquema é o recomendado e é o que vamos usar para configurar nossa saída. Basicamente, ele será um objeto JSON que define o tipo e as propriedades dentro desse bloco configurado. Por padrão, ele vem com uma mensagem do tipo String. A chave é o nome que queremos, mas é definida por um objeto com alguns parâmetros.

Precisamos trocar o conteúdo do objeto propriedades para o que desejamos. Para facilitar, temos um arquivo separado pronto para copiar e colar. Dentro das propriedades que queremos, ele deve gerar um nome para o teste e a matriz. O nome é apenas para facilitar a comunicação. A matriz será do tipo Array, e podemos definir os itens dentro dela. Cada item será do tipo Objeto, com suas próprias propriedades.

Definindo propriedades e requisitos do esquema

Definimos nosso esquema com propriedades de alto nível, respondendo com o nome e a matriz. O nome é do tipo String, a matriz é do tipo Array, e cada item da matriz é um objeto com propriedades como ID, arquivo ou módulo, mudança no Diff, comportamento esperado, tipo de teste, cenário de teste e observações. O nível foi removido.

O esquema que queremos está definido, e também incluímos o que é requerido. A propriedade required é obrigatória e deve incluir todas as chaves do Array. No caso do nível, foi removido, mas a observação deve ser adicionada. Todas as chaves das propriedades do item devem estar no required. Um item tem o tipo, as propriedades e o que é requerido. Também é necessário definir se há propriedades adicionais, com verdadeiro ou falso. No nosso caso, é falso.

Executando e ajustando o esquema

Vamos copiar esse esquema, sem incluir properties e as chaves de abertura e fechamento, pois já estão no nosso texto no N8n. Podemos ver a matriz do tipo array com os itens, cada um do tipo objeto, com propriedades e requisitos. Podemos organizar os espaços e definir se há propriedades adicionais.

Se observarmos mais abaixo, temos propriedades adicionais, falso, required, mensagem. Tudo que for declarado como type object precisa dessas propriedades, tanto do required quanto das propriedades adicionais. No nosso novo esquema, temos o nome e a matriz, que precisam ser incluídos no required.

Ao executar, pode ocorrer um erro indicando que o input text não é suportado, devendo ser do tipo output text. Isso ocorre devido ao tipo de role. Alteramos para user, e agora ele mudou a mensagem, indicando que o esquema é inválido. No contexto, ele menciona que o required deve incluir todas as chaves, como o nome e a matriz.

Processando a matriz de implementação de testes

Configurar esse esquema pode ser complicado e detalhado, mas a API fornece respostas e orientações. Ao executar, esperamos que a saída esteja no formato desejado. Mesmo que as mensagens estejam separadas em duas, ambas são do tipo user, podendo ser unidas sem problemas, já que não conseguimos usar o tipo de role assistente.

A execução pode demorar, mas esperamos que a saída esteja no formato desejado. O output gerado inclui o ID da mensagem, tipo mensagem, status completo e conteúdo. O conteúdo traz o texto, nome, matriz de implementação de testes e PR. Ele criou o nome e analisou o contexto enviado, facilitando a comunicação e registro em log.

A matriz inclui o ID, módulo, mudança, comportamento esperado, tipo de teste, cenário de teste e observações. O planejamento para o teste está definido, com cenários de teste criados. Vamos tratar essa implementação e planejamento para criar os testes usando o N8n.

Utilizando código para manipular a matriz

Para processar a matriz de implementação de testes, utilizamos o seguinte código:

const { matriz } = JSON.parse($input.item.json.text);
const items = [];
for (const item of matriz) {
  const newItem = {
    json: item
  };
  items.push(newItem);
}
return items;

Esse código extrai a matriz de implementação de testes do JSON de entrada, itera sobre cada item da matriz, cria um novo objeto newItem para cada item, e finalmente retorna todos os itens processados. Isso nos permite manipular e utilizar a matriz de forma estruturada dentro do N8n.

Sobre o curso n8n para devs: Automatizando testes e integrando IA ao fluxo de trabalho

O curso n8n para devs: Automatizando testes e integrando IA ao fluxo de trabalho possui 192 minutos de vídeos, em um total de 39 atividades. Gostou? Conheça nossos outros cursos de Automação e Produtividade em Programação, ou leia nossos artigos de Programação.

Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:

Aprenda Automação e Produtividade acessando integralmente esse e outros cursos, comece hoje!

Conheça os Planos para Empresas