Codelab: Mit Gemini die testgesteuerte Entwicklung beschleunigen

1. Einführung

In diesem Codelab werden die Prinzipien der testgesteuerten Entwicklung ( Test Driven Development, TDD) vorgestellt, bei der Sie Tests vor der Implementierung von Code schreiben. Wir zeigen Ihnen, wie wir mit Ruby eine einfache Rechner-App erstellen.

Außerdem erfährst du, wie du Gemini als deinen Coding-Assistenten verwendest. Gemini trägt dazu bei, den TDD-Zyklus zu beschleunigen, indem Testfälle generiert, Codeimplementierungen vorgeschlagen und sogar Erläuterungen zum Code bereitgestellt werden.

Schließlich erfahren Sie, wie Sie die Rechner-App in Cloud Functions, der vollständig verwalteten serverlosen Plattform von Google, bereitstellen und so auf Ihre Anwendung zugreifen können.

2. Vorbereitung

  • Ein Google Cloud-Projekt mit aktivierter Abrechnung
  • Einen Webbrowser

Projekt erstellen

Gemini API aktivieren

  • Rufen Sie den Gemini Marketplace auf, um die API zu aktivieren. Sie können die API auch mit gcloud aktivieren:
gcloud services enable cloudaicompanion.googleapis.com --project PROJECT_ID

Cloud Functions API aktivieren

gcloud services enable cloudfunctions.googleapis.com --project PROJECT_ID

Cloud Shell aktivieren

  • Sie verwenden Cloud Shell, eine Befehlszeilenumgebung, die in der Google Cloud Console ausgeführt wird und in der alle erforderlichen Sprachen vorinstalliert sind. Klicken Sie in der Cloud Console oben rechts auf Cloud Shell aktivieren:

6757b2fb50ddcc2d.png

  • Sobald Sie mit Cloud Shell verbunden sind, sollten Sie sehen, dass Sie bereits authentifiziert sind und dass das Projekt auf Ihre Projekt-ID eingestellt ist. Führen Sie in Cloud Shell den folgenden Befehl aus, um zu prüfen, ob Sie authentifiziert sind:
gcloud auth list
  • Führen Sie in Cloud Shell den folgenden Befehl aus, um zu prüfen, ob der gcloud-Befehl Ihr Projekt kennt:
gcloud config list project
  • Wenn Ihr Projekt noch nicht eingerichtet ist, verwenden Sie den folgenden Befehl, um es festzulegen:
gcloud config set project <YOUR_PROJECT_ID>

Informationen zu gcloud-Befehlen und deren Verwendung finden Sie in der Dokumentation.

Editor öffnen

  • Für dieses Codelab verwenden wir den integrierten Cloud-Editor. Klicken Sie im Cloud Shell-Fenster rechts oben auf die Schaltfläche „Editor öffnen“. Daraufhin wird ein VSCode-Editor geöffnet.

e5a5e95d543db556.png

Ruby-Erweiterung hinzufügen

  • Klicke im Menü auf der linken Seite auf das Erweiterungssymbol 999939b067e1d0dc.png, gib vscode ruby in die Suchleiste ein und installiere die VSCode-Erweiterung „Ruby“.

a6fd4e37b3d847d2.png

3. Aufwärmübung für Gemini

LLMs sind nicht deterministisch. Während Sie diese Prompts ausprobieren, sieht die Antwort, die Sie erhalten, also möglicherweise anders aus als auf den Screenshots im Codelab.

Fragen wir Gemini zuerst, was ein TDD ist. Wenn Sie mit Gemini im selben Cloud Shell-Editor sprechen möchten, in dem Sie sich auch gerade befinden, gehen Sie so vor:

  • Suchen Sie links auf der Seite nach dem Gemini-Symbol 25fdcae4447d063c.png. Dadurch wird das Chatfenster auf der linken Seite geöffnet.
  • Sie können mit der Eingabe in das Textfeld beginnen, in dem „Enter a prompt here“ steht.

5e09b0fb6a1b44dd.png

Prompt:

What is Test Driven Development?

Antwort:

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.
....

Sie erhalten eine kurze Einführung in TDD und seine Vorteile.

Fragen wir Gemini nun, was Ruby ist:

Prompt:

What is Ruby?

Antwort:

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.
....

Darin wird erläutert, was Ruby ist und welche Vorteile die Verwendung von Ruby als Sprache bietet.

4. Projekt einrichten

Beginnen wir mit dem Erstellen einer einfachen Sinatra-App.

  • Erstellen wir einen leeren Ordner. Sie können ihm einen beliebigen Namen geben. In diesem Codelab nennen wir sie gemini-tdd. Erstellen Sie im Cloud-Editor auf der linken Seite unter dem Tab „Explorer“ einen Ordner unter /home/<YOUR-USERNAME>/.

