1. Introdução
Este codelab apresenta os princípios do desenvolvimento orientado a testes ( TDD, na sigla em inglês), em que você escreve testes antes de implementar o código. Criaremos um aplicativo de calculadora simples com o Ruby demonstrando essa abordagem.
Você também vai aprender a usar o Gemini, seu assistente de programação. O Gemini vai ajudar a acelerar o ciclo de TDD gerando casos de teste, sugerindo implementações e até mesmo fornecendo explicações sobre o código.
Por fim, você vai aprender a implantar o app de calculadora no Cloud Functions, a plataforma sem servidor totalmente gerenciada do Google para tornar seu app acessível.
2. Pré-requisitos
- Um projeto do Google Cloud com o faturamento ativado
- Um navegador da Web
Criar seu projeto
- No console do Google Cloud, na página de seletor de projetos, selecione ou crie um projeto do Google Cloud.
- Verifique se o faturamento está ativado no seu projeto do Cloud. Saiba como verificar se o faturamento está ativado em um projeto.
Ativar a API Gemini
- Acesse o Gemini Marketplace para ativar a API. Também é possível usar a gcloud para ativar a API:
gcloud services enable cloudaicompanion.googleapis.com --project PROJECT_ID
- Acesse a página do Gemini e clique em "Iniciar conversa".
- Importante: siga as etapas 1 e 2 deste codelab para começar a usar o Gemini e ativar o Gemini no ambiente de desenvolvimento integrado do Cloud Shell, respectivamente.
Ativar a API Cloud Functions
- No console do Google Cloud, na página de seletor de projetos, selecione ou crie um projeto do Google Cloud.
- Acesse a página da API Cloud Functions para ativar a API. Também é possível usar a gcloud para ativar a API:
gcloud services enable cloudfunctions.googleapis.com --project PROJECT_ID
Ativar o Cloud Shell
- Você vai usar o Cloud Shell, um ambiente de linha de comando em execução no console do Google Cloud que vem pré-carregado com as linguagens necessárias instaladas. No console do Cloud, clique em Ativar o Cloud Shell no canto superior direito:
- Depois de se conectar ao Cloud Shell, sua conta já está autenticada e o projeto está configurado com o ID do seu projeto. Execute o seguinte comando no Cloud Shell para confirmar se você está autenticado:
gcloud auth list
- Execute o seguinte comando no Cloud Shell para confirmar que o comando gcloud sabe sobre seu projeto:
gcloud config list project
- Se o projeto não estiver definido, use este comando:
gcloud config set project <YOUR_PROJECT_ID>
Consulte a documentação para ver o uso e os comandos gcloud.
Abrir editor
- Neste codelab, vamos usar o editor integrado do Cloud. Na janela do Cloud Shell, clique no botão "Abrir editor" no canto superior direito. Isso vai abrir um editor do VSCode para você.
Adicionar extensão Ruby
- No menu do lado esquerdo, clique no ícone de extensões , escreva
vscode ruby
na barra de pesquisa e instale a extensão Ruby do VSCode.
3. Aquecimento para Gemini
LLMs não são determinísticos. Portanto, ao testar esses comandos, a resposta recebida pode ser diferente das capturas de tela anexadas no codelab.
Primeiro, vamos perguntar ao Gemini o que é um TDD. Para começar a conversar com o Gemini no mesmo editor do Cloud Shell em que estamos, siga estas etapas:
- No lado esquerdo da página, localize o ícone do Gemini . Isso vai abrir a janela de chat à esquerda.
- Comece a digitar na caixa de texto
Enter a prompt here
Comando:
What is Test Driven Development?
Resposta:
Test-driven development (TDD) is a software development methodology that requires developers to write automated tests before writing any production code. This helps ensure the code is correct and meets the requirement. ....
Ele apresenta uma breve introdução ao TDD e seus benefícios.
Agora vamos perguntar ao Gemini o que é Ruby:
Comando:
What is Ruby?
Resposta:
Ruby is a general-purpose, interpreted, object-oriented programming language. It is designed to be easy to read and write. Ruby is dynamically typed, meaning that the type of a variable is not declared and can change during execution. ....
Ele explica o que é Ruby e quais são os benefícios de usá-lo como linguagem.
4. Configuração do projeto
Agora, vamos começar criando um app Sinatra simples.
- Vamos criar uma pasta vazia. Você pode dar o nome que quiser a ela. Neste codelab, vamos chamá-lo de
gemini-tdd
. No editor de nuvem no lado esquerdo, na guia Explorer, crie a pasta em/home/<YOUR-USERNAME>/
- Vamos abrir a pasta que acabamos de criar. No menu mais à esquerda, clique no ícone e em "Arquivo ->". Abrir pasta.
- Vamos criar um novo arquivo Ruby nesta pasta raiz. Ele servirá como ponto de partida para o aplicativo. Dê o nome que quiser a ele. Neste codelab, vamos chamar de
app.rb
. - Também vamos adicionar um
Gemfile
à pasta raiz. Também é uma boa ideia perguntar ao Gemini sobreGemfile
. - Também criaremos um arquivo
app_test.rb
para programar nossos casos de teste.
5. Implementação orientada pelo Gemini
Agora vamos começar explicando ao Gemini o que estamos tentando fazer e pedir que ele gere casos de teste para isso. Copie o comando a seguir na conversa do Gemini.
Comando:
Answer as a software engineer with Ruby expertise. We want to build a Ruby calculator application with a test driven development approach. Let's start by writing some tests for the calculator app using minitest gem.
Resposta:
Here is a simple test for a calculator app that adds two numbers:
require "minitest/autorun"
describe "Calculator" do
it "should add two numbers" do
calculator = Calculator.new
assert_equal 5, calculator.add(2, 3)
end
end
This test uses the assert_equal method to verify that the result of the add method is correct. .....
Ele fornece um exemplo de caso de teste para o app Calculadora, ou seja, para adicionar dois números. Ele também importou a dependência minitest/autorun
necessária para os testes. Vamos copiar o conteúdo para app_test.rb
. Vamos tentar executar esse teste agora. como não temos nenhum código escrito, ele vai falhar.
Vamos perguntar ao Gemini como fazer esse teste.
Comando:
How do we run the tests written in app_test.rb using ruby command?
Resposta:
To run the tests written in app_test.rb using the ruby command, you can use the following steps: 1.Make sure that you are in the same directory as the app_test.rb file. 2.Open a terminal window. 3.Type the following command:
ruby app_test.rb
This will run all of the tests in the app_test.rb file and report the results.
Então, vamos executar o teste. Na guia Explorer, clique com o botão direito do mouse em app_test.rb
e clique em "Open in Embedded Terminal"
Verifique se você está na mesma pasta que o arquivo app_test.rb. Caso contrário, use o comando cd. No terminal, execute o comando retornado pelo Gemini:
ruby app_test.rb
Você vai encontrar o seguinte erro:
NameError: uninitialized constant Calculator
Vamos perguntar ao Gemini como corrigir isso no editor. Clique no ícone de chat no painel de navegação do editor do Cloud Shell e faça o seguinte comando:
Comando:
NameError: uninitialized constant Calculator. Give me Calculator class code.
Resposta:
The error you are getting is because you have not defined the Calculator class. You need to define the Calculator class before you can use it in your tests. Here is the code for the Calculator class:
Class Calculator
def add(a, b)
a + b
end
end
Once you have defined the Calculator class, you can run the tests again and they will pass. .....
O Gemini está nos dizendo que não temos uma classe chamada Calculator
e que precisamos criar uma. Ela também forneceu o código para criar a classe Calculator
. Vamos usar este código. Abra o app.rb
na guia "Explorador" e copie o código fornecido pelo Gemini. Ao modificar o conteúdo no app.rb, você pode receber algumas sugestões do Gemini como preenchimento automático. pressione tab
se quiser aceitá-lo ou Esc
se não quiser.
Agora, vamos executar o teste novamente. Digite o seguinte comando no terminal integrado:
ruby app_test.rb
No entanto, o mesmo erro "NameError: uninitialized constant Calculator
" ainda será exibido. Vamos perguntar ao Gemini como corrigir isso.
6. TDD iterativo com o Gemini
Comando:
I am still getting this error: "NameError: uninitialized constant Calculator".
Resposta:
The error you are getting is because you have not defined the Calculator class. You need to define the Calculator class before you can use it in your tests. Here is the code for the Calculator class:
class Calculator
def add(a, b)
a + b
end
def subtract(a, b)
a - b
end
def multiply(a, b)
a * b
end
def divide(a, b)
a / b
end
end
....
A resposta pode ser a mesma mostrada acima. Então, vamos informar explicitamente ao Gemini que temos a classe Calculator definida em app.rb .
Comando:
Calculator class is defined in app.rb already.
Resposta:
I see that the Calculator class is defined in the app.rb file. However, you are getting the NameError error because you are trying to use the Calculator class in the app_test.rb file without requiring the app.rb file. To fix this, you need to add the following line to the top of the app_test.rb file:
require_relative "app"
Recebemos a resposta do Gemini para importar o app.rb onde definimos a classe Calculadora. Às vezes, pode levar de 2 a 3 iterações para receber a resposta certa, mas quando você pegar o jeito, vai melhorar. Talvez você também veja require "./app" como resposta do Gemini. Vamos adicionar isso ao app.rb em app_test.rb e executar o mesmo teste novamente.
Verifique se, neste momento, seu app_test.rb está assim:
require "minitest/autorun"
require "./app"
describe "Calculator" do
it "should add two numbers" do
calculator = Calculator.new
assert_equal 5, calculator.add(2, 3)
end
end
Execute o comando abaixo no terminal do Cloud Shell na pasta do projeto:
ruby app_test.rb
Se tudo correr bem, o teste será aprovado. Por isso, desenvolvemos um app Ruby muito simples com a abordagem TDD, e contamos com a ajuda do Gemini. As respostas dos comandos não são sempre as mesmas, e isso é algo que acontece por causa dos modelos LLM. O Gemini pode executar mais operações na calculadora, mas, no geral, o mesmo processo que acabamos de seguir deve funcionar.
7. Implantar o app no Cloud Functions
Agora, vamos pedir que o Gemini implante isso no Cloud Function:
Comando:
Let's deploy this app to Cloud Functions
Resposta:
To deploy your app to Cloud Functions, you can use the following steps: 1.Create a new Cloud Functions project. 2.Create a new Cloud Function. 3.Set the trigger for the Cloud Function to be an HTTP request. 4.Set the entry point for the Cloud Function to be the app method in the app.rb file. 5.Deploy the Cloud Function. Once you have deployed the Cloud Function, you can test it by sending an HTTP request to the function's URL. ....
O Gemini explica como fazer a implantação manual usando a interface do Cloud Functions. Mas não quero fazer isso. Vamos pedir para o Gemini dar o comando gcloud
, que posso executar diretamente do terminal integrado.
Comando:
How do I deploy this app to Cloud Functions gen2 using the gcloud command?
Resposta:
... Here are the specific commands you can use to deploy your app to Cloud Functions using the gcloud command: gcloud functions deploy calculator --runtime ruby32 --trigger-http --entry-point app This command will create a new Cloud Function called calculator that is triggered by an HTTP request and uses the app method in the app.rb file as the entry point. Once the Cloud Function is deployed, you can test it by sending an HTTP request to the function's URL. For example, you can use the following command to send a request to the function: curl -X POST -H "Content-Type: application/json" -d '{"a": 2, "b": 3}' https://REGION-PROJECT_ID.cloudfunctions.net/calculator
Vamos executar o comando gcloud fornecido pelo Gemini no terminal.
gcloud functions deploy calculator --runtime ruby32 --trigger-http --entry-point app
Você vai encontrar o seguinte erro:
"ERROR: (gcloud.functions.deploy) OperationError: code=3, message=Build failed: Could not find Gemfile.lock file in your app. Please make sure your bundle is up to date before deploying.; Error ID: 7916f05c
"
Vamos pedir ajuda do Gemini para corrigir o erro.
Comando:
ERROR: (gcloud.functions.deploy) OperationError: code=3, message=Build failed: Could not find Gemfile.lock file in your app. Please make sure your bundle is up to date before deploying.; Error ID: 7916f05c
Resposta:
It looks like you're trying to deploy a function to Cloud Functions, but you don't have a Gemfile.lock file in your app. To fix this, run the following command in your app directory:
bundle install
This will create a Gemfile.lock file that lists all of the gems that your app uses. ...
Execute bundle install
no terminal, que criará Gemfile.lock
. Depois de executar o comando, verifique a guia "Explorer" e localize Gemfile.lock
.
Vamos tentar implantar no Cloud Functions de novo. Execute o mesmo comando de implantação no terminal:
gcloud functions deploy calculator --runtime ruby32 --trigger-http --entry-point app
Você vai encontrar o seguinte erro:
"ERROR: (gcloud.functions.deploy) OperationError: code=3, message=Build failed: unable to execute functions-framework-ruby; please ensure a recent version of the functions_framework gem is in your Gemfile; Error ID: 89ae7dda
"
8. Functions Framework para Ruby
Vamos perguntar ao Gemini sobre o erro:
Comando:
ERROR: (gcloud.functions.deploy) OperationError: code=3, message=Build failed: unable to execute functions-framework-ruby; please ensure a recent version of the functions_framework gem is in your Gemfile; Error ID: 89ae7dda
Resposta:
It looks like you're trying to deploy a function to Cloud Functions, but the build is failing because the functions_framework gem is not in your Gemfile. To fix this, add the following line to your Gemfile: gem "functions_framework" Then, run the following command to install the gem: bundle install Once the gem is installed, you can try deploying your function again. ....
Basicamente, está faltando a gem functions_framework do nosso app. Agora vamos adicionar esta linha ao Gemfile:
gem "functions_framework"
Agora, execute bundle install
no terminal. Você pode ou não encontrar um erro dizendo "Nenhum recurso global explícito no Gemfile" , Se isso acontecer, verifique se a primeira linha do seu Gemfile é a seguinte:
source "https://rubygems.org"
Em seguida, execute bundle install
no terminal novamente. Agora, execute o comando "deploy" novamente:
gcloud functions deploy calculator --runtime ruby32 --trigger-http --entry-point app --project PROJECT_ID
Você vai encontrar o seguinte erro:
"ERROR: (gcloud.functions.deploy) OperationError: code=3, message=Build failed: failed to verify function target "app" in source "app.rb": Undefined function: "app"; Error ID: e12ab0f9
"
Para resolver isso, vamos testar o recurso Generate Code
do Gemini. Vamos abrir o app.rb na guia "Explorer", que já contém o código do app Calculadora. No app.rb, na primeira linha, comece a digitar FunctionsFramework
e depois ".
". Você verá algumas sugestões em texto cinza :
Pressione Tab para aceitar a sugestão. Depois que ela for aceita, você verá mais sugestões, como as mostradas abaixo:
Pressione a tecla Tab para aceitar mais sugestões. Assim, seu app.rb ficará assim:
Renomeie o nome da função de add para app.
require "functions_framework"
FunctionsFramework.http "app" do |request|
a = request.params["a"].to_i
b = request.params["b"].to_i
Calculator.new.add(a, b)
end
class Calculator
def add(a, b)
a + b
end
end
Acabamos de criar o ponto de entrada do app Cloud Functions e também aprendemos a usar a sugestão de código do Gemini no editor. Agora vamos tentar implantar o app de novo.
gcloud functions deploy calculator --runtime ruby32 --trigger-http --entry-point app --project PROJECT_ID
Se tudo correr bem, a implantação será concluída e você verá o URL em que o aplicativo está hospedado. Legal, vamos modificar um pouco o app.rb para retornar o resultado da adição. O app.rb final vai ficar assim:
require "functions_framework"
FunctionsFramework.http "app" do |request|
a = request.params["a"].to_i
b = request.params["b"].to_i
calculator = Calculator.new
add = calculator.add(a, b)
"Result: #{add}"
end
class Calculator
def add(a, b)
a + b
end
end
9. Testes de ponta a ponta
Abra o URL e transmita os parâmetros de consulta a
e b
, conforme mostrado abaixo:
https://[APP-URL]/?a=2&b=3
Você verá a resposta como : "Result: 5"
. A Calculadora realiza muitas operações. Você pode ampliar este app para fazer isso também e receber a ajuda do Gemini.
10. Conclusão
Vimos como desenvolver um app em Ruby hoje usando a abordagem TDD com a ajuda do Gemini. Como você notou, o Gemini pode apresentar resultados diferentes, mas ele pode ajudar a acelerar o processo de desenvolvimento em uma linguagem que talvez você não conheça e ainda mostrar funções ou snippets para acelerar sua curva de aprendizado.
Qualquer desenvolvedor, seja qual for a experiência que tenha, pode receber a ajuda do Gemini no próprio processo de desenvolvimento. Se não for para desenvolver, você pode usar o Gemini para explicar o código que já existe. Você pode pedir que ele gere testes para o código que já existe. Essa é a tarefa mais chata para mim 🙂
Divirta-se programando com o Gemini!