Codelab: Gemini ช่วยเร่งการพัฒนาการทดสอบ

1. บทนำ

Codelab นี้จะแนะนำหลักการของการพัฒนาที่ขับเคลื่อนด้วยการทดสอบ ( TDD) ซึ่งคุณจะเขียนการทดสอบก่อนที่จะใช้โค้ด เราจะสร้างแอปเครื่องคิดเลขอย่างง่ายโดยใช้ Ruby เพื่อแสดงแนวทางนี้

นอกจากนี้ คุณยังจะได้ทราบวิธีใช้ Gemini เป็นผู้ช่วยด้านการเขียนโค้ดด้วย Gemini จะช่วยเร่งรอบ TDD ด้วยการสร้างกรณีทดสอบ แนะนำการใช้งานโค้ด และแม้กระทั่งอธิบายโค้ด

สุดท้ายนี้ คุณจะได้ดูวิธีทําให้แอปเครื่องคิดเลขใช้งานได้ใน Cloud Functions ซึ่งเป็นแพลตฟอร์มแบบไร้เซิร์ฟเวอร์ที่มีการจัดการอย่างเต็มรูปแบบของ Google เพื่อให้แอปของคุณเข้าถึงได้

2. ข้อกำหนดเบื้องต้น

  • โปรเจ็กต์ Google Cloud ที่เปิดใช้การเรียกเก็บเงิน
  • เว็บเบราว์เซอร์

สร้างโปรเจ็กต์

เปิดใช้ Gemini API

  • ไปที่Gemini Marketplace เพื่อเปิดใช้ API นอกจากนี้ คุณยังใช้ gcloud เพื่อเปิดใช้ API ได้ด้วย โดยทำดังนี้
gcloud services enable cloudaicompanion.googleapis.com --project PROJECT_ID

เปิดใช้ Cloud Functions API

  • ในคอนโซล Google Cloud ให้เลือกหรือสร้างโปรเจ็กต์ Google Cloud ในหน้าตัวเลือกโปรเจ็กต์
  • ไปที่หน้า Cloud Functions API เพื่อเปิดใช้ API นอกจากนี้ คุณยังใช้ gcloud เพื่อเปิดใช้ API ได้ด้วย โดยทำดังนี้
gcloud services enable cloudfunctions.googleapis.com --project PROJECT_ID

เปิดใช้งาน Cloud Shell

  • คุณจะใช้ Cloud Shell ซึ่งเป็นสภาพแวดล้อมบรรทัดคำสั่งที่ทำงานใน Google Cloud Console และโหลดภาษาที่จำเป็นไว้ล่วงหน้า จาก Cloud Console ให้คลิกเปิดใช้งาน Cloud Shell ที่มุมบนขวา

6757b2fb50ddcc2d.png

  • เมื่อเชื่อมต่อกับ Cloud Shell แล้ว คุณควรเห็นว่าคุณได้รับการตรวจสอบสิทธิ์แล้วและระบบได้ตั้งค่าโปรเจ็กต์เป็นรหัสโปรเจ็กต์ของคุณ เรียกใช้คำสั่งต่อไปนี้ใน Cloud Shell เพื่อยืนยันว่าคุณได้รับการตรวจสอบสิทธิ์แล้ว
gcloud auth list
  • เรียกใช้คำสั่งต่อไปนี้ใน Cloud Shell เพื่อยืนยันว่าคำสั่ง gcloud รู้จักโปรเจ็กต์ของคุณ
gcloud config list project
  • หากไม่ได้ตั้งค่าโปรเจ็กต์ ให้ใช้คำสั่งต่อไปนี้เพื่อตั้งค่า
gcloud config set project <YOUR_PROJECT_ID>

โปรดดูคำสั่งและการใช้งาน gcloud ในเอกสารประกอบ

เปิดเครื่องมือแก้ไข

  • สำหรับโค้ดแล็บนี้ เราจะใช้โปรแกรมแก้ไข Cloud ในตัว ในหน้าต่าง Cloud Shell ให้คลิกปุ่ม "เปิดเครื่องมือแก้ไข" ที่มุมขวาบน ซึ่งจะเปิดโปรแกรมแก้ไข VSCode ให้คุณ

e5a5e95d543db556.png

เพิ่มส่วนขยาย Ruby

  • ในเมนูด้านซ้าย ให้คลิกไอคอนส่วนขยาย 999939b067e1d0dc.png พิมพ์ vscode ruby ในแถบค้นหา แล้วติดตั้งส่วนขยาย VSCode Ruby

a6fd4e37b3d847d2.png

3. การวอร์มอัพ Gemini

LLM เป็นแบบไม่กำหนด ดังนั้น ขณะที่คุณลองใช้พรอมต์เหล่านี้ คำตอบที่คุณได้รับอาจดูแตกต่างจากคำตอบในภาพหน้าจอที่แนบมาในโค้ดแล็บ

ก่อนอื่นเรามาถาม Gemini ว่า TDD คืออะไรกันก่อน หากต้องการเริ่มสนทนากับ Gemini ใน Cloud Shell Editor เดียวกับที่เราอยู่ ให้ทำตามขั้นตอนต่อไปนี้

  • ที่ด้านซ้ายมือของหน้าเว็บ ให้มองหาไอคอน 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 และประโยชน์ของ 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 คืออะไรและมีประโยชน์อย่างไรในการใช้เป็นภาษา

4. การตั้งค่าโปรเจ็กต์

มาเริ่มสร้างแอป Sinatra อย่างง่ายกันเลย

  • มาสร้างโฟลเดอร์เปล่ากัน คุณตั้งชื่อได้ตามต้องการ เราจะเรียกชื่อว่า gemini-tdd สำหรับ Codelab นี้ ในโปรแกรมแก้ไขบนระบบคลาวด์ทางด้านซ้ายใต้แท็บ Explorer ให้สร้างโฟลเดอร์ในส่วน /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. 
.....

โดยจะแสดงกรณีทดสอบตัวอย่างสำหรับแอปเครื่องคิดเลข เช่น การบวกตัวเลข 2 จำนวน นอกจากนี้ยังนำเข้าการอ้างอิงที่จำเป็น 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 อย่างชัดเจนว่าเราได้กำหนดคลาส Calculator ไว้ใน 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 ที่เรากำหนดคลาส Calculator ไว้ บางครั้งคุณอาจต้องป้อนพรอมต์ 2-3 ครั้งจึงจะได้คำตอบที่ถูกต้อง แต่เมื่อคุณคุ้นเคยกับการใช้งานแล้ว การใช้งานก็จะดีขึ้น โปรดทราบว่าคุณอาจเห็น require "./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 ภายในโฟลเดอร์โปรเจ็กต์

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 อธิบายวิธีติดตั้งใช้งานด้วยตนเองโดยใช้ UI ของ 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.
....

ดังนั้นโดยพื้นฐานแล้ว เราจึงไม่มี Gem ของฟังก์ชัน 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 จากแท็บ Explorer กัน ซึ่งเรามีโค้ดแอปเครื่องคิดเลขอยู่แล้ว ใน 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