d1d920b074cd7c79.png

  • Öffnen wir den soeben erstellten Ordner. Klicken Sie im Menü ganz links auf das Symbol 1d080370a3ccad53.png und dann auf „File“ (Datei) -> Ordner öffnen.
  • Erstellen wir nun eine neue Ruby-Datei in diesem Stammordner, die als Ausgangspunkt für die Anwendung dient. Sie können ihr einen beliebigen Namen geben. In diesem Codelab nennen wir sie app.rb. 7beab8d21c59eee7.png
  • Außerdem fügen wir dem Stammordner eine Gemfile hinzu. Am besten fragst du Gemini auch nach Gemfile.
  • Außerdem erstellen wir eine app_test.rb-Datei, um unsere Testfälle zu schreiben.

5. Implementierung durch Gemini

Geben wir Gemini als Erstes einen Überblick über unsere Ziele und bitten Gemini, entsprechende Testläufe zu generieren. Kopieren Sie den folgenden Prompt in den Gemini-Chat-Prompt.

Prompt:

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.

Antwort:

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. 
.....

Sie erhalten einen Beispiel-Testfall für die Rechner App, d.h. zum Addieren von zwei Zahlen. Außerdem wurde die erforderliche Abhängigkeit minitest/autorun für die Tests importiert. Kopieren Sie jetzt den Inhalt zu app_test.rb. Lassen Sie uns den Test jetzt durchführen: da wir keinen Code geschrieben haben, scheitert er mit Sicherheit.

Fragen wir Gemini, wie dieser Test durchgeführt wird.

Prompt:

How do we run the tests written in app_test.rb using ruby command?

Antwort:

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.

Lassen Sie uns jetzt den Test durchführen. Klicken Sie im Explorer-Tab mit der rechten Maustaste auf app_test.rb und klicken Sie dann auf „Open in Integrated Terminal“ (Im integrierten Terminal öffnen).

66b4bb9598c1feca.png

Achten Sie darauf, dass Sie sich im selben Ordner wie die Datei „app_test.rb“ befinden. Verwenden Sie andernfalls den Befehl cd, um dorthin zu gelangen. Führen Sie im Terminal den von Gemini zurückgegebenen Befehl aus:

ruby app_test.rb

Der folgende Fehler wird angezeigt:

NameError: uninitialized constant Calculator

Lassen Sie uns Gemini fragen, wie das Problem direkt über den Editor behoben werden kann. Klicken Sie im Navigationsbereich des Cloud Shell-Editors auf das Chatsymbol und fragen Sie die folgende Eingabeaufforderung:

Prompt:

NameError: uninitialized constant Calculator. Give me Calculator class code.

Antwort:

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 teilt uns mit, dass wir keine Klasse namens „Calculator“ haben und eine Klasse erstellen müssen. Außerdem wurde damit der Code zum Erstellen der Calculator-Klasse bereitgestellt. Fahren wir fort und verwenden wir diesen Code. Öffne app.rb über den Tab „Explorer“ und kopiere den von Gemini bereitgestellten Code darin. Während Sie die Inhalte in app.rb bearbeiten, erhalten Sie möglicherweise einige Vorschläge von Gemini zur automatischen Vervollständigung. Sie müssen tab drücken, um sie zu akzeptieren, oder Esc, wenn nicht.

Führen Sie den Test jetzt erneut durch. Geben Sie den folgenden Befehl in Ihrem integrierten Terminal ein:

ruby app_test.rb

Der Fehler "NameError: uninitialized constant Calculator" wird jedoch weiterhin angezeigt. Fragen wir Gemini, wie es behoben werden kann.

6. Iteratives TDD mit Gemini

Prompt:

I am still getting this error: "NameError: uninitialized constant Calculator".

Antwort:

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
....

Sie hat eine Antwort erhalten, die mit den oben genannten Punkten identisch sein kann. Teilen wir Gemini also ausdrücklich mit, dass die Calculator-Klasse in app.rb definiert ist .

Prompt:

Calculator class is defined in app.rb already.

Antwort:

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"

Wir haben die Antwort von Gemini erhalten, um die app.rb-Datei zu importieren, in die wir die Calculator-Klasse definiert haben. Manchmal sind zwei bis drei Prompts erforderlich, um die richtige Antwort zu erhalten, aber wenn Sie den Dreh raus haben, wird es besser. Hinweis: Möglicherweise wird stattdessen require „./app“ als Antwort von Gemini angezeigt. Fügen wir dies nun der Datei app.rb in app_test.rb hinzu und führen den gleichen Test erneut aus.

Stellen Sie sicher, dass Ihre app_test.rb-Datei jetzt so aussieht:

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

Führen Sie den folgenden Befehl über das Cloud Shell-Terminal im Projektordner aus:

ruby app_test.rb

Wenn alles gut läuft, sollte der Test bestanden werden. Also haben wir auf Basis des TDD-Ansatzes eine sehr einfache Ruby-App entwickelt und dabei Gemini verwendet. Die Prompt-Antworten sind nicht immer gleich. Das liegt an den LLM-Modellen. Möglicherweise erhalten Sie mehr Vorgänge für den Rechner von Gemini, aber insgesamt sollte der gleiche Prozess, den wir gerade ausgeführt haben, funktionieren.

7. Anwendung in Cloud Functions bereitstellen

Bitten Sie Gemini nun, dies in Cloud Functions bereitzustellen:

Prompt:

Let's deploy this app to Cloud Functions

Antwort:

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 erklärt, wie Sie den Dienst über die Cloud Functions-UI manuell bereitstellen. Aber das will ich nicht. Bitten wir Gemini, uns den Befehl gcloud zu geben, den ich direkt über das integrierte Terminal ausführen kann.

Prompt:

How do I deploy this app to Cloud Functions gen2 using the gcloud command?

Antwort:

...
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

Führen Sie nun den von Gemini ausgegebenen gcloud-Befehl im Terminal aus.

gcloud functions deploy calculator --runtime ruby32 --trigger-http --entry-point app

Der folgende Fehler wird angezeigt:

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

Wenden Sie sich an Gemini, um den Fehler zu beheben.

Prompt:

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

Antwort:

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.
...

Führen Sie bundle install im Terminal aus, wodurch Gemfile.lock erstellt wird . Nachdem Sie den Befehl ausgeführt haben, sollten Sie auf dem Explorer-Tab die Gemfile.lock sehen .

Versuchen wir noch einmal, die Bereitstellung in Cloud Functions durchzuführen. Führen Sie im Terminal denselben Bereitstellungsbefehl aus:

gcloud functions deploy calculator --runtime ruby32 --trigger-http --entry-point app

Es wird ein weiterer Fehler angezeigt:

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 für Ruby

Fragen wir Gemini nach dem Fehler:

Prompt:

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

Antwort:

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.
....

In unserer App fehlt also das Gem „functions_framework“. Lassen Sie uns nun diese Zeile in unser Gemfile einfügen:

gem "functions_framework"

Führen Sie jetzt bundle install im Terminal aus. Möglicherweise tritt der Fehler „Keine explizite globale Ressource in Gemfile“ auf. . Stellen Sie in diesem Fall sicher, dass die erste Zeile Ihres Gemfile Folgendes enthält:

source "https://rubygems.org"

Führen Sie dann bundle install noch einmal über das Terminal aus. Führen Sie nun den Bereitstellungsbefehl noch einmal aus:

gcloud functions deploy calculator --runtime ruby32 --trigger-http --entry-point app --project PROJECT_ID

Jetzt tritt der folgende Fehler auf:

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

Um dieses Problem zu lösen, testen wir die Funktion „Generate Code“ von Gemini. Öffnen wir app.rb über den Tab „Explorer“, in dem sich bereits der Code der Rechner App befindet. Beginnen Sie in app.rb, in der ersten Zeile FunctionsFramework und dann „.“ einzugeben. Einige Vorschläge werden in grauem Text angezeigt :

9e17476a4a586433.png

Drücken Sie die Tabulatortaste, um den Vorschlag anzunehmen. Sobald das der Fall ist, sehen Sie weitere Vorschläge, wie unten dargestellt:

f3c35d1539789acc.png

Drücken Sie die Tabulatortaste, um weitere Vorschläge anzunehmen. Ihre app.rb-Datei sollte also so aussehen:

( Benennen Sie den Funktionsnamen von add in app um.)

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

Wir haben gerade den Einstiegspunkt für die Cloud Functions-App erstellt und gelernt, wie man den Codevorschlag von Gemini im Editor verwendet. Versuchen wir nun noch einmal, die App bereitzustellen.

gcloud functions deploy calculator --runtime ruby32 --trigger-http --entry-point app --project PROJECT_ID

Und wenn alles gut läuft, sollte die Bereitstellung durchgeführt werden und Sie sollten die URL sehen können, unter der Ihre Anwendung gehostet wird. Cool, ändern wir die Datei app.rb ein wenig, um das Additionsergebnis zurückzugeben. Ihre endgültige app.rb-Datei sollte so aussehen:

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. End-to-End-Tests

Öffnen Sie die URL und übergeben Sie die Suchparameter a und b wie unten gezeigt:

https://[APP-URL]/?a=2&b=3

Sie sollten die Antwort so sehen können : "Result: 5". Der Taschenrechner bietet zahlreiche Funktionen. Du kannst diese App auch erweitern, um auch diese zu nutzen und dabei von Gemini Unterstützung in Anspruch zu nehmen.

10. Fazit

Wir haben heute gesehen, wie wir mithilfe von Gemini eine Ruby-App mit dem TDD-Ansatz entwickeln können. Wie du bemerkt hast, liefert Gemini vielleicht unterschiedliche Ergebnisse, aber es kann auf jeden Fall dazu beitragen, den Entwicklungsprozess in einer Sprache zu beschleunigen, mit der du vielleicht noch nicht am meisten vertraut bist. Außerdem werden dir Funktionen oder Snippets angezeigt, um den Lernprozess zu beschleunigen.

Jeder Entwickler ( unabhängig von der verwendeten Erfahrung) kann bei der Entwicklung von Gemini Unterstützung in Anspruch nehmen. Wenn Sie nicht zum Entwickeln brauchen, können Sie Gemini verwenden, um vorhandenen Code zu erklären. Sie können ihn bitten, Tests für den vorhandenen Code zu generieren, was für mich zumindest die langweiligste Aufgabe ist. 🙂

Viel Spaß beim Programmieren mit Gemini!