1. Introduction
Cet atelier de programmation présente les principes du développement piloté par les tests ( TDD), qui consiste à écrire des tests avant d'implémenter le code. Pour illustrer cette approche, nous allons créer une application de calcul simple à l'aide de Ruby.
Vous apprendrez également à utiliser Gemini en tant qu'assistant de codage. Gemini aidera à accélérer le cycle des TTD en générant des scénarios de test, en suggérant des implémentations de code et même en fournissant des explications sur le code.
Enfin, vous verrez comment déployer l'application de calcul sur Cloud Functions, la plate-forme sans serveur entièrement gérée de Google, afin de rendre votre application accessible.
2. Prérequis
- Un projet Google Cloud pour lequel la facturation est activée
- Un navigateur Web
Créer un projet
- Dans la console Google Cloud, sur la page du sélecteur de projet, sélectionnez ou créez un projet Google Cloud.
- Assurez-vous que la facturation est activée sur votre projet Cloud. Découvrez comment vérifier si la facturation est activée sur un projet.
Activer l'API Gemini
- Accédez à la Marketplace Gemini pour activer l'API. Vous pouvez également utiliser gcloud pour activer l'API:
gcloud services enable cloudaicompanion.googleapis.com --project PROJECT_ID
- Accédez à la page Gemini, puis cliquez sur "Commencer à discuter".
- Important: Suivez les étapes 1 et 2 de cet atelier de programmation pour commencer à utiliser Gemini et activer Gemini dans l'IDE Cloud Shell respectivement.
Activer l'API Cloud Functions
- Dans la console Google Cloud, sur la page du sélecteur de projet, sélectionnez ou créez un projet Google Cloud.
- Accédez à la page de l'API Cloud Functions pour activer l'API. Vous pouvez également utiliser gcloud pour activer l'API:
gcloud services enable cloudfunctions.googleapis.com --project PROJECT_ID
Activer Cloud Shell
- Vous allez utiliser Cloud Shell, un environnement de ligne de commande qui s'exécute dans la console Google Cloud et sur lequel les langages requis sont préchargés. Dans la console Cloud, cliquez sur Activer Cloud Shell en haut à droite:
- Une fois connecté à Cloud Shell, vous êtes en principe authentifié, et le projet est défini sur votre ID de projet. Exécutez la commande suivante dans Cloud Shell pour vérifier que vous êtes authentifié:
gcloud auth list
- Exécutez la commande suivante dans Cloud Shell pour vérifier que la commande gcloud connaît votre projet:
gcloud config list project
- Si votre projet n'est pas défini, utilisez la commande suivante pour le définir :
gcloud config set project <YOUR_PROJECT_ID>
Consultez la documentation pour connaître les commandes gcloud ainsi que leur utilisation.
Ouvrir l'éditeur
- Pour cet atelier de programmation, nous allons utiliser l'éditeur Cloud intégré. Dans la fenêtre Cloud Shell, cliquez sur le bouton "Ouvrir l'éditeur" en haut à droite. Un éditeur VSCode s'ouvre.
Ajouter l'extension Ruby
- Dans le menu de gauche, cliquez sur l'icône Extensions
, saisissez
vscode ruby
dans la barre de recherche, puis installez l'extension VSCode Ruby.
3. Échauffement Gemini
Les LLM ne sont pas déterministes. Pendant que vous essayez ces invites, la réponse que vous recevez peut donc être différente de celles présentées dans les captures d'écran jointes dans l'atelier de programmation.
Commençons par demander à Gemini ce qu'est un TTD. Pour commencer à discuter avec Gemini dans l'éditeur Cloud Shell que nous utilisons actuellement, procédez comme suit:
- Recherchez l'icône Gemini
sur la gauche de la page pour ouvrir la fenêtre de chat sur la gauche.
- Vous pouvez commencer à saisir du texte dans la zone de texte indiquant
Enter a prompt here
Requête :
What is Test Driven Development?
Solution :
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. ....
Il vous présente brièvement le TDD et ses avantages.
À présent, demandons à Gemini ce qu'est Ruby:
Requête :
What is Ruby?
Solution :
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. ....
Il explique ce qu'est Ruby et quels sont ses avantages.
4. Configuration du projet
Commençons par créer une application Sinatra simple.
- Créons un dossier vide. Vous pouvez lui donner le nom de votre choix. Nous l'appellerons
gemini-tdd
pour cet atelier de programmation. Dans l'éditeur cloud à gauche, sous l'onglet "Explorateur", créez un dossier sous/home/<YOUR-USERNAME>/
.
- Ouvrons le dossier que nous venons de créer. Dans le menu situé tout à gauche, cliquez sur l'icône
, puis sur Fichier ->. Ouvrir le dossier.
- Créons dans ce dossier racine un fichier Ruby qui servira de point de départ pour l'application. Vous pouvez lui donner le nom de votre choix. Nous l'appellerons
app.rb
dans cet atelier de programmation. - Ajoutons également
Gemfile
dans le dossier racine. Nous vous recommandons de poser également des questions à Gemini surGemfile
. - Nous allons également créer un fichier
app_test.rb
pour écrire nos scénarios de test.
5. Implémentation basée sur Gemini
Commençons par expliquer à Gemini ce que nous essayons de faire et lui demander de générer des scénarios de test pour cela. Copiez la requête suivante dans la requête de chat Gemini.
Requête :
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.
Solution :
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. .....
Elle fournit un scénario type pour l'application Calculatrice, c'est-à-dire pour ajouter deux nombres. Il a également importé la dépendance minitest/autorun
requise pour les tests. Copions le contenu dans app_test.rb
. Essayons d'exécuter
ce test maintenant ; puisque nous n'avons pas de code écrit, il échouera à coup sûr.
Demandons à Gemini comment effectuer ce test.
Requête :
How do we run the tests written in app_test.rb using ruby command?
Solution :
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.
Alors, allons-y,
exécutons le test. Dans l'onglet "Explorateur", effectuez un clic droit sur app_test.rb
, puis cliquez sur "Ouvrir dans un terminal intégré".
Assurez-vous de vous trouver dans le même dossier que le fichier app_test.rb. Si ce n'est pas le cas, utilisez la commande cd pour y accéder. Dans le terminal, exécutez la commande renvoyée par Gemini:
ruby app_test.rb
L'erreur suivante s'affiche:
NameError: uninitialized constant Calculator
Demandons à Gemini comment la corriger directement depuis l'éditeur. Cliquez sur l'icône de chat dans le volet de navigation de l'éditeur Cloud Shell et posez la requête suivante:
Requête :
NameError: uninitialized constant Calculator. Give me Calculator class code.
Solution :
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. .....
Gemini nous indique que nous n'avons pas de classe appelée Calculator
et que nous devons en créer une. Il nous a également fourni le code permettant de créer la classe Calculator
. Utilisons ce code. Ouvrez app.rb
depuis l'onglet "Explorateur" et copiez-y le code fourni par Gemini. Lorsque vous modifiez le contenu dans le fichier app.rb, vous pouvez recevoir des suggestions de Gemini comme la saisie semi-automatique : vous devez appuyer sur tab
si vous souhaitez l'accepter, ou sur Esc
dans le cas contraire.
Exécutons à nouveau le test. Saisissez la commande suivante dans votre terminal intégré:
ruby app_test.rb
Mais vous verrez toujours la même erreur "NameError: uninitialized constant Calculator
". Demandons à Gemini comment le résoudre.
6. TTD itératif avec Gemini
Requête :
I am still getting this error: "NameError: uninitialized constant Calculator".
Solution :
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
....
Elle a généré une réponse, qui peut être identique à celle indiquée ci-dessus. Précisons donc explicitement à Gemini que la classe Calculatrice est définie dans app.rb .
Requête :
Calculator class is defined in app.rb already.
Solution :
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"
Gemini nous a demandé d'importer le fichier app.rb dans lequel la classe du calculateur est définie. Il faut parfois deux à trois itérations de requêtes pour obtenir la bonne réponse, mais au fur et à mesure que vous vous y habituerez, le processus s'améliorera. Il se peut que le message require "./app" s'affiche également à la place en réponse à Gemini. Ajoutons ceci au fichier app.rb dans app_test.rb et exécutons à nouveau le même test.
À ce stade, vérifiez que votre fichier app_test.rb se présente comme suit:
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
Exécutez la commande suivante à partir du terminal Cloud Shell dans le dossier du projet:
ruby app_test.rb
Si tout se passe comme prévu, le test devrait réussir. Nous avons donc développé une application Ruby très simple basée sur l'approche TDD, en nous aidant de Gemini. Les réponses aux requêtes ne sont pas toujours les mêmes, et c'est la nature même des modèles LLM. Gemini peut effectuer d'autres opérations de la calculatrice, mais dans l'ensemble, le processus que nous venons de suivre devrait fonctionner.
7. Déployer l'application sur Cloud Functions
Demandons à présent à Gemini de la déployer dans une fonction Cloud:
Requête :
Let's deploy this app to Cloud Functions
Solution :
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. ....
Gemini explique comment le déployer manuellement à l'aide de l'interface utilisateur de Cloud Functions. Mais je ne veux pas faire ça. Demandons à Gemini de nous fournir la commande gcloud
, que je peux exécuter directement depuis le terminal intégré.
Requête :
How do I deploy this app to Cloud Functions gen2 using the gcloud command?
Solution :
... 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
Exécutons la commande gcloud fournie par Gemini dans le terminal.
gcloud functions deploy calculator --runtime ruby32 --trigger-http --entry-point app
L'erreur suivante s'affiche:
"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
"
Laissons-nous l'aide de Gemini pour corriger l'erreur.
Requête :
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
Solution :
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. ...
Exécutons bundle install
dans le terminal pour créer Gemfile.lock
. Après avoir exécuté la commande, consultez l'onglet "Explorer" (Explorateur). Vous devriez voir apparaître Gemfile.lock
.
Essayons à nouveau de déployer sur Cloud Functions. Exécutez la même commande "deploy" dans le terminal:
gcloud functions deploy calculator --runtime ruby32 --trigger-http --entry-point app
Une autre erreur s'affiche:
"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. Framework des fonctions pour Ruby
Interrogons Gemini sur l'erreur:
Requête :
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
Solution :
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. ....
Donc, essentiellement, il nous manque le gem functions_framework dans notre application. Ajoutons cette ligne à notre fichier Gemfile:
gem "functions_framework"
Exécutez maintenant bundle install
dans le terminal. Il se peut que vous rencontriez l'erreur "Aucune ressource globale explicite dans Gemfile" pour en savoir plus. Si vous rencontrez ce problème, assurez-vous d'inclure la ligne suivante sur la première ligne de votre fichier Gemfile:
source "https://rubygems.org"
Exécutez à nouveau bundle install
à partir du terminal. Exécutons à nouveau la commande "deploy" :
gcloud functions deploy calculator --runtime ruby32 --trigger-http --entry-point app --project PROJECT_ID
Vous allez maintenant rencontrer l'erreur suivante:
"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
"
Pour résoudre ce problème, testons la fonctionnalité Generate Code
de Gemini. Ouvrons app.rb à partir de l'onglet "Explorateur", qui contient déjà le code de l'application Calculatrice. Dans le fichier app.rb, commencez à saisir FunctionsFramework
sur la première ligne, puis ".
". Quelques suggestions s'affichent en gris :
Appuyez sur la touche Tabulation pour accepter la suggestion. Une fois celles-ci acceptées, d'autres suggestions vous seront proposées, comme celles indiquées ci-dessous:
Appuyez sur la touche Tabulation pour accepter d'autres suggestions. Votre app.rb doit donc se présenter comme suit:
( Renommez la fonction add en 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
Nous venons de créer le point d'entrée de l'application Cloud Functions et nous avons également appris à utiliser la suggestion de code de Gemini dans l'éditeur. Essayons maintenant de déployer l'application à nouveau.
gcloud functions deploy calculator --runtime ruby32 --trigger-http --entry-point app --project PROJECT_ID
Si tout se passe bien, le déploiement devrait aboutir et vous devriez être en mesure de voir l'URL où votre application est hébergée. Modifions un peu le fichier app.rb pour renvoyer le résultat de l'addition. Le fichier app.rb final doit se présenter comme suit:
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. Tests de bout en bout
Ouvrez l'URL, puis transmettez les paramètres de requête a
et b
, comme indiqué ci-dessous:
https://[APP-URL]/?a=2&b=3
La réponse doit s'afficher comme suit : "Result: 5"
. La calculatrice peut effectuer de nombreuses opérations. Vous pouvez étendre cette appli pour qu'elle les exécute également et bénéficier de l'aide de Gemini sur ce point.
10. Conclusion
Aujourd'hui, nous avons vu comment développer une application Ruby en utilisant l'approche TDD avec l'aide de Gemini. Comme vous l'avez remarqué, Gemini peut vous donner des résultats différents, mais il peut tout à fait vous aider à accélérer le processus de développement dans un langage que vous ne connaissez peut-être pas le mieux, tout en vous montrant des fonctions ou des extraits pour accélérer votre apprentissage.
Tous les développeurs ( quelle que soit leur expérience) peuvent faire appel à Gemini pour mener à bien leur processus de développement. Si ce n'est pas pour le développement, vous pouvez utiliser Gemini pour expliquer le code existant. Vous pouvez lui demander de générer des tests pour le code existant, ce qui est au moins le plus ennuyeux pour moi 😃
Bon codage avec Gemini !