Codelab: Gemini להאצת פיתוח מבוסס-בדיקות

1. מבוא

Codelab זה מציג את העקרונות של פיתוח מבוסס בדיקה ( TDD ), שבו כותבים בדיקות לפני הטמעת קוד. אנחנו נבנה אפליקציית מחשבון פשוטה בעזרת Ruby, תוך שימוש בגישה הזו.

תלמדו גם איך להשתמש ב-Gemini, בתור העוזר הדיגיטלי בתכנות. Gemini יעזור להאיץ את מחזור ה-TDD באמצעות יצירת מקרי בדיקה, הצעת הטמעות קוד ואפילו הסברים על הקוד.

לבסוף, תלמדו איך לפרוס את אפליקציית המחשבון ב-Cloud Functions, פלטפורמה מנוהלת של Google ללא שרת (serverless), שהופכת את האפליקציה שלכם לנגישה.

2. דרישות מוקדמות

  • פרויקט ב-Google Cloud שמופעל בו חיוב
  • בדפדפן אינטרנט

יוצרים פרויקט

הפעלת Gemini API

  • כדי להפעיל את ה-API, צריך לעבור אל Gemini Marketplace. אפשר להשתמש ב-gcloud גם כדי להפעיל את ה-API:
gcloud services enable cloudaicompanion.googleapis.com --project PROJECT_ID

הפעלת Cloud Functions API

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

הפעלת Cloud Shell

  • תשתמשו ב-Cloud Shell, סביבת שורת פקודה שפועלת ב-Google Cloud Console וכוללת מראש את השפות הנדרשות. לוחצים על Activate Cloud Shell בפינה הימנית העליונה ב-Cloud Console:

6757b2fb50ddcc2d.png

  • אחרי ההתחברות ל-Cloud Shell, אתם אמורים לראות שכבר בוצע אימות ושהפרויקט מוגדר לפי מזהה הפרויקט שלכם. מריצים את הפקודה הבאה ב-Cloud Shell כדי לוודא שהאימות בוצע:
gcloud auth list
  • מריצים את הפקודה הבאה ב-Cloud Shell כדי לוודא שהפקודה ב-gcloud יודעת על הפרויקט שלכם:
gcloud config list project
  • אם הפרויקט לא מוגדר, מגדירים אותו באמצעות הפקודה הבאה:
gcloud config set project <YOUR_PROJECT_ID>

עיינו במאמרי העזרה לפקודות ולשימוש ב-gcloud.

פתיחת העורך

  • לצורך ה-Codelab הזה, נשתמש בעורך Cloud המובנה. בחלון המעטפת של הענן, לוחצים על הלחצן 'פתיחת העורך' בפינה השמאלית העליונה. הפעולה הזו תפתח עבורכם עורך VSCode.

e5a5e95d543db556.png

הוספת תוסף Ruby

  • בתפריט הימני, לוחצים על סמל התוספים 999939b067e1d0dc.png, כותבים vscode ruby בסרגל החיפוש ומתקינים את התוסף VSCode Ruby.

a6fd4e37b3d847d2.png

3. החימום של Gemini

מודלים גדולים של שפה הם לא דטרמיניסטיים. לכן, כשתנסו את ההנחיות האלה, יכול להיות שהתשובה שתקבלו תיראה שונה מהתשובות בצילומי המסך המצורפים ב-Codelab.

קודם כל, נשאל את Gemini מה זה TDD. כדי להתחיל לשוחח עם Gemini באותו עורך Cloud Shell שבו אנחנו נמצאים, צריך לפעול לפי השלבים הבאים:

  • בצד ימין של הדף, מאתרים את הסמל של Gemini 25fdcae4447d063c.png. פעולה זו תפתח את חלון השיחה בצד ימין.
  • אפשר להתחיל להקליד בתיבת הטקסט שבה כתוב Enter a prompt here

5e09b0fb6a1b44dd.png

הנחיה:

What is Test Driven Development?

תשובה:

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

במאמר הזה נציג בקצרה את TDD ואת היתרונות שלו.

עכשיו נשאל את Gemini מה זה Ruby:

הנחיה:

What is Ruby?

תשובה:

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

בסרטון מוסבר מה זה Ruby ומה היתרונות של השימוש ב-Ruby כשפה.

4. הגדרת הפרויקט

עכשיו נתחיל ביצירת אפליקציה פשוטה של Sinatra.

  • שניצור תיקייה ריקה? אתם יכולים לתת לו כל שם שתרצו. נגדיר אותו כ-gemini-tdd ב-Codelab הזה. בעורך הענן שבצד ימין בכרטיסייה 'סייר', יוצרים תיקייה בקטע /home/<YOUR-USERNAME>/

d1d920b074cd7c79.png

  • בואו נפתח את התיקייה שיצרנו עכשיו. בתפריט הימני ביותר, לוחצים על הסמל 1d080370a3ccad53.png, ואז לוחצים על 'קובץ' ->. פתיחת התיקייה.
  • ניצור קובץ Ruby חדש בתיקיית הבסיס הזו, שישמש כנקודת התחלה של האפליקציה. תוכלו לתת לו כל שם שתרצו. נתקרא app.rb ב-Codelab הזה. 7beab8d21c59eee7.png
  • נוסיף גם Gemfile לתיקיית הבסיס. כדאי גם לשאול את Gemini על Gemfile.
  • ניצור גם קובץ app_test.rb כדי לכתוב את מקרי הבדיקה שלנו.

5. הטמעה מבוססת-Gemini

עכשיו נתחיל באפשרות לתת ל-Gemini הקשר לגבי מה שאנחנו מנסים לעשות, ונבקש ממנו ליצור מקרי בדיקה למטרה הזו. מעתיקים את ההנחיה הבאה להנחיה בצ'אט של Gemini.

הנחיה:

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.

תשובה:

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

זהו תרחיש לדוגמה לדוגמה של אפליקציית המחשבון, כלומר להוספת שני מספרים. היא גם ייבאת את התלות הנדרשת minitest/autorun עבור הבדיקות. נעתיק את התוכן אל app_test.rb. בואו ננסה להריץ את הבדיקה הזו עכשיו. מכיוון שלא כתבנו קוד, הוא ייכשל בטוח.

שנשאל את Gemini איך להריץ את הבדיקה הזו.

הנחיה:

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

תשובה:

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.

בואו נריץ את הבדיקה. לוחצים לחיצה ימנית על app_test.rb בכרטיסייה Explorer ואז לוחצים על 'פתיחה בטרמינל משולב'

66b4bb9598c1feca.png

חשוב לוודא שנמצאים באותה תיקייה שבה נמצא הקובץ app_test.rb, אם לא משתמשים בפקודה cd כדי להגיע לשם. בטרמינל, מריצים את הפקודה שמוחזרת מ-Gemini:

ruby app_test.rb

תופיע השגיאה הבאה:

NameError: uninitialized constant Calculator

נשאל את Gemini איך לתקן את הבעיה ישירות מהעורך. לוחצים על סמל הצ'אט בחלונית הניווט של העורך של Cloud Shell ושואלים את הבקשה הבאה:

הנחיה:

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

תשובה:

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 אומרים לנו שאין לנו כיתה בשם Calculator ושאנחנו צריכים ליצור אותה. הוא גם נתן לנו את הקוד ליצירת הכיתה Calculator. קדימה, נשתמש בקוד הזה. פותחים את הקובץ app.rb מהכרטיסייה Explorer ומעתיקים את הקוד שקיבלת מ-Gemini. כשמשנים את התוכן ב-app.rb, יכול להיות שיוצגו לכם כמה הצעות מ-Gemini כהשלמה אוטומטית. כדי לאשר את ההזמנה, צריך להקיש על tab, או על Esc אם לא.

נריץ את הבדיקה שוב. מקלידים את הפקודה הבאה בטרמינל המשולב:

ruby app_test.rb

עם זאת, עדיין תוצג לכם השגיאה "NameError: uninitialized constant Calculator". שנשאל את Gemini איך לפתור את הבעיה.

6. TDD איטרטיבי עם Gemini

הנחיה:

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

תשובה:

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

קיבלנו תשובה מסוימת, יכולה להיות זהה או שונה מהתשובה שצוינה למעלה. אז בואו נגיד ל-Gemini במפורש שהגדרתנו את המחלקה 'מחשבון' ב-app.rb .

הנחיה:

Calculator class is defined in app.rb already.

תשובה:

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 לייבא את app.rb במקום שבו מוגדרת מחלקה של המחשבון. לפעמים לוקח 2-3 חזרות על הנחיות עד שמקבלים את התשובה הנכונה, אבל ברגע שמתחילים לנסות את התהליך, הביצועים משתפרים. שימו לב: יכול להיות שתראו גם את ההודעה הדרושה "./app", בתגובה מ-Gemini. עכשיו נוסיף את הפונקציה הזו אל app.rb ב-app_test.rb ונריץ את אותה הבדיקה שוב.

ודאו שבשלב הזה, הפרמטר app_test.rb נראה כך:

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

מריצים את הפקודה הבאה מ-Cloud Shell Terminal בתוך תיקיית הפרויקט:

ruby app_test.rb

אם הכול תקין, הבדיקה אמורה לעבור בהצלחה. לכן פיתחנו אפליקציה פשוטה מאוד של Ruby לפי גישת ה-TDD, ועזרנו ב-Gemini. התשובות להנחיות לא יהיו זהות כל הזמן, וזה מטבעם של מודלים של LLM. יכול להיות שיופיעו ב-Gemini יותר פעולות המחשבון, אבל באופן כללי התהליך שעבדנו עליו אמור לפעול.

7. פריסת האפליקציה ב-Cloud Functions

עכשיו נבקש מ-Gemini לפרוס את הפונקציה הזו בפונקציה של Cloud Functions:

הנחיה:

Let's deploy this app to Cloud Functions

תשובה:

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 מסביר איך לפרוס אותו ידנית באמצעות ממשק המשתמש של Cloud Functions. אבל אני לא רוצה לעשות את זה. נבקש מ-Gemini לתת לנו את הפקודה gcloud, שאותה אפשר להריץ ישירות מהטרמינל המשולב.

הנחיה:

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

תשובה:

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

נריץ את הפקודה ב-gcloud ש-Gemini נותן בטרמינל.

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

תופיע השגיאה הבאה:

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

בואו ניקח עזרה מ-Gemini כדי לתקן את השגיאה.

הנחיה:

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

תשובה:

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

נריץ את bundle install בטרמינל כדי ליצור את Gemfile.lock . אחרי שמריצים את הפקודה, חשוב לבדוק את הכרטיסייה Explorer כדי לראות את התג Gemfile.lock .

ננסה שוב לפרוס את Cloud Functions. מריצים את אותה פקודת פריסה בטרמינל:

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

תופיע השגיאה הבאה:

"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 ל-Ruby

שנשאל את Gemini על השגיאה:

הנחיה:

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

תשובה:

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

למעשה, חסרה באפליקציה שלנו פנינה של function_framework. נוסיף את השורה הבאה ב-Gemfile:

gem "functions_framework"

עכשיו מריצים את bundle install בטרמינל. יכול להיות שתיתקלו בשגיאה "אין משאב גלובלי מפורש ב-Gemfile", או שלא תופיע. הקצר הזה. התשובות שלך יעזרו לנו להשתפר. אם נתקלתם בבעיה הזו, ודאו שהשורה הראשונה ב-Gemfile מופיעה בשורה הראשונה:

source "https://rubygems.org"

לאחר מכן מריצים שוב את bundle install מהטרמינל. כעת נריץ שוב את פקודת הפריסה:

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

השגיאה הבאה תופיע עכשיו:

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

כדי לפתור את הבעיה, כדאי לנסות את התכונה Generate Code ב-Gemini. נפתח את app.rb מהכרטיסייה 'סייר', שבה כבר יש לנו את הקוד של אפליקציית המחשבון. ב-app.rb, בשורה הראשונה מתחילים להקליד FunctionsFramework ואז מקלידים ".". יופיעו כמה הצעות בטקסט אפור :

9e17476a4a586433.png

כדי לקבל את ההצעה צריך להקיש על Tab. לאחר האישור, יוצגו לך עוד הצעות כמו אלה שמפורטות בהמשך:

f3c35d1539789acc.png

אפשר להקיש על Tab כדי לקבל הצעות נוספות. לכן, ה-app.rb שלכם אמור להיראות כך:

( צריך לשנות את שם הפונקציה מ-add ל-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

בדיוק יצרנו את נקודת הכניסה לאפליקציית Cloud Functions, וגם למדנו איך להשתמש בהצעה לקוד של Gemini בעורך. עכשיו ננסה לפרוס שוב את האפליקציה.

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

אם הכול תקין, הפריסה אמורה להתבצע ותוכלו לראות את כתובת ה-URL שבה האפליקציה מתארחת. מגניב, נשנה קצת את app.rb כדי להחזיר את תוצאת ההוספה. ה-app.rb הסופי שלכם אמור להיראות כך:

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. בדיקות 'קצה-לקצה'

פותחים את כתובת ה-URL ומעבירים את הפרמטרים a ו-b של השאילתה כפי שמוצג בהמשך:

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

התשובה אמורה להופיע בתור : "Result: 5". המחשבון מבצע הרבה פעולות. אפשר להרחיב את האפליקציה הזו כדי לבצע גם את הפעולות האלה ולקבל עזרה מ-Gemini בנושא הזה.

10. סיכום

למדנו היום איך לפתח אפליקציית Ruby תוך שימוש בגישת TDD בעזרת Gemini. כמו ששמת לב, Gemini יכול לתת תוצאות שונות, אבל הוא יכול לעזור להאיץ את תהליך הפיתוח בשפה שאולי לא הכי מוכרת לך, ועדיין להציג לך פונקציות או קטעי טקסט שיעזרו לך לזרז את עקומת הלמידה.

כל מפתח ( בלי קשר לחוויית השימוש) יכול להיעזר ב-Gemini בתהליך הפיתוח שלו. אם לא לצורכי פיתוח, אפשר להשתמש ב-Gemini כדי להסביר את הקוד הקיים, אפשר לבקש ממנו ליצור בדיקות לקוד הקיים, שזו המשימה הכי משעממת בעיניי, לפחות 🙂

בהצלחה בכתיבת קוד ב-Gemini